openclaw-code-agent 4.5.7 → 4.5.8

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 CHANGED
@@ -1,43 +1,43 @@
1
- var Yu=Object.defineProperty;var H=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var Zu=(t,e)=>{for(var n in e)Yu(t,n,{get:e[n],enumerable:!0})};function Zt(t,e){return e?{...e,...t}:t}function Xu(t){return{...t,[Xo]:!0}}function ec(t){return{const:t,type:typeof t}}var Xo,g,re=H(()=>{Xo=Symbol("optionalSchema");g={Object(t,e){let n=Object.entries(t).filter(([,o])=>!o[Xo]).map(([o])=>o),r=Object.fromEntries(Object.entries(t).map(([o,i])=>{let{[Xo]:s,...a}=i;return[o,a]}));return{...e,type:"object",...n.length>0?{required:n}:{},properties:r}},String(t){return Zt({type:"string"},t)},Number(t){return Zt({type:"number"},t)},Boolean(t){return Zt({type:"boolean"},t)},Array(t,e){return Zt({type:"array",items:t},e)},Literal:ec,Union(t,e){return Zt({anyOf:t},e)},Optional:Xu}});function ei(t){v=t}function ti(t){z=t}var v,z,F=H(()=>{v=null,z=null});function Fs(t){let e=t.chatId.trim(),n=t.topicId.trim();return!/^-?\d+$/.test(e)||!/^\d+$/.test(n)?null:`${e}:topic:${n}`}function ic(t){let e=t.conversationId.trim(),n=e.match(/^(-?\d+):topic:(\d+)$/i);if(n?.[1]&&n[2]){let i=Fs({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=Fs({chatId:r,topicId:e});return o?{chatId:r,topicId:e,canonicalConversationId:o}:null}function sc(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 ac(t,e){if(!/^\d+$/.test(t))return t;let n=sc(e);return n?`${n}:${t}`:`channel:${t}`}function lc(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 dc(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 uc(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||!oc.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 cc(t,e=ic){try{return e({conversationId:t})}catch{return null}}function ni(t){return{provider:"system",target:"system",sessionKey:t?.trim()||void 0}}function ri(t,e){return{...t,threadId:e??t.threadId}}function mc(t,e,n){return t==="telegram"&&n?.provider==="telegram"&&!!n.target&&e!==n.target}function fc(t){let e=t?.trim();if(!e)return;let n=uc(e);if(!n)return;let{provider:r,kind:o,rawId:i}=n,s=dc(i),a=null;if(r==="telegram")try{a=pc.safeParseTelegramTopicConversation(i)}catch{a=null}let l=a?.chatId??s.id,d=a?.topicId??s.threadId,u=r==="discord"?o==="direct"||o==="dm"?`user:${l}`:`channel:${l}`:l;return{provider:r,target:u,threadId:d,sessionKey:e}}function oi(t){let e=t?.match(/:topic:(\d+)$/i);return e?parseInt(e[1],10):void 0}function qs(t){return!!(t?.provider&&t.target&&t.provider!=="system"&&t.target!=="system")}function Xt(t,e,n){let r=fc(n),o=e!=null?String(e):void 0,i=t?.trim();if(!i||i.toLowerCase()==="unknown")return r?ri(r,o):ni(n);let s=i.split("|").map(m=>m.trim());if(s.length<2)return r?ri(r,o):ni(n);let[a,l,d]=s,u=s.length>=3?d:l,c=s.length>=3?l:void 0,p=a?.toLowerCase();if(!p||!u)return r?ri(r,o):ni(n);let f=p==="discord"?ac(u,n):u;return mc(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 et(t){return Xt(lc(t.route)??t.originChannel,t.route?.threadId??t.originThreadId,t.route?.sessionKey??t.originSessionKey)??t.route}function Ee(t){let e=et(t);return qs(e)?e:void 0}function gc(t){return Object.fromEntries(Object.entries(t).filter(e=>!!e[1]))}function en(t){let e=et(t);if(!qs(e))return"";let n=gc({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 oc,pc,Ie=H(()=>{oc=new Set(["telegram","discord","slack","system","mattermost","feishu","line","whatsapp","signal","matrix","googlechat","bluebubbles","imessage","msteams"]);pc={safeParseTelegramTopicConversation:cc}});import{readFileSync as hc}from"fs";import{homedir as yc}from"os";import{join as kc}from"path";function Us(){if(tn!==void 0)return tn;try{let t=hc(kc(yc(),".claude.json"),"utf-8");tn=JSON.parse(t).mcpServers??{}}catch{tn={}}return tn}function Vs(t){let e=t.defaultHarness??Ks,n={};for(let[r,o]of Object.entries(nn)){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});D={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 de(){return D.defaultHarness??Ks}function ai(t){let e=nn[t],n=D.harnesses[t];return{...e,...n,allowedModels:n?.allowedModels??e?.allowedModels}}function yt(t){return ai(t).defaultModel}function Fn(t){return D.harnesses[t]?.allowedModels??D.allowedModels}function je(t){return ai(t).reasoningEffort}function kt(t){return t==="codex"?ai(t).fastMode:void 0}function Se(t){return t==null?void 0:String(t).trim()||void 0}function li(t){return{channel:Se(t?.deliveryContext?.channel),to:Se(t?.deliveryContext?.to),accountId:Se(t?.deliveryContext?.accountId),threadId:Se(t?.deliveryContext?.threadId)}}function Gs(t,e,n){if(!(!t||!e))return n?`${t}|${n}|${e}`:`${t}|${e}`}function ii(t){return Se(t?.requesterSenderId??t?.senderId)}function si(t){return(Se(t.deliveryContext?.channel)??t.messageChannel??t.channel)?.toLowerCase()!=="telegram"?!1:!!(oi(t.sessionKey)||Se(t.messageThreadId)||Se(t.deliveryContext?.threadId))}function qn(t){let e=li(t),n=Gs(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=Se(t.chatId);if(r.length===1&&o)return`${r[0]}|${o}`;let i=ii(t);if(r.length===1&&i&&!si(t))return`${r[0]}|${i}`}if(t.workspaceDir){let r=tt(t.workspaceDir);if(r)return r}if(t.messageChannel&&t.messageChannel.includes("|"))return t.messageChannel}function rn(t,e){if(e&&String(e).includes("|"))return String(e);let n=li(t),r=Gs(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 l=Se(t.chatId);if(l)return`${a}|${l}`;let d=ii(t);if(d&&!si(t))return`${a}|${d}`}let o=Se(t?.channel),i=Se(t?.chatId);if(o&&i)return`${o}|${i}`;let s=ii(t);return o&&s&&!si(t)?`${o}|${s}`:t?.id&&/^-?\d+$/.test(String(t.id))?`telegram|${t.id}`:D.fallbackChannel??"unknown"}function di(t){return li(t).threadId??t?.messageThreadId??void 0}function St(t,e,n){return Xt(rn(t,e),di(t),n??t?.sessionKey)}function tt(t){let e=D.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 js(t){return oi(t)}var tn,Ks,nn,D,ae=H(()=>{Ie();Ks="claude-code",nn={"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:{}};D={maxSessions:20,idleTimeoutMinutes:15,sessionGcAgeMinutes:1440,maxPersistedSessions:1e4,maxAutoResponds:10,permissionMode:"plan",planApproval:"delegate",defaultWorktreeStrategy:"delegate",harnesses:{"claude-code":{...nn["claude-code"]},codex:{...nn.codex},opencode:{...nn.opencode}}}});function K(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function G(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 Hs(t,e){return e&&typeof e.recommended=="boolean"?e.recommended:e&&typeof e.isRecommended=="boolean"?e.isRecommended:/\b(?:not\s+(?:a\s+)?|non[-\s]?|un)recommended\b/i.test(t)?!1:/\brecommended\b/i.test(t)}function zs(t){if(typeof t=="string"){let s=t.trim();return s?{label:s,value:s,recommended:Hs(s)}:void 0}let e=K(t);if(!e)return;let n=G(e,["label","title","text","value","name","id"])?.trim();if(!n)return;let r=G(e,["description","preview","detail","details"]),o=G(e,["value","id","name"]),i=e.isOther===!0||e.is_other===!0||e.other===!0;return{label:n,...r?{description:r}:{},...o?{value:o}:{},...i?{isOther:!0}:{},recommended:Hs(n,e)}}function Kn(t){let e=K(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(zs).filter(r=>!!r):[]}function wt(t){let e=K(t);return(Array.isArray(e?.questions)?e.questions:[]).map((r,o)=>Sc(r,o)).filter(r=>!!r)}function Sc(t,e=0){let n=K(t);if(!n)return;let r=G(n,["question","prompt","message","text","summary"])?.trim();if(!r)return;let o=G(n,["id","questionId","question_id","name"]),i=G(n,["header","title","label"]),a=(Array.isArray(n.options)?n.options:Array.isArray(n.choices)?n.choices:[]).map(zs).filter(u=>!!u),l=n.multiSelect===!0||n.multi_select===!0,d=n.isOther===!0||n.is_other===!0||n.allowFreeText===!0||n.allowsFreeText===!0||l||a.some(u=>u.isOther);return{id:o??`question_${e+1}`,...i?{header:i}:{},question:r,options:a,...l?{multiSelect:!0}:{},...d?{allowsFreeText:!0}:{},...n.isSecret===!0||n.is_secret===!0?{isSecret:!0}:{}}}function Qs(t,e,n){let r=[n>1?`Question ${e+1}`:void 0,t.header].filter(Boolean).join(" - "),o=[...r?[r]:[],t.question];return t.options.length>0&&o.push("Options:",...t.options.map((i,s)=>{let a=i.recommended&&!/\brecommended\b/i.test(i.label)?" (recommended)":"",l=i.description?` - ${i.description}`:"",d=i.isOther?" (free text)":"";return` ${s+1}. ${i.label}${a}${d}${l}`})),t.allowsFreeText&&!t.options.some(i=>i.isOther)&&o.push(t.multiSelect?"Reply with one or more option labels.":"Free-form answer is allowed."),o}function Un(t){if(t.length===0)return;let e=t.flatMap((n,r)=>[...r>0?[""]:[],...Qs(n,r,t.length)]);return t.length>1&&e.push("","Reply with answers by question, for example: Q1: ..., Q2: ..."),e.join(`
3
- `)}function De(t,e,n){return Qs(t,e,n).join(`
4
- `)}var on=H(()=>{});function Pt(t){return{type:"backend_ref",ref:t}}function bt(t){return{type:"run_started",...t?{runId:t}:{}}}function nt(t){return{type:"text_delta",text:t}}function Vn(t,e){return{type:"tool_call",name:t,input:e}}function Me(t){return{type:"pending_input",state:t}}function ze(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function Gn(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function Rt(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function Oe(t){return{type:"run_completed",data:t}}var He,jn=H(()=>{He=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 zn from"@anthropic-ai/claude-agent-sdk";function vc(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(`
5
- `)}}function wc(t,e,n){let r=wt(n),o=r.length>0?0:void 0,i=o!=null?r[o]:void 0,s=i?.options.map(l=>l.label)??[],a=i?De(i,o,r.length):Un(r);return{requestId:`${t||"claude"}-ask-${e}`,kind:"question",promptText:a,options:s,...r.length>0?{questions:r}:{},...o!=null?{activeQuestionIndex:o}:{},allowsFreeText:i?.allowsFreeText===!0||s.length===0}}var Hn,Js=H(()=>{on();jn();Hn=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 He,r=!1,o="",i=!1,s=0,a=e.resumeSessionId??"",l=e.canUseTool,d={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,...l?{canUseTool:async(m,y)=>{if(m!=="AskUserQuestion")return{behavior:"allow"};let k=wc(a,++s,y);n.enqueue(Me(k));try{let S=await l(m,y);return n.enqueue(ze(k.requestId)),S}catch(S){throw n.enqueue(ze(k.requestId)),S}}}:{}};e.resumeSessionId&&(d.resume=e.resumeSessionId,d.forkSession=e.forkSession??!1);let u=e.prompt,c=this.deps.query??zn.query,p=this.deps.startup??zn.startup,f=(async()=>{if(typeof p!="function")return c({prompt:u,options:d});let m=await p({options:d});try{return m.query(u)}catch(y){throw await m.close?.(),y}})();return(async()=>{try{let m=await f;for await(let y of m){let k=y;if(k.type==="system"&&k.subtype==="init"){a=k.session_id??a,n.enqueue(Pt({kind:"claude-code",conversationId:a}));continue}if(k.type==="system"&&k.subtype==="status"&&k.permissionMode){n.enqueue(Rt(k.permissionMode));continue}if(k.type==="assistant"){r||(r=!0,n.enqueue(bt()));for(let S of k.message?.content??[]){if(S.type==="text"){o+=o?`
6
- ${S.text}`:S.text,n.enqueue(nt(S.text));continue}S.type==="tool_use"&&((S.name==="ExitPlanMode"||S.name==="set_permission_mode")&&(i=!0),S.name!=="AskUserQuestion"&&n.enqueue(Vn(S.name,S.input)))}continue}if(k.type==="result"){let S=o.trim();if(S&&(e.permissionMode==="plan"||i)){let b={explanation:void 0,steps:[],markdown:S};n.enqueue(Gn(b,!0))}n.enqueue(Oe({success:k.subtype==="success",duration_ms:k.duration_ms??0,total_cost_usd:k.total_cost_usd??0,num_turns:k.num_turns??0,result:vc(k),session_id:k.session_id??a})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(m=>{n.enqueue(Oe({success:!1,duration_ms:0,total_cost_usd:0,num_turns:0,result:m instanceof Error?m.message:String(m),session_id:a})),n.close()}),{messages:n.messages(),async setPermissionMode(m){let y=await f;typeof y.setPermissionMode=="function"&&await y.setPermissionMode(m)},async streamInput(m){let y=await f;typeof y.streamInput=="function"&&await y.streamInput(m)},async interrupt(){let m=await f;typeof m.interrupt=="function"&&await m.interrupt()}}}buildUserMessage(e,n){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:n}}}});import{spawn as Pc}from"node:child_process";import bc from"node:readline";function Ys(t){return t instanceof Error?t.message:String(t)}function At(t,e){JSON.stringify({component:"CodexAppServerRpc",event:t,at:new Date().toISOString(),...e})}function Rc(t,e){return{commandKind:t==="codex"?"codex":"custom",appServerSubcommand:!0,configuredArgCount:e.length}}function Ac(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function Ic(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:Ys(r)}})}}}function ui(t){return t.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/?#@]+@/gi,"$1[redacted credential]@").replace(/\b(authorization\s*[:=]\s*)[^\r\n,;}]+/gi,"$1[redacted credential]").replace(/\b(Bearer\s+)[^\s]+/gi,"$1[redacted credential]").replace(/(["'][A-Za-z0-9_.-]*(?:api[_-]?key|token|secret|password|authorization)[A-Za-z0-9_.-]*["']\s*:\s*["'])[^"']+(["'])/gi,"$1[redacted credential]$2").replace(/\b([A-Za-z0-9_.-]*(?:api[_-]?key|token|secret|password|authorization)[A-Za-z0-9_.-]*\s*[:=]\s*)[^\s,}]+/gi,"$1[redacted credential]").replace(/\b(?:sk-[A-Za-z0-9_-]{8,}|gh[opsru]_[A-Za-z0-9_]{8,}|[A-Za-z0-9_-]{32,})\b/g,"[redacted token]").replace(/(?:\/Users|\/home)\/[^\s]+/g,"[redacted path]").replace(/\s+/g," ").slice(-1e3)}var Qn,Zs=H(()=>{Qn=class{constructor(e,n,r){this.command=e;this.args=n;this.requestTimeoutMs=r}command;args;requestTimeoutMs;process=null;pending=new Map;stderrTail="";counter=0;onNotification=()=>{};onRequest=async()=>({});setNotificationHandler(e){this.onNotification=e}setRequestHandler(e){this.onRequest=e}async connect(){if(this.process)return;let e=Pc(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(At("process.spawn",{...Rc(this.command,this.args),pid:e.pid,requestTimeoutMs:this.requestTimeoutMs}),!e.stdin||!e.stdout||!e.stderr)throw new Error("codex app server stdio pipes unavailable");this.process=e,bc.createInterface({input:e.stdout}).on("line",r=>{this.handleLine(r)}),e.stderr.on("data",r=>{this.stderrTail=`${this.stderrTail}${r.toString("utf8")}`.slice(-4e3)}),e.on("error",r=>{At("process.error",{pid:e.pid,error:Ys(r)})}),e.on("close",(r,o)=>{At("process.close",{pid:e.pid,code:r,signal:o,pendingRequests:this.pending.size,recentStderr:ui(this.stderrTail.trim())}),this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){At("client.close",{pid:this.process?.pid,pendingRequests:this.pending.size}),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 l=Math.max(100,r??this.requestTimeoutMs),d=setTimeout(()=>{this.pending.delete(o),At("request.timeout",{id:o,method:e,timeoutMs:l,pid:this.process?.pid,recentStderr:ui(this.stderrTail.trim())}),a(new Error(this.buildTimeoutErrorMessage(e,l)))},l);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)}
7
- `)}async handleLine(e){let n=Ac(e);n&&await Ic(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){this.pending.size>0&&At("pending.flush",{pendingRequests:this.pending.size,error:e.message,pid:this.process?.pid});for(let[n,r]of this.pending)clearTimeout(r.timer),r.reject(e),this.pending.delete(n)}buildTimeoutErrorMessage(e,n){let r=this.stderrTail.trim(),o=r?`; recent stderr: ${ui(r)}`:"";return`codex app server timeout after ${n}ms: ${e}${o}`}}});function Xs(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()))}var ea=H(()=>{});function We(t,e){let n=e?.trim();if(!n)return;if(t!=="codex")return n;let[r,...o]=n.split("/");return r?.toLowerCase()==="openai"&&o.length===1&&o[0]?.trim()?o[0].trim():n}function xc(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>We("codex",r)?.toLowerCase()===n)}function Jn(t,e,n){return t==="codex"?xc(e,n):Xs(e,n)}function It(t,e){return t!=="codex"||!e?!0:!e.includes("/")}function Yn(t,e,n){if(t!=="codex"||!e||!n||n.length===0)return e;let r=e.toLowerCase(),o=n.find(i=>We("codex",i)?.toLowerCase()===r);return We("codex",o)??e}var Zn=H(()=>{ea()});function Tc(t){return t instanceof Error?t.message:String(t)}function ta(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function Qe(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>Qe(n)).join("");let e=K(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=Qe(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=Qe(e[n]);if(r)return r}return""}function sn(t){let e=K(t);if(!e)return{};let n=K(e.thread)??K(e.session),r=K(e.turn)??K(e.run),o=K(e.item),i=K(e.serverRequest);return{threadId:G(e,["threadId","thread_id","conversationId","conversation_id"])??G(n,["id","threadId","thread_id","conversationId"]),runId:G(e,["turnId","turn_id","runId","run_id"])??G(r,["id","turnId","turn_id","runId","run_id"]),requestId:G(e,["requestId","request_id","serverRequestId"])??G(i,["id","requestId","request_id"]),itemId:G(e,["itemId","item_id"])??G(o,["id","itemId","item_id"])}}function Xn(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=Xn(i,e,n+1);if(s)return s}return}let r=K(t);if(!r)return;let o=G(r,e);if(o)return o;for(let i of Object.values(r)){let s=Xn(i,e,n+1);if(s)return s}}function an(t){return{threadId:sn(t).threadId,cwd:Xn(t,["cwd","workdir","directory"])}}function na(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function ra(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 er(t){let e=K(t);if(!e)return;let n=K(e.item)??e;return G(n,["id","itemId","item_id","messageId","message_id"])}function Cc(t,e=!1){let n=K(t);if(!n)return"";let r=K(n.item)??n;return G(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?Qe(r):G(r,["text"],{trim:!1})??Qe(r)}function oa(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:Qe(e),itemId:er(e)}:n==="item/completed"?{mode:"snapshot",text:Cc(e),itemId:er(e)}:{mode:"ignore",text:""}}function ia(t){return{itemId:er(t),delta:Qe(t)}}function sa(t){let e=K(t),n=K(e?.plan),o=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(i=>{let s=K(i),a=G(s,["step","title","text"]);if(!a)return null;let l=G(s,["status"])?.toLowerCase()??"pending";return{step:a,status:l==="inprogress"||l==="in_progress"?"inProgress":l==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:G(n,["explanation"])??G(e,["explanation"]),steps:o}}function aa(t){let e=K(t);if(!e)return{};let n=K(e.item)??e;return G(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:er(n),text:G(n,["text"],{trim:!1})??Qe(n)}}function la(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=K(e)??{},o=K(r.turn)??r,i=G(o,["status"])?.toLowerCase();return i==="failed"?"failed":i==="interrupted"||i==="cancelled"?"interrupted":"completed"}function da(t,e){let n=K(e)??{},r=K(n.turn)??n,o=K(r.error)??K(n.error);if(o)return G(o,["message","text","summary","reason"])}function Mc(t,e){let n=Tc(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 $c(t){return _c.has(t.trim().toLowerCase())}function Ec(t){let e=K(t);return e?!!G(e,["threadId","thread_id"]):!1}async function ln(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($c(n)&&!Ec(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,!Mc(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function ua(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 ca(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 Dc(t){return[{type:"text",text:t}]}function Oc(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 pa(t){let e={threadId:t.threadId,input:Dc(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=Oc(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function ma(t){return[{threadId:t.threadId,turnId:t.turnId}]}function Wc(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 fa(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=wt(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let a=o?Kn(n):[],l=s.length>0?0:void 0,d=l!=null?s[l]:void 0,u=d?d.options:[],p=(o&&u.length===0?a:u).map(y=>y.label),f=(d?De(d,l??0,s.length):Un(s))??(o?Xn(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,m=o?p.map(y=>({kind:"approval",label:y,decision:Wc(y),responseDecision:y})):p.map(y=>({kind:"option",label:y,value:y}));return{requestId:e,kind:o?"approval":"question",promptText:f,options:p,...s.length>0?{questions:s}:{},...l!=null?{activeQuestionIndex:l}:{},actions:m,allowsFreeText:!0}}function ga(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function ci(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var _c,ha=H(()=>{on();_c=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function Kc(t){let e=t?.trim();return e&&qc.test(e)?e:void 0}function Uc(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return pi;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:pi}function dn(t){return t instanceof Error?t.message:String(t)}function ve(t,e){JSON.stringify({component:"CodexHarness",event:t,at:new Date().toISOString(),...e})}function Vc(t){return{commandKind:t.command==="codex"?"codex":"custom",configuredArgCount:t.args.length,requestTimeoutMs:t.requestTimeoutMs}}function Ne(t){return{hasThreadId:!!t.threadId,hasTurnId:!!t.turnId,hasBackendWorktreePath:!!t.backendWorktreePath,hasBackendWorktreeId:!!t.backendWorktreeId}}function Gc(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)}function ka(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:De(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}function jc(t){if(t===void 0)return ya;let e=ta(t);return e.length>0?e:ya}var Nc,pi,ya,Lc,Bc,Fc,qc,tr,Sa=H(()=>{Zs();jn();on();Zn();ha();Nc="1.0",pi=12e4,ya=["--listen","stdio://"],Lc="OPENCLAW_CODEX_APP_SERVER_COMMAND",Bc="OPENCLAW_CODEX_APP_SERVER_ARGS",Fc="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS",qc=/^(?:urn:uuid:)?[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;tr=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[Lc]?.trim()||"codex",args:jc(process.env[Bc]),requestTimeoutMs:Uc(process.env[Fc])},r=this.deps.createClient?.(n)??new Qn(n.command,n.args,n.requestTimeoutMs),o=new He,i=Kc(e.resumeSessionId);e.resumeSessionId;let s,a=e.backendRef?.worktreePath,l=e.backendRef?.worktreeId,d=e.permissionMode??"default",u=We(this.name,e.model);if(!It(this.name,u))throw new Error(`Codex model "${e.model}" is not supported. Use a bare Codex model id such as "gpt-5.5".`);let c,p=0,f="",m=[],y,k=new Map,S=new Set,b=$=>{let T=$?.trim();if(!T)return;let C=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&T!==C&&na(T)&&(a=T,l=ra(T))},A=()=>{i&&o.enqueue(Pt({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...l?{worktreeId:l}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async($,T)=>{let C=$.trim().toLowerCase(),q=sn(T),j=an(T);if(q.threadId&&i&&q.threadId!==i)return;if(q.threadId&&(i=q.threadId),q.runId&&(s=q.runId),b(j.cwd),(q.threadId||q.runId||j.cwd)&&A(),C==="serverrequest/resolved"){c&&(o.enqueue(ze(c.requestId)),c=void 0);return}if(C==="turn/plan/updated"){let V=sa(T);f=V.explanation??f,V.steps.length>0&&(m=V.steps);return}if(C==="item/plan/delta"){let V=ia(T);if(V.itemId&&V.delta){let se=k.get(V.itemId)??"";k.set(V.itemId,`${se}${V.delta}`)}return}if(C==="item/completed"){let V=aa(T);if(V.text?.trim()){let se={explanation:f||void 0,steps:m,markdown:V.text.trim()};o.enqueue(Gn(se,!0));return}}let N=oa(C,T);if(N.mode==="delta"&&N.text){N.itemId&&S.add(N.itemId),o.enqueue(nt(N.text));return}N.mode==="snapshot"&&N.text&&(!N.itemId||!S.has(N.itemId))&&o.enqueue(nt(N.text)),(C==="turn/completed"||C==="turn/failed"||C==="turn/cancelled")&&y&&(y.method=$,y.params=T,y.resolve())}),r.setRequestHandler(async($,T)=>{if(!ga($))return{};let C=sn(T),q=an(T);if(C.threadId&&i&&C.threadId!==i)return{};C.threadId&&(i=C.threadId),C.runId&&(s=C.runId),b(q.cwd),(C.threadId||C.runId||q.cwd)&&A();let j=C.requestId??`${i??"codex"}-${Date.now().toString(36)}`,N;try{N=fa($,j,T)}catch(Qt){let Jt=dn(Qt);return`${Jt}`,{error:Jt}}let V=$.trim().toLowerCase(),se=N.options,Ae=N.actions??[],gt=await new Promise(Qt=>{c={requestId:j,methodLower:V,state:N,options:se,actions:Ae,answers:{...N.answers??{}},resolveResponse:Qt},o.enqueue(Me(N))});return c=void 0,o.enqueue(ze(j)),gt});let x=async()=>{ve("client.initialize.start",{...Vc(n),hasResumeSessionId:!!e.resumeSessionId}),await r.connect(),await r.request("initialize",{protocolVersion:Nc,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},n.requestTimeoutMs),await r.notify("initialized",{}),ve("client.initialize.done",{hasResumeSessionId:!!e.resumeSessionId})},R=async()=>{let $=ci(d,e.codexApprovalPolicy);if(i){ve("thread.resume.start",Ne({threadId:i}));let q=await ln({client:r,methods:["thread/resume"],payloads:ca({threadId:i,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:$.approvalPolicy,sandbox:$.sandbox}),timeoutMs:n.requestTimeoutMs}),j=an(q);i=j.threadId??i,b(j.cwd),A(),ve("thread.resume.done",{...Ne({threadId:i,backendWorktreePath:a,backendWorktreeId:l})});return}ve("thread.start.start",{hasCwd:!!e.cwd});let T=await ln({client:r,methods:["thread/start","thread/new"],payloads:ua({cwd:e.cwd,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:$.approvalPolicy,sandbox:$.sandbox}),timeoutMs:n.requestTimeoutMs}),C=an(T);if(i=C.threadId,!i)throw new Error("Codex App Server did not return a thread id.");b(C.cwd),A(),ve("thread.start.done",{...Ne({threadId:i,backendWorktreePath:a,backendWorktreeId:l})})},h=async $=>{await R(),ve("turn.start",{...Ne({threadId:i}),runCounter:p+1,promptChars:$.length,permissionMode:d}),o.enqueue(bt()),p+=1,f="",m=[],k.clear(),S.clear();let T="",C,q,j=new Promise(N=>{q=N});y={resolve:q};try{let N=ci(d,e.codexApprovalPolicy),V=await ln({client:r,methods:["turn/start"],payloads:pa({threadId:i,prompt:$,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:d,approvalPolicy:N.approvalPolicy,sandbox:N.sandbox}),timeoutMs:n.requestTimeoutMs}),se=sn(V);se.runId&&(s=se.runId,A()),await j,T=y?.method??"turn/failed",C=y?.params;let Ae=la(T,C);ve("turn.terminal",{...Ne({threadId:i,turnId:s}),terminalMethod:T,outcome:Ae}),o.enqueue(Oe({success:Ae==="completed",outcome:Ae,duration_ms:0,total_cost_usd:0,num_turns:p,result:da(T,C),session_id:i}))}catch(N){ve("turn.error",{...Ne({threadId:i,turnId:s}),error:dn(N)}),o.enqueue(Oe({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:dn(N),session_id:i??""}))}finally{y=void 0}},w=async $=>{let T=c;if(!T)return!1;let C=$.trim();if(T.methodLower.includes("requestapproval"))return T.resolveResponse({decision:C||"decline"}),!0;let q=T.state.questions??[];if(q.length>0){if(!C)return!1;let j=T.state.activeQuestionIndex??0,N=q[j];if(!N)return!1;T.answers={...T.answers,[N.id]:{answers:[C]}};let V=j+1;if(V<q.length)return T.state=ka(T.state,V,T.answers),T.options=T.state.options,o.enqueue(Me(T.state)),!0;T.resolveResponse({answers:T.answers})}else T.resolveResponse({text:C});return!0},L=async($,T={})=>{let C=c;if(!C||T.requestId&&T.requestId!==C.state.requestId)return!1;let q=C.actions[$];if(q?.kind==="approval")return C.resolveResponse({decision:q.responseDecision,...q.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:q.proposedExecpolicyAmendment}:{}}),!0;let j=C.state.questions??[],N=C.state.activeQuestionIndex??0,V=j.length>0?j[N]:void 0;if(T.questionId&&T.questionId!==V?.id)return!1;let se=V?.options[$];if(V&&se){C.answers={...C.answers,[V.id]:{answers:[se.value??se.label]}};let gt=N+1;return gt<j.length?(C.state=ka(C.state,gt,C.answers),C.options=C.state.options,o.enqueue(Me(C.state)),!0):(C.resolveResponse({answers:C.answers}),!0)}let Ae=C.options[$];return Ae?(C.methodLower.includes("requestapproval")?C.resolveResponse({decision:Ae}):C.resolveResponse({option:Ae,index:$}),!0):!1},ne=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{await x();for await(let $ of ne){let T=Gc($).trim();!T||await w(T)||await h(T)}}catch($){ve("session.error",{...Ne({threadId:i,turnId:s}),error:dn($)}),o.enqueue(Oe({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:dn($),session_id:i??e.resumeSessionId??""}))}finally{ve("client.close.start",Ne({threadId:i,turnId:s})),await r.close().catch(()=>{}),ve("client.close.done",Ne({threadId:i,turnId:s})),o.close()}})(),{messages:o.messages(),async setPermissionMode($){d=$,o.enqueue(Rt($))},async submitPendingInputOption($,T){return L($,T)},async submitPendingInputText($){return w($)},async interrupt(){!i||!s||await ln({client:r,methods:["turn/interrupt"],payloads:ma({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as Hc}from"node:child_process";import{constants as zc,accessSync as Qc}from"node:fs";import{createServer as Jc}from"node:net";import{delimiter as Yc,dirname as mi,join as Pa,sep as Zc}from"node:path";function Tt(t){return t instanceof Error?t.message:String(t)}function rp(t){try{return Qc(t,zc.X_OK),!0}catch{return!1}}function op(t){return t.includes("/")||Zc==="\\"&&t.includes("\\")}function ip(t){let e=(t??"").split(Yc).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(Pa(mi(mi(mi(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function sp(t,e=process.env.PATH){if(op(t))return t;for(let n of ip(e)){let r=Pa(n,t);if(rp(r))return r}return t}function oe(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function ap(t){if(typeof t=="string")return t;if(!oe(t))return String(t);if(typeof t.text=="string")return t.text;let e=oe(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function ba(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 lp(t){let e=ba(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function va(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return np.map(r=>({permission:r,pattern:"*",action:n}))}function fi(){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 dp(){return new Promise((t,e)=>{let n=Jc();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 Ra(t){await new Promise(e=>setTimeout(e,t))}async function nr(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(l),e.signal?.removeEventListener("abort",a)},s=d=>{o||(o=!0,i(),d())},a=()=>{s(()=>r(new Error(e.abortMessage??"Operation was aborted.")))},l=setTimeout(()=>{s(()=>{e.onTimeout?.(),r(new Error(e.timeoutMessage))})},e.timeoutMs);e.signal?.addEventListener("abort",a,{once:!0}),t.then(d=>s(()=>n(d)),d=>s(()=>r(d)))})}async function xt(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 up(t){return t.headers.get("content-type")?.toLowerCase()??""}function hi(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function cp(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function pp(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=hi(r),s=cp(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 mp(t,e,n){let r=ba(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function fp(t,e){if(!oe(t))return!1;if(!(e in t))return!0;let n=t[e];return oe(n)&&n.type==="idle"}function gp(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function hp(t){return new Promise((e,n)=>{wa=wa.then(()=>t().then(e,n)).catch(()=>{})})}async function yp(t){return hp(async()=>{let e=await dp(),n=process.env[Xc]?.trim()||"opencode",r=sp(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??Si,1e4),a=t.startupTimeoutMs??ep,l=Hc(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),d=`http://127.0.0.1:${e}`,u="",c="",p,f=(S,b)=>{let A=S+String(b);return A.length>8e3?A.slice(-8e3):A};l.stdout.on("data",S=>{u=f(u,S)}),l.stderr.on("data",S=>{c=f(c,S)}),l.once("error",S=>{p=S});let m=()=>` Command: ${n===r?r:`${r} (resolved from ${n})`} ${o.join(" ")}. Cwd: ${t.cwd}. Port: ${e}. PATH: ${process.env.PATH??""}.`,y=()=>{let S=[u.trim(),c.trim()].filter(Boolean).join(`
1
+ var tc=Object.defineProperty;var H=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var nc=(t,e)=>{for(var n in e)tc(t,n,{get:e[n],enumerable:!0})};function tn(t,e){return e?{...e,...t}:t}function rc(t){return{...t,[ti]:!0}}function oc(t){return{const:t,type:typeof t}}var ti,g,re=H(()=>{ti=Symbol("optionalSchema");g={Object(t,e){let n=Object.entries(t).filter(([,o])=>!o[ti]).map(([o])=>o),r=Object.fromEntries(Object.entries(t).map(([o,i])=>{let{[ti]:s,...a}=i;return[o,a]}));return{...e,type:"object",...n.length>0?{required:n}:{},properties:r}},String(t){return tn({type:"string"},t)},Number(t){return tn({type:"number"},t)},Boolean(t){return tn({type:"boolean"},t)},Array(t,e){return tn({type:"array",items:t},e)},Literal:oc,Union(t,e){return tn({anyOf:t},e)},Optional:rc}});function ni(t){v=t}function ri(t){z=t}var v,z,K=H(()=>{v=null,z=null});function Ks(t){let e=t.chatId.trim(),n=t.topicId.trim();return!/^-?\d+$/.test(e)||!/^\d+$/.test(n)?null:`${e}:topic:${n}`}function lc(t){let e=t.conversationId.trim(),n=e.match(/^(-?\d+):topic:(\d+)$/i);if(n?.[1]&&n[2]){let i=Ks({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=Ks({chatId:r,topicId:e});return o?{chatId:r,topicId:e,canonicalConversationId:o}:null}function uc(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 cc(t,e){if(!/^\d+$/.test(t))return t;let n=uc(e);return n?`${n}:${t}`:`channel:${t}`}function pc(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 mc(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 fc(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||!dc.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 gc(t,e=lc){try{return e({conversationId:t})}catch{return null}}function oi(t){return{provider:"system",target:"system",sessionKey:t?.trim()||void 0}}function ii(t,e){return{...t,threadId:e??t.threadId}}function yc(t,e,n){return t==="telegram"&&n?.provider==="telegram"&&!!n.target&&e!==n.target}function kc(t){let e=t?.trim();if(!e)return;let n=fc(e);if(!n)return;let{provider:r,kind:o,rawId:i}=n,s=mc(i),a=null;if(r==="telegram")try{a=hc.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 si(t){let e=t?.match(/:topic:(\d+)$/i);return e?parseInt(e[1],10):void 0}function Us(t){return!!(t?.provider&&t.target&&t.provider!=="system"&&t.target!=="system")}function nn(t,e,n){let r=kc(n),o=e!=null?String(e):void 0,i=t?.trim();if(!i||i.toLowerCase()==="unknown")return r?ii(r,o):oi(n);let s=i.split("|").map(m=>m.trim());if(s.length<2)return r?ii(r,o):oi(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?ii(r,o):oi(n);let f=p==="discord"?cc(u,n):u;return yc(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 rt(t){return nn(pc(t.route)??t.originChannel,t.route?.threadId??t.originThreadId,t.route?.sessionKey??t.originSessionKey)??t.route}function De(t){let e=rt(t);return Us(e)?e:void 0}function Sc(t){return Object.fromEntries(Object.entries(t).filter(e=>!!e[1]))}function rn(t){let e=rt(t);if(!Us(e))return"";let n=Sc({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 dc,hc,xe=H(()=>{dc=new Set(["telegram","discord","slack","system","mattermost","feishu","line","whatsapp","signal","matrix","googlechat","bluebubbles","imessage","msteams"]);hc={safeParseTelegramTopicConversation:gc}});import{readFileSync as vc}from"fs";import{homedir as wc}from"os";import{join as Pc}from"path";function Gs(){if(on!==void 0)return on;try{let t=vc(Pc(wc(),".claude.json"),"utf-8");on=JSON.parse(t).mcpServers??{}}catch{on={}}return on}function js(t){let e=t.defaultHarness??Vs,n={};for(let[r,o]of Object.entries(sn)){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 le(){return E.defaultHarness??Vs}function li(t){let e=sn[t],n=E.harnesses[t];return{...e,...n,allowedModels:n?.allowedModels??e?.allowedModels}}function vt(t){return li(t).defaultModel}function Kn(t){return E.harnesses[t]?.allowedModels??E.allowedModels}function He(t){return li(t).reasoningEffort}function wt(t){return t==="codex"?li(t).fastMode:void 0}function Se(t){return t==null?void 0:String(t).trim()||void 0}function ui(t){return{channel:Se(t?.deliveryContext?.channel),to:Se(t?.deliveryContext?.to),accountId:Se(t?.deliveryContext?.accountId),threadId:Se(t?.deliveryContext?.threadId)}}function Hs(t,e,n){if(!(!t||!e))return n?`${t}|${n}|${e}`:`${t}|${e}`}function ai(t){return Se(t?.requesterSenderId??t?.senderId)}function di(t){return(Se(t.deliveryContext?.channel)??t.messageChannel??t.channel)?.toLowerCase()!=="telegram"?!1:!!(si(t.sessionKey)||Se(t.messageThreadId)||Se(t.deliveryContext?.threadId))}function Un(t){let e=ui(t),n=Hs(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=Se(t.chatId);if(r.length===1&&o)return`${r[0]}|${o}`;let i=ai(t);if(r.length===1&&i&&!di(t))return`${r[0]}|${i}`}if(t.workspaceDir){let r=ot(t.workspaceDir);if(r)return r}if(t.messageChannel&&t.messageChannel.includes("|"))return t.messageChannel}function an(t,e){if(e&&String(e).includes("|"))return String(e);let n=ui(t),r=Hs(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=Se(t.chatId);if(d)return`${a}|${d}`;let l=ai(t);if(l&&!di(t))return`${a}|${l}`}let o=Se(t?.channel),i=Se(t?.chatId);if(o&&i)return`${o}|${i}`;let s=ai(t);return o&&s&&!di(t)?`${o}|${s}`:t?.id&&/^-?\d+$/.test(String(t.id))?`telegram|${t.id}`:E.fallbackChannel??"unknown"}function ci(t){return ui(t).threadId??t?.messageThreadId??void 0}function Pt(t,e,n){return nn(an(t,e),ci(t),n??t?.sessionKey)}function ot(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 zs(t){return si(t)}var on,Vs,sn,E,ae=H(()=>{xe();Vs="claude-code",sn={"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":{...sn["claude-code"]},codex:{...sn.codex},opencode:{...sn.opencode}}}});function U(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function j(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 Qs(t,e){return e&&typeof e.recommended=="boolean"?e.recommended:e&&typeof e.isRecommended=="boolean"?e.isRecommended:/\b(?:not\s+(?:a\s+)?|non[-\s]?|un)recommended\b/i.test(t)?!1:/\brecommended\b/i.test(t)}function Js(t){if(typeof t=="string"){let s=t.trim();return s?{label:s,value:s,recommended:Qs(s)}:void 0}let e=U(t);if(!e)return;let n=j(e,["label","title","text","value","name","id"])?.trim();if(!n)return;let r=j(e,["description","preview","detail","details"]),o=j(e,["value","id","name"]),i=e.isOther===!0||e.is_other===!0||e.other===!0;return{label:n,...r?{description:r}:{},...o?{value:o}:{},...i?{isOther:!0}:{},recommended:Qs(n,e)}}function Vn(t){let e=U(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(Js).filter(r=>!!r):[]}function Rt(t){let e=U(t);return(Array.isArray(e?.questions)?e.questions:[]).map((r,o)=>bc(r,o)).filter(r=>!!r)}function bc(t,e=0){let n=U(t);if(!n)return;let r=j(n,["question","prompt","message","text","summary"])?.trim();if(!r)return;let o=j(n,["id","questionId","question_id","name"]),i=j(n,["header","title","label"]),a=(Array.isArray(n.options)?n.options:Array.isArray(n.choices)?n.choices:[]).map(Js).filter(u=>!!u),d=n.multiSelect===!0||n.multi_select===!0,l=n.isOther===!0||n.is_other===!0||n.allowFreeText===!0||n.allowsFreeText===!0||d||a.some(u=>u.isOther);return{id:o??`question_${e+1}`,...i?{header:i}:{},question:r,options:a,...d?{multiSelect:!0}:{},...l?{allowsFreeText:!0}:{},...n.isSecret===!0||n.is_secret===!0?{isSecret:!0}:{}}}function Ys(t,e,n){let r=[n>1?`Question ${e+1}`:void 0,t.header].filter(Boolean).join(" - "),o=[...r?[r]:[],t.question];return t.options.length>0&&o.push("Options:",...t.options.map((i,s)=>{let a=i.recommended&&!/\brecommended\b/i.test(i.label)?" (recommended)":"",d=i.description?` - ${i.description}`:"",l=i.isOther?" (free text)":"";return` ${s+1}. ${i.label}${a}${l}${d}`})),t.allowsFreeText&&!t.options.some(i=>i.isOther)&&o.push(t.multiSelect?"Reply with one or more option labels.":"Free-form answer is allowed."),o}function Gn(t){if(t.length===0)return;let e=t.flatMap((n,r)=>[...r>0?[""]:[],...Ys(n,r,t.length)]);return t.length>1&&e.push("","Reply with answers by question, for example: Q1: ..., Q2: ..."),e.join(`
3
+ `)}function Oe(t,e,n){return Ys(t,e,n).join(`
4
+ `)}var dn=H(()=>{});function At(t){return{type:"backend_ref",ref:t}}function It(t){return{type:"run_started",...t?{runId:t}:{}}}function it(t){return{type:"text_delta",text:t}}function jn(t,e){return{type:"tool_call",name:t,input:e}}function _e(t){return{type:"pending_input",state:t}}function Qe(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function Hn(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function xt(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function We(t){return{type:"run_completed",data:t}}var ze,zn=H(()=>{ze=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 Jn from"@anthropic-ai/claude-agent-sdk";function Rc(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(`
5
+ `)}}function Ac(t,e,n){let r=Rt(n),o=r.length>0?0:void 0,i=o!=null?r[o]:void 0,s=i?.options.map(d=>d.label)??[],a=i?Oe(i,o,r.length):Gn(r);return{requestId:`${t||"claude"}-ask-${e}`,kind:"question",promptText:a,options:s,...r.length>0?{questions:r}:{},...o!=null?{activeQuestionIndex:o}:{},allowsFreeText:i?.allowsFreeText===!0||s.length===0}}var Qn,Zs=H(()=>{dn();zn();Qn=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 ze,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(m,y)=>{if(m!=="AskUserQuestion")return{behavior:"allow"};let k=Ac(a,++s,y);n.enqueue(_e(k));try{let S=await d(m,y);return n.enqueue(Qe(k.requestId)),S}catch(S){throw n.enqueue(Qe(k.requestId)),S}}}:{}};e.resumeSessionId&&(l.resume=e.resumeSessionId,l.forkSession=e.forkSession??!1);let u=e.prompt,c=this.deps.query??Jn.query,p=this.deps.startup??Jn.startup,f=(async()=>{if(typeof p!="function")return c({prompt:u,options:l});let m=await p({options:l});try{return m.query(u)}catch(y){throw await m.close?.(),y}})();return(async()=>{try{let m=await f;for await(let y of m){let k=y;if(k.type==="system"&&k.subtype==="init"){a=k.session_id??a,n.enqueue(At({kind:"claude-code",conversationId:a}));continue}if(k.type==="system"&&k.subtype==="status"&&k.permissionMode){n.enqueue(xt(k.permissionMode));continue}if(k.type==="assistant"){r||(r=!0,n.enqueue(It()));for(let S of k.message?.content??[]){if(S.type==="text"){o+=o?`
6
+ ${S.text}`:S.text,n.enqueue(it(S.text));continue}S.type==="tool_use"&&((S.name==="ExitPlanMode"||S.name==="set_permission_mode")&&(i=!0),S.name!=="AskUserQuestion"&&n.enqueue(jn(S.name,S.input)))}continue}if(k.type==="result"){let S=o.trim();if(S&&(e.permissionMode==="plan"||i)){let b={explanation:void 0,steps:[],markdown:S};n.enqueue(Hn(b,!0))}n.enqueue(We({success:k.subtype==="success",duration_ms:k.duration_ms??0,total_cost_usd:k.total_cost_usd??0,num_turns:k.num_turns??0,result:Rc(k),session_id:k.session_id??a})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(m=>{n.enqueue(We({success:!1,duration_ms:0,total_cost_usd:0,num_turns:0,result:m instanceof Error?m.message:String(m),session_id:a})),n.close()}),{messages:n.messages(),async setPermissionMode(m){let y=await f;typeof y.setPermissionMode=="function"&&await y.setPermissionMode(m)},async streamInput(m){let y=await f;typeof y.streamInput=="function"&&await y.streamInput(m)},async interrupt(){let m=await f;typeof m.interrupt=="function"&&await m.interrupt()}}}buildUserMessage(e,n){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:n}}}});import{spawn as Ic}from"node:child_process";import xc from"node:readline";function Xs(t){return t instanceof Error?t.message:String(t)}function Tt(t,e){JSON.stringify({component:"CodexAppServerRpc",event:t,at:new Date().toISOString(),...e})}function Tc(t,e){return{commandKind:t==="codex"?"codex":"custom",appServerSubcommand:!0,configuredArgCount:e.length}}function Cc(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function Mc(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:Xs(r)}})}}}function pi(t){return t.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/?#@]+@/gi,"$1[redacted credential]@").replace(/\b(authorization\s*[:=]\s*)[^\r\n,;}]+/gi,"$1[redacted credential]").replace(/\b(Bearer\s+)[^\s]+/gi,"$1[redacted credential]").replace(/(["'][A-Za-z0-9_.-]*(?:api[_-]?key|token|secret|password|authorization)[A-Za-z0-9_.-]*["']\s*:\s*["'])[^"']+(["'])/gi,"$1[redacted credential]$2").replace(/\b([A-Za-z0-9_.-]*(?:api[_-]?key|token|secret|password|authorization)[A-Za-z0-9_.-]*\s*[:=]\s*)[^\s,}]+/gi,"$1[redacted credential]").replace(/\b(?:sk-[A-Za-z0-9_-]{8,}|gh[opsru]_[A-Za-z0-9_]{8,}|[A-Za-z0-9_-]{32,})\b/g,"[redacted token]").replace(/(?:\/Users|\/home)\/[^\s]+/g,"[redacted path]").replace(/\s+/g," ").slice(-1e3)}var Yn,ea=H(()=>{Yn=class{constructor(e,n,r){this.command=e;this.args=n;this.requestTimeoutMs=r}command;args;requestTimeoutMs;process=null;pending=new Map;stderrTail="";counter=0;onNotification=()=>{};onRequest=async()=>({});setNotificationHandler(e){this.onNotification=e}setRequestHandler(e){this.onRequest=e}async connect(){if(this.process)return;let e=Ic(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(Tt("process.spawn",{...Tc(this.command,this.args),pid:e.pid,requestTimeoutMs:this.requestTimeoutMs}),!e.stdin||!e.stdout||!e.stderr)throw new Error("codex app server stdio pipes unavailable");this.process=e,xc.createInterface({input:e.stdout}).on("line",r=>{this.handleLine(r)}),e.stderr.on("data",r=>{this.stderrTail=`${this.stderrTail}${r.toString("utf8")}`.slice(-4e3)}),e.on("error",r=>{Tt("process.error",{pid:e.pid,error:Xs(r)})}),e.on("close",(r,o)=>{Tt("process.close",{pid:e.pid,code:r,signal:o,pendingRequests:this.pending.size,recentStderr:pi(this.stderrTail.trim())}),this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){Tt("client.close",{pid:this.process?.pid,pendingRequests:this.pending.size}),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=Math.max(100,r??this.requestTimeoutMs),l=setTimeout(()=>{this.pending.delete(o),Tt("request.timeout",{id:o,method:e,timeoutMs:d,pid:this.process?.pid,recentStderr:pi(this.stderrTail.trim())}),a(new Error(this.buildTimeoutErrorMessage(e,d)))},d);l.unref?.(),this.pending.set(o,{resolve:s,reject:a,timer:l})});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)}
7
+ `)}async handleLine(e){let n=Cc(e);n&&await Mc(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){this.pending.size>0&&Tt("pending.flush",{pendingRequests:this.pending.size,error:e.message,pid:this.process?.pid});for(let[n,r]of this.pending)clearTimeout(r.timer),r.reject(e),this.pending.delete(n)}buildTimeoutErrorMessage(e,n){let r=this.stderrTail.trim(),o=r?`; recent stderr: ${pi(r)}`:"";return`codex app server timeout after ${n}ms: ${e}${o}`}}});function ta(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()))}var na=H(()=>{});function Ne(t,e){let n=e?.trim();if(!n)return;if(t!=="codex")return n;let[r,...o]=n.split("/");return r?.toLowerCase()==="openai"&&o.length===1&&o[0]?.trim()?o[0].trim():n}function _c(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>Ne("codex",r)?.toLowerCase()===n)}function Zn(t,e,n){return t==="codex"?_c(e,n):ta(e,n)}function Ct(t,e){return t!=="codex"||!e?!0:!e.includes("/")}function Xn(t,e,n){if(t!=="codex"||!e||!n||n.length===0)return e;let r=e.toLowerCase(),o=n.find(i=>Ne("codex",i)?.toLowerCase()===r);return Ne("codex",o)??e}var er=H(()=>{na()});function $c(t){return t instanceof Error?t.message:String(t)}function ra(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function Je(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>Je(n)).join("");let e=U(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=Je(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=Je(e[n]);if(r)return r}return""}function ln(t){let e=U(t);if(!e)return{};let n=U(e.thread)??U(e.session),r=U(e.turn)??U(e.run),o=U(e.item),i=U(e.serverRequest);return{threadId:j(e,["threadId","thread_id","conversationId","conversation_id"])??j(n,["id","threadId","thread_id","conversationId"]),runId:j(e,["turnId","turn_id","runId","run_id"])??j(r,["id","turnId","turn_id","runId","run_id"]),requestId:j(e,["requestId","request_id","serverRequestId"])??j(i,["id","requestId","request_id"]),itemId:j(e,["itemId","item_id"])??j(o,["id","itemId","item_id"])}}function tr(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=tr(i,e,n+1);if(s)return s}return}let r=U(t);if(!r)return;let o=j(r,e);if(o)return o;for(let i of Object.values(r)){let s=tr(i,e,n+1);if(s)return s}}function un(t){return{threadId:ln(t).threadId,cwd:tr(t,["cwd","workdir","directory"])}}function oa(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function ia(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 nr(t){let e=U(t);if(!e)return;let n=U(e.item)??e;return j(n,["id","itemId","item_id","messageId","message_id"])}function Ec(t,e=!1){let n=U(t);if(!n)return"";let r=U(n.item)??n;return j(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?Je(r):j(r,["text"],{trim:!1})??Je(r)}function sa(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:Je(e),itemId:nr(e)}:n==="item/completed"?{mode:"snapshot",text:Ec(e),itemId:nr(e)}:{mode:"ignore",text:""}}function aa(t){return{itemId:nr(t),delta:Je(t)}}function da(t){let e=U(t),n=U(e?.plan),o=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(i=>{let s=U(i),a=j(s,["step","title","text"]);if(!a)return null;let d=j(s,["status"])?.toLowerCase()??"pending";return{step:a,status:d==="inprogress"||d==="in_progress"?"inProgress":d==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:j(n,["explanation"])??j(e,["explanation"]),steps:o}}function la(t){let e=U(t);if(!e)return{};let n=U(e.item)??e;return j(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:nr(n),text:j(n,["text"],{trim:!1})??Je(n)}}function ua(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=U(e)??{},o=U(r.turn)??r,i=j(o,["status"])?.toLowerCase();return i==="failed"?"failed":i==="interrupted"||i==="cancelled"?"interrupted":"completed"}function ca(t,e){let n=U(e)??{},r=U(n.turn)??n,o=U(r.error)??U(n.error);if(o)return j(o,["message","text","summary","reason"])}function Dc(t,e){let n=$c(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 Wc(t){return Oc.has(t.trim().toLowerCase())}function Nc(t){let e=U(t);return e?!!j(e,["threadId","thread_id"]):!1}async function cn(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(Wc(n)&&!Nc(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,!Dc(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function pa(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 ma(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 Lc(t){return[{type:"text",text:t}]}function Bc(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 fa(t){let e={threadId:t.threadId,input:Lc(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=Bc(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function ga(t){return[{threadId:t.threadId,turnId:t.turnId}]}function Fc(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 ha(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=Rt(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let a=o?Vn(n):[],d=s.length>0?0:void 0,l=d!=null?s[d]:void 0,u=l?l.options:[],p=(o&&u.length===0?a:u).map(y=>y.label),f=(l?Oe(l,d??0,s.length):Gn(s))??(o?tr(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,m=o?p.map(y=>({kind:"approval",label:y,decision:Fc(y),responseDecision:y})):p.map(y=>({kind:"option",label:y,value:y}));return{requestId:e,kind:o?"approval":"question",promptText:f,options:p,...s.length>0?{questions:s}:{},...d!=null?{activeQuestionIndex:d}:{},actions:m,allowsFreeText:!0}}function ya(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 Oc,ka=H(()=>{dn();Oc=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function jc(t){let e=t?.trim();return e&&Gc.test(e)?e:void 0}function Hc(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return fi;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:fi}function pn(t){return t instanceof Error?t.message:String(t)}function ve(t,e){JSON.stringify({component:"CodexHarness",event:t,at:new Date().toISOString(),...e})}function zc(t){return{commandKind:t.command==="codex"?"codex":"custom",configuredArgCount:t.args.length,requestTimeoutMs:t.requestTimeoutMs}}function Le(t){return{hasThreadId:!!t.threadId,hasTurnId:!!t.turnId,hasBackendWorktreePath:!!t.backendWorktreePath,hasBackendWorktreeId:!!t.backendWorktreeId}}function Qc(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)}function va(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:Oe(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}function Jc(t){if(t===void 0)return Sa;let e=ra(t);return e.length>0?e:Sa}var qc,fi,Sa,Kc,Uc,Vc,Gc,rr,wa=H(()=>{ea();zn();dn();er();ka();qc="1.0",fi=12e4,Sa=["--listen","stdio://"],Kc="OPENCLAW_CODEX_APP_SERVER_COMMAND",Uc="OPENCLAW_CODEX_APP_SERVER_ARGS",Vc="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS",Gc=/^(?:urn:uuid:)?[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;rr=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[Kc]?.trim()||"codex",args:Jc(process.env[Uc]),requestTimeoutMs:Hc(process.env[Vc])},r=this.deps.createClient?.(n)??new Yn(n.command,n.args,n.requestTimeoutMs),o=new ze,i=jc(e.resumeSessionId);e.resumeSessionId;let s,a=e.backendRef?.worktreePath,d=e.backendRef?.worktreeId,l=e.permissionMode??"default",u=Ne(this.name,e.model);if(!Ct(this.name,u))throw new Error(`Codex model "${e.model}" is not supported. Use a bare Codex model id such as "gpt-5.5".`);let c,p=0,f="",m=[],y,k=new Map,S=new Set,b=D=>{let C=D?.trim();if(!C)return;let T=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&C!==T&&oa(C)&&(a=C,d=ia(C))},A=()=>{i&&o.enqueue(At({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...d?{worktreeId:d}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async(D,C)=>{let T=D.trim().toLowerCase(),F=ln(C),q=un(C);if(F.threadId&&i&&F.threadId!==i)return;if(F.threadId&&(i=F.threadId),F.runId&&(s=F.runId),b(q.cwd),(F.threadId||F.runId||q.cwd)&&A(),T==="serverrequest/resolved"){c&&(o.enqueue(Qe(c.requestId)),c=void 0);return}if(T==="turn/plan/updated"){let G=da(C);f=G.explanation??f,G.steps.length>0&&(m=G.steps);return}if(T==="item/plan/delta"){let G=aa(C);if(G.itemId&&G.delta){let se=k.get(G.itemId)??"";k.set(G.itemId,`${se}${G.delta}`)}return}if(T==="item/completed"){let G=la(C);if(G.text?.trim()){let se={explanation:f||void 0,steps:m,markdown:G.text.trim()};o.enqueue(Hn(se,!0));return}}let L=sa(T,C);if(L.mode==="delta"&&L.text){L.itemId&&S.add(L.itemId),o.enqueue(it(L.text));return}L.mode==="snapshot"&&L.text&&(!L.itemId||!S.has(L.itemId))&&o.enqueue(it(L.text)),(T==="turn/completed"||T==="turn/failed"||T==="turn/cancelled")&&y&&(y.method=D,y.params=C,y.resolve())}),r.setRequestHandler(async(D,C)=>{if(!ya(D))return{};let T=ln(C),F=un(C);if(T.threadId&&i&&T.threadId!==i)return{};T.threadId&&(i=T.threadId),T.runId&&(s=T.runId),b(F.cwd),(T.threadId||T.runId||F.cwd)&&A();let q=T.requestId??`${i??"codex"}-${Date.now().toString(36)}`,L;try{L=ha(D,q,C)}catch(Zt){let Xt=pn(Zt);return`${Xt}`,{error:Xt}}let G=D.trim().toLowerCase(),se=L.options,Ie=L.actions??[],kt=await new Promise(Zt=>{c={requestId:q,methodLower:G,state:L,options:se,actions:Ie,answers:{...L.answers??{}},resolveResponse:Zt},o.enqueue(_e(L))});return c=void 0,o.enqueue(Qe(q)),kt});let x=async()=>{ve("client.initialize.start",{...zc(n),hasResumeSessionId:!!e.resumeSessionId}),await r.connect(),await r.request("initialize",{protocolVersion:qc,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},n.requestTimeoutMs),await r.notify("initialized",{}),ve("client.initialize.done",{hasResumeSessionId:!!e.resumeSessionId})},R=async()=>{let D=mi(l,e.codexApprovalPolicy);if(i){ve("thread.resume.start",Le({threadId:i}));let F=await cn({client:r,methods:["thread/resume"],payloads:ma({threadId:i,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:D.approvalPolicy,sandbox:D.sandbox}),timeoutMs:n.requestTimeoutMs}),q=un(F);i=q.threadId??i,b(q.cwd),A(),ve("thread.resume.done",{...Le({threadId:i,backendWorktreePath:a,backendWorktreeId:d})});return}ve("thread.start.start",{hasCwd:!!e.cwd});let C=await cn({client:r,methods:["thread/start","thread/new"],payloads:pa({cwd:e.cwd,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:D.approvalPolicy,sandbox:D.sandbox}),timeoutMs:n.requestTimeoutMs}),T=un(C);if(i=T.threadId,!i)throw new Error("Codex App Server did not return a thread id.");b(T.cwd),A(),ve("thread.start.done",{...Le({threadId:i,backendWorktreePath:a,backendWorktreeId:d})})},h=async D=>{await R(),ve("turn.start",{...Le({threadId:i}),runCounter:p+1,promptChars:D.length,permissionMode:l}),o.enqueue(It()),p+=1,f="",m=[],k.clear(),S.clear();let C="",T,F,q=new Promise(L=>{F=L});y={resolve:F};try{let L=mi(l,e.codexApprovalPolicy),G=await cn({client:r,methods:["turn/start"],payloads:fa({threadId:i,prompt:D,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:l,approvalPolicy:L.approvalPolicy,sandbox:L.sandbox}),timeoutMs:n.requestTimeoutMs}),se=ln(G);se.runId&&(s=se.runId,A()),await q,C=y?.method??"turn/failed",T=y?.params;let Ie=ua(C,T);ve("turn.terminal",{...Le({threadId:i,turnId:s}),terminalMethod:C,outcome:Ie}),o.enqueue(We({success:Ie==="completed",outcome:Ie,duration_ms:0,total_cost_usd:0,num_turns:p,result:ca(C,T),session_id:i}))}catch(L){ve("turn.error",{...Le({threadId:i,turnId:s}),error:pn(L)}),o.enqueue(We({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:pn(L),session_id:i??""}))}finally{y=void 0}},w=async D=>{let C=c;if(!C)return!1;let T=D.trim();if(C.methodLower.includes("requestapproval"))return C.resolveResponse({decision:T||"decline"}),!0;let F=C.state.questions??[];if(F.length>0){if(!T)return!1;let q=C.state.activeQuestionIndex??0,L=F[q];if(!L)return!1;C.answers={...C.answers,[L.id]:{answers:[T]}};let G=q+1;if(G<F.length)return C.state=va(C.state,G,C.answers),C.options=C.state.options,o.enqueue(_e(C.state)),!0;C.resolveResponse({answers:C.answers})}else C.resolveResponse({text:T});return!0},N=async(D,C={})=>{let T=c;if(!T||C.requestId&&C.requestId!==T.state.requestId)return!1;let F=T.actions[D];if(F?.kind==="approval")return T.resolveResponse({decision:F.responseDecision,...F.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:F.proposedExecpolicyAmendment}:{}}),!0;let q=T.state.questions??[],L=T.state.activeQuestionIndex??0,G=q.length>0?q[L]:void 0;if(C.questionId&&C.questionId!==G?.id)return!1;let se=G?.options[D];if(G&&se){T.answers={...T.answers,[G.id]:{answers:[se.value??se.label]}};let kt=L+1;return kt<q.length?(T.state=va(T.state,kt,T.answers),T.options=T.state.options,o.enqueue(_e(T.state)),!0):(T.resolveResponse({answers:T.answers}),!0)}let Ie=T.options[D];return Ie?(T.methodLower.includes("requestapproval")?T.resolveResponse({decision:Ie}):T.resolveResponse({option:Ie,index:D}),!0):!1},Q=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{await x();for await(let D of Q){let C=Qc(D).trim();!C||await w(C)||await h(C)}}catch(D){ve("session.error",{...Le({threadId:i,turnId:s}),error:pn(D)}),o.enqueue(We({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:pn(D),session_id:i??e.resumeSessionId??""}))}finally{ve("client.close.start",Le({threadId:i,turnId:s})),await r.close().catch(()=>{}),ve("client.close.done",Le({threadId:i,turnId:s})),o.close()}})(),{messages:o.messages(),async setPermissionMode(D){l=D,o.enqueue(xt(D))},async submitPendingInputOption(D,C){return N(D,C)},async submitPendingInputText(D){return w(D)},async interrupt(){!i||!s||await cn({client:r,methods:["turn/interrupt"],payloads:ga({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as Yc}from"node:child_process";import{constants as Zc,accessSync as Xc}from"node:fs";import{createServer as ep}from"node:net";import{delimiter as tp,dirname as gi,join as Ra,sep as np}from"node:path";function _t(t){return t instanceof Error?t.message:String(t)}function ap(t){try{return Xc(t,Zc.X_OK),!0}catch{return!1}}function dp(t){return t.includes("/")||np==="\\"&&t.includes("\\")}function lp(t){let e=(t??"").split(tp).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(Ra(gi(gi(gi(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function up(t,e=process.env.PATH){if(dp(t))return t;for(let n of lp(e)){let r=Ra(n,t);if(ap(r))return r}return t}function oe(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function cp(t){if(typeof t=="string")return t;if(!oe(t))return String(t);if(typeof t.text=="string")return t.text;let e=oe(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function Aa(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 pp(t){let e=Aa(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function Pa(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return sp.map(r=>({permission:r,pattern:"*",action:n}))}function hi(){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 mp(){return new Promise((t,e)=>{let n=ep();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 Ia(t){await new Promise(e=>setTimeout(e,t))}async function or(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 Mt(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 fp(t){return t.headers.get("content-type")?.toLowerCase()??""}function ki(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function gp(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function hp(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=ki(r),s=gp(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 yp(t,e,n){let r=Aa(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function kp(t,e){if(!oe(t))return!1;if(!(e in t))return!0;let n=t[e];return oe(n)&&n.type==="idle"}function Sp(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function vp(t){return new Promise((e,n)=>{ba=ba.then(()=>t().then(e,n)).catch(()=>{})})}async function wp(t){return vp(async()=>{let e=await mp(),n=process.env[rp]?.trim()||"opencode",r=up(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??wi,1e4),a=t.startupTimeoutMs??op,d=Yc(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),l=`http://127.0.0.1:${e}`,u="",c="",p,f=(S,b)=>{let A=S+String(b);return A.length>8e3?A.slice(-8e3):A};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 m=()=>` Command: ${n===r?r:`${r} (resolved from ${n})`} ${o.join(" ")}. Cwd: ${t.cwd}. Port: ${e}. PATH: ${process.env.PATH??""}.`,y=()=>{let S=[u.trim(),c.trim()].filter(Boolean).join(`
8
8
  `).trim();return`${m()}${S?` Output:
9
- ${S}`:""}`},k=()=>{xt(l)};if(t.signal?.aborted)throw await xt(l),new Error(`OpenCode server startup aborted before readiness.${y()}`);t.signal?.addEventListener("abort",k,{once:!0});try{let S=Date.now();for(;Date.now()-S<a;){if(t.signal?.aborted)throw await xt(l),new Error(`OpenCode server startup aborted before readiness.${y()}`);if(p)throw new Error(`OpenCode server failed to start: ${p.message}${y()}`);if(l.exitCode!==null)throw new Error(`OpenCode server exited before readiness.${y()}`);try{if(await Sp({baseUrl:d,fetchImpl:i,requestTimeoutMs:s,startupSignal:t.signal,timeoutMessage:`OpenCode GET /api/health timed out after ${s}ms during server readiness.${y()}`,abortMessage:`OpenCode server startup aborted before readiness.${y()}`}))return{baseUrl:d,close:async()=>{await xt(l)}}}catch{if(t.signal?.aborted)throw await xt(l),new Error(`OpenCode server startup aborted before readiness.${y()}`)}await Ra(100)}throw await xt(l),new Error(`Timed out waiting for OpenCode server readiness.${y()}`)}finally{t.signal?.removeEventListener("abort",k)}})}async function kp(t){for(let e=1;;e+=1)try{return await yp(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(Tt(n)))throw n}}async function Sp(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await nr(t.fetchImpl(`${t.baseUrl}/api/health`,{headers:fi(),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 vp(t){let e=oe(t)&&oe(t.payload)?t.payload:t;return oe(e)?e.type==="sync"?{type:typeof e.name=="string"?e.name.replace(/\.\d+$/,""):void 0,properties:oe(e.data)?e.data:{}}:{type:typeof e.type=="string"?e.type:void 0,properties:oe(e.properties)?e.properties:e}:{properties:{}}}function wp(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function Pp(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 bp(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=wt(t),o=Kn(t),i=r.length>0?r:[{id:e,question:n,options:o,allowsFreeText:!0}],s=i.length>0?0:void 0,a=s!=null?i[s]:void 0,l=a?.options.map(d=>d.label)??o.map(d=>d.label);return{requestId:e,kind:"question",promptText:a?De(a,s??0,i.length):n,options:l,...i.length>0?{questions:i}:{},...s!=null?{activeQuestionIndex:s}:{},allowsFreeText:!0}}function Rp(t,e,n){let r=t.questions??[],o=r[e],i=o?.options.map(s=>s.label)??[];return{...t,promptText:o?De(o,e,r.length):t.promptText,options:i,activeQuestionIndex:e,answers:n}}function Ap(t,e){return t.length===1?e[t[0].id]?.answers.join(", ")??"":t.map((n,r)=>{let o=e[n.id]?.answers.join(", ")??"";return`Q${r+1}: ${n.question}
9
+ ${S}`:""}`},k=()=>{Mt(d)};if(t.signal?.aborted)throw await Mt(d),new Error(`OpenCode server startup aborted before readiness.${y()}`);t.signal?.addEventListener("abort",k,{once:!0});try{let S=Date.now();for(;Date.now()-S<a;){if(t.signal?.aborted)throw await Mt(d),new Error(`OpenCode server startup aborted before readiness.${y()}`);if(p)throw new Error(`OpenCode server failed to start: ${p.message}${y()}`);if(d.exitCode!==null)throw new Error(`OpenCode server exited before readiness.${y()}`);try{if(await bp({baseUrl:l,fetchImpl:i,requestTimeoutMs:s,startupSignal:t.signal,timeoutMessage:`OpenCode GET /api/health timed out after ${s}ms during server readiness.${y()}`,abortMessage:`OpenCode server startup aborted before readiness.${y()}`}))return{baseUrl:l,close:async()=>{await Mt(d)}}}catch{if(t.signal?.aborted)throw await Mt(d),new Error(`OpenCode server startup aborted before readiness.${y()}`)}await Ia(100)}throw await Mt(d),new Error(`Timed out waiting for OpenCode server readiness.${y()}`)}finally{t.signal?.removeEventListener("abort",k)}})}async function Pp(t){for(let e=1;;e+=1)try{return await wp(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(_t(n)))throw n}}async function bp(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await or(t.fetchImpl(`${t.baseUrl}/api/health`,{headers:hi(),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 Rp(t){let e=oe(t)&&oe(t.payload)?t.payload:t;return oe(e)?e.type==="sync"?{type:typeof e.name=="string"?e.name.replace(/\.\d+$/,""):void 0,properties:oe(e.data)?e.data:{}}:{type:typeof e.type=="string"?e.type:void 0,properties:oe(e.properties)?e.properties:e}:{properties:{}}}function Ap(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function Ip(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 xp(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=Rt(t),o=Vn(t),i=r.length>0?r:[{id:e,question:n,options:o,allowsFreeText:!0}],s=i.length>0?0:void 0,a=s!=null?i[s]:void 0,d=a?.options.map(l=>l.label)??o.map(l=>l.label);return{requestId:e,kind:"question",promptText:a?Oe(a,s??0,i.length):n,options:d,...i.length>0?{questions:i}:{},...s!=null?{activeQuestionIndex:s}:{},allowsFreeText:!0}}function Tp(t,e,n){let r=t.questions??[],o=r[e],i=o?.options.map(s=>s.label)??[];return{...t,promptText:o?Oe(o,e,r.length):t.promptText,options:i,activeQuestionIndex:e,answers:n}}function Cp(t,e){return t.length===1?e[t[0].id]?.answers.join(", ")??"":t.map((n,r)=>{let o=e[n.id]?.answers.join(", ")??"";return`Q${r+1}: ${n.question}
10
10
  A${r+1}: ${o}`}).join(`
11
11
 
12
- `)}function Ip(t){return ki(t).result}function ki(t){let e=Array.isArray(t)?t:oe(t)&&Array.isArray(t.messages)?t.messages:oe(t)&&Array.isArray(t.items)?t.items:[],n=[];for(let r of e){let o=oe(r)&&oe(r.info)?r.info:r;if(!oe(o)||(typeof o.role=="string"?o.role:o.type)!=="assistant")continue;let s=Array.isArray(o.content)?o.content:[],a=oe(r)&&Array.isArray(r.parts)?r.parts:[];for(let l of[...s,...a])oe(l)&&l.type==="text"&&typeof l.text=="string"&&n.push(l.text)}return{count:n.length,result:n.at(-1)}}var Xc,ep,Si,tp,np,gi,wa,yi,rr,Aa=H(()=>{on();jn();Xc="OPENCLAW_OPENCODE_COMMAND",ep=15e3,Si=6e4,tp=15*6e4,np=["edit","bash","task","todowrite","external_directory"];gi=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};wa=Promise.resolve();yi=class{constructor(e,n,r=Si){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,l=o.timeoutMs??this.requestTimeoutMs,d=`OpenCode ${e} ${n} timed out after ${l}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 nr(this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:{...fi(),...r===void 0?{}:{"content-type":"application/json"}},body:r===void 0?void 0:JSON.stringify(r),signal:i.signal}),{timeoutMs:l,timeoutMessage:d,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!p.ok){let y=await nr(p.text(),{timeoutMs:l,timeoutMessage:d,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}}).catch(()=>"");throw new gi(e,n,p.status,hi(y))}if(p.status===204)return;let f=await nr(p.text(),{timeoutMs:l,timeoutMessage:d,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!f)return;let m=up(p);if(!m.includes("application/json")&&!m.includes("+json"))throw new Error(pp(e,n,m,f));try{return JSON.parse(f)}catch(y){let k=hi(f);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${Tt(y)}${k?`: ${k}`:""}`)}}catch(p){if(i.signal.aborted){if(a)throw new Error(`OpenCode ${e} ${n} timed out after ${l}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:fi(),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 d=>{let u=d.split(/\r?\n/).filter(c=>c.startsWith("data:")).map(c=>c.slice(5).trimStart()).join(`
13
- `).trim();!u||u==="[DONE]"||await e(JSON.parse(u))};for(;;){let{done:d,value:u}=await o.read();if(d)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 l=s.trim();l&&await a(l)}};rr=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 He,r=this.deps.fetch??fetch,o,i,s,a=e.resumeSessionId,l=0,d=e.permissionMode??"default",u,c=!e.resumeSessionId,p=!1,f=!1,m=new AbortController,y,k=!1,S=!1,b=!1,A=!1,x=!1,R=!1,h,w=new Set,L=M=>A?!1:(A=!0,n.enqueue(Oe(M)),!0),ne=(M,I,_)=>L({success:M,outcome:I,duration_ms:0,total_cost_usd:0,num_turns:l,result:_,session_id:a??""}),$=()=>{a&&h!==a&&(h=a,n.enqueue(Pt({kind:"opencode-server",conversationId:a})))},T=M=>{M&&w.has(M)||(M&&w.add(M),n.enqueue(ze(M)),M&&u?.requestId===M&&(u=void 0))},C=async()=>{if(i)return i;s??=(async()=>{let M=await(this.deps.createServer??kp)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(x||e.abortController?.signal.aborted)throw await M.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=M,i=new yi(M.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(M){throw s=void 0,M}},q=async(M,I)=>{!i||!a||await i.request("POST",`/permission/${encodeURIComponent(M)}/reply`,{reply:I})},j=async(M,I)=>{!i||!a||await i.request("POST",`/question/${encodeURIComponent(M)}/reply`,{answers:[[I]]})},N=async M=>{let I=vp(M),_=wp(I.properties);if(!(_&&_!==a)){if((I.type==="session.next.text.delta"||I.type==="message.part.delta")&&I.properties.field!=="reasoning"&&typeof I.properties.delta=="string"){n.enqueue(nt(I.properties.delta));return}if(I.type==="session.next.tool.called"||I.type==="message.part.updated"){let W=oe(I.properties.part)?I.properties.part:void 0;if(I.type==="message.part.updated"&&W?.type!=="tool"){n.enqueue({type:"activity"});return}let te=typeof I.properties.tool=="string"?I.properties.tool:typeof W?.tool=="string"?W.tool:"tool";n.enqueue(Vn(te,I.properties.input));return}if(I.type==="session.next.step.failed"||I.type==="session.error"){let W=oe(I.properties.error)&&typeof I.properties.error.message=="string"?I.properties.error.message:`${I.type} failed`;S&&!b&&(y?.abort(),ne(!1,"failed",W));return}if(I.type==="permission.asked"){if(d==="bypassPermissions"){let te=typeof I.properties.id=="string"?I.properties.id:void 0;te&&(await q(te,"once").catch(()=>{}),T(te));return}let W=Pp(I.properties);u={requestId:W.requestId,kind:"approval",options:W.options,actions:W.actions??[],state:W},n.enqueue(Me(W));return}if(I.type==="permission.replied"){let W=typeof I.properties.requestID=="string"?I.properties.requestID:void 0;T(W);return}if(I.type==="question.asked"){let W=bp(I.properties);u={requestId:W.requestId,kind:"question",options:W.options,actions:[],state:W},n.enqueue(Me(W));return}if(I.type==="question.replied"||I.type==="question.rejected"){let W=typeof I.properties.requestID=="string"?I.properties.requestID:void 0;T(W);return}(I.type?.startsWith("session.next.")||I.type?.startsWith("message.")||I.type==="session.status"||I.type==="session.idle")&&(gp(I)&&(R=!0),n.enqueue({type:"activity"}))}},V=()=>{k||!i||(k=!0,i.streamEvents(N,m.signal).catch(M=>{!m.signal.aborted&&S&&!b&&(y?.abort(),ne(!1,"failed",Tt(M)))}).finally(()=>{k=!1}))},se=async(M,I)=>await M.request("GET",`/session/${encodeURIComponent(I)}/message`),Ae=async(M,I,_,W,te)=>{await M.request("POST",`/session/${encodeURIComponent(I)}/prompt_async`,mp(_,e.model,W),{signal:te})},gt=async(M,I,_,W)=>{let te=Date.now(),Ce=!1,he=_,Ue,ht=0,Ve,Ls=this.deps.turnTimeoutMs??tp;for(;;){if(W.aborted)throw new Error("wait aborted");let Ju=await se(M,I).catch(()=>{}),Ge=ki(Ju),Bs=Ge.count>_&&!!Ge.result;Bs&&Ge.count===he&&Ge.result===Ue?ht+=1:(ht=Bs?1:0,he=Ge.count,Ue=Ge.result);let Zo=!1;try{let Yt=await M.request("GET","/session/status",void 0,{signal:W,timeoutMs:Math.min(this.deps.requestTimeoutMs??Si,1e4)});Zo=fp(Yt,I),Ve=void 0,Zo||(Ce=!0)}catch(Yt){if(W.aborted)throw new Error("wait aborted");Ve=Tt(Yt)}if(Zo&&(Ce||Ge.count>_)||R&&Ge.count>_||ht>=2&&Ve)return;if(Date.now()-te>Ls){let Yt=Ve?` Last status error: ${Ve}`:"";throw new Error(`Timed out waiting for OpenCode session ${I} to become idle after ${Ls}ms.${Yt}`)}await Ra(250)}},Qt=async()=>{let M=await C();if(a){if(e.forkSession&&!p){let W=await M.request("POST",`/session/${encodeURIComponent(a)}/fork`,{});if(!W.id)throw new Error("OpenCode fork did not return a session id.");a=W.id,p=!0,c=!0}else c||(await se(M,a),c=!0);return $(),V(),a}let I=lp(e.model),_=await M.request("POST","/session",{...I?{model:I}:{},metadata:{client:"openclaw-code-agent"},permission:va(d)});if(!_.id)throw new Error("OpenCode did not return a session id.");return a=_.id,c=!0,$(),V(),a},Jt=async(M,I,_=M?"completed":"failed")=>{let W=I;if(M&&i&&a){let te=await se(i,a).catch(()=>{});W=W??Ip(te)}ne(M,_,W)},zu=async M=>{S=!0,b=!1,A=!1,R=!1;try{let I=await C();if(x)return;let _=await Qt();if(x)return;n.enqueue(bt()),l+=1;let W=f?void 0:e.systemPrompt,te=await se(I,_).catch(()=>{}),Ce=ki(te).count,he=new AbortController;y=he,await Ae(I,_,M,W,he.signal),f=!0,await gt(I,_,Ce,he.signal),y=void 0,b=!0,await Jt(!0)}catch(I){y=void 0,await Jt(!1,Tt(I))}finally{S=!1,b=!1}},Yo=async(M,I={})=>{let _=u;if(!_||_.kind!=="question"||I.requestId&&I.requestId!==_.requestId)return!1;let W=M.trim();if(!W)return!1;let te=_.state?.questions??[];if(te.length>0){let Ce=_.state?.activeQuestionIndex??0,he=te[Ce];if(!he||I.questionId&&I.questionId!==he.id)return!1;_.answers={..._.answers,[he.id]:{answers:[W]}};let Ue=Ce+1;return Ue<te.length?(_.state=Rp(_.state,Ue,_.answers),_.options=_.state.options,n.enqueue(Me(_.state)),!0):(await j(_.requestId,Ap(te,_.answers)),T(_.requestId),!0)}return await j(_.requestId,W),T(_.requestId),!0},Qu=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{for await(let M of Qu){if(x)break;let I=ap(M).trim();if(I){if(u?.kind==="question"){await Yo(I);continue}if(await zu(I),x)break}}}catch(M){x||(S||(A=!1),ne(!1,"failed",Tt(M)))}finally{m.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(M){a&&await(await C()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:va(M)}),d=M,n.enqueue(Rt(M))},async submitPendingInputOption(M,I={}){let _=u;if(!_||I.requestId&&I.requestId!==_.requestId)return!1;if(_.kind==="approval"){let ht=_.actions[M],Ve=ht?.kind==="approval"?ht.responseDecision:void 0;return Ve?(await q(_.requestId,Ve),T(_.requestId),!0):!1}let W=_.state?.questions??[],te=_.state?.activeQuestionIndex??0,Ce=W[te];if(I.questionId&&I.questionId!==Ce?.id)return!1;let he=Ce?.options[M],Ue=he?.value??he?.label??_.options[M];return Ue?await Yo(Ue,I):!1},async submitPendingInputText(M){return await Yo(M)},async interrupt(){if(x=!0,m.abort(),y?.abort(),S||(A=!1),ne(!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 wi(t){vi.set(t.name,t)}function un(t){let e=vi.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...vi.keys()].join(", ")}`);return e}function Ia(){return un(de())}var vi,Pi=H(()=>{Js();Sa();Aa();ae();vi=new Map;wi(new Hn);wi(new tr);wi(new rr)});function E(t){return t.backendRef?.conversationId??t.harnessSessionId}function U(t){return t.id??t.sessionId??t.name??E(t)??t.harnessSessionId}function xp(t){return t.harnessSessionId}function fe(t){let e=[U(t),E(t),xp(t)].filter(n=>!!n);return[...new Set(e)]}function bi(t){return t.harnessName??t.persistedHarness??de()}function cn(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return un(bi(t)).capabilities.worktrees}catch{return"plugin-managed"}}function Ri(t){return t==="native-execution"}function or(t){return t==="native-restore"}function Tp(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function ue(t){let e=cn(t);return(Ri(e)||or(e))&&Tp(t)}var X=H(()=>{ae();Pi()});import{execFileSync as ie}from"child_process";import*as Sr from"fs";import{tmpdir as om}from"os";import{dirname as Qa,join as im}from"path";function sm(t){try{return ie("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function vr(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(D.worktreeDir)return D.worktreeDir;if(t){let e=sm(t);if(e)return im(e,".worktrees")}return om()}function Ja(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100).replace(/[-.]+$/,"")||"session"}function wr(t){try{let e=ie("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")?Qa(e):void 0}catch{return}}function am(){if(yr!==void 0)return yr;try{return ie("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),yr=!0,!0}catch{return yr=!1,!1}}function Te(){if(kr!==void 0)return kr;try{return ie("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),kr=!0,!0}catch{return kr=!1,!1}}function Ci(t){if(!am())return!1;try{return ie("git",["rev-parse","--git-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Ya(t){try{let e=dm(t);if(!e)return`${vr(t)}`,!0;let n=Sr.statfsSync(e),r=n.bavail*n.bsize;return um(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function hn(t,e){try{return ie("git",["-C",t,"rev-parse","--verify",e],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function lm(t){let e=t;for(;;){if(Sr.existsSync(e))return e;let n=Qa(e);if(n===e)return;e=n}}function dm(t){return lm(vr(t))}function um(t){return t>=104857600}function _e(t){let e=process.env.OPENCLAW_WORKTREE_BASE_BRANCH?.trim();if(e)return e;try{let r=ie("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 ie("git",["-C",t,"rev-parse","--verify","main"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"main"}catch{}try{return ie("git",["-C",t,"rev-parse","--verify","master"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"master"}catch{return"main"}}function Et(t){try{let n=ie("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 yn(t,e,n){try{let r=ie("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10);return Number.isFinite(o)?o:void 0}catch{return}}function Za(t,e,n){try{let r=ie("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 Dt(t,e,n){try{return ie("git",["-C",t,"merge-base","--is-ancestor",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Pr(t,e,n){try{let r=ie("git",["-C",t,"merge-tree","--write-tree",n,e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),o=ie("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 ye(t,e){try{return ie("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 Xa(t,e){if(e)return e;let n;try{n=ie("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}try{let r=ie("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 yr,kr,Ot=H(()=>{ae()});import{execFileSync as Wt}from"child_process";import{randomBytes as cm}from"crypto";import{appendFileSync as pm,existsSync as nl,mkdirSync as el,readFileSync as mm,rmSync as Mi}from"fs";import{relative as fm,sep as tl}from"path";function gm(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function hm(t){try{return Wt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function ym(t){return t===0?"":`-${t}-${cm(8).toString("hex")}`}function km(t,e){let n=hm(t);if(!n)return;let r=fm(n,e);if(!r||r.startsWith("..")||r.includes(`..${tl}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(tl).join("/").replace(/\/$/,"")}/`;try{let s=nl(o)?mm(o,"utf-8"):"";s.split(/\r?\n/).map(l=>l.trim()).some(l=>l===i||l===`/${i}`)||pm(o,`${s.endsWith(`
12
+ `)}function Mp(t){return vi(t).result}function vi(t){let e=Array.isArray(t)?t:oe(t)&&Array.isArray(t.messages)?t.messages:oe(t)&&Array.isArray(t.items)?t.items:[],n=[];for(let r of e){let o=oe(r)&&oe(r.info)?r.info:r;if(!oe(o)||(typeof o.role=="string"?o.role:o.type)!=="assistant")continue;let s=Array.isArray(o.content)?o.content:[],a=oe(r)&&Array.isArray(r.parts)?r.parts:[];for(let d of[...s,...a])oe(d)&&d.type==="text"&&typeof d.text=="string"&&n.push(d.text)}return{count:n.length,result:n.at(-1)}}var rp,op,wi,ip,sp,yi,ba,Si,ir,xa=H(()=>{dn();zn();rp="OPENCLAW_OPENCODE_COMMAND",op=15e3,wi=6e4,ip=15*6e4,sp=["edit","bash","task","todowrite","external_directory"];yi=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};ba=Promise.resolve();Si=class{constructor(e,n,r=wi){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 or(this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:{...hi(),...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 y=await or(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}}).catch(()=>"");throw new yi(e,n,p.status,ki(y))}if(p.status===204)return;let f=await or(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!f)return;let m=fp(p);if(!m.includes("application/json")&&!m.includes("+json"))throw new Error(hp(e,n,m,f));try{return JSON.parse(f)}catch(y){let k=ki(f);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${_t(y)}${k?`: ${k}`:""}`)}}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:hi(),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(`
13
+ `).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)}};ir=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 ze,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,m=new AbortController,y,k=!1,S=!1,b=!1,A=!1,x=!1,R=!1,h,w=new Set,N=M=>A?!1:(A=!0,n.enqueue(We(M)),!0),Q=(M,I,_)=>N({success:M,outcome:I,duration_ms:0,total_cost_usd:0,num_turns:d,result:_,session_id:a??""}),D=()=>{a&&h!==a&&(h=a,n.enqueue(At({kind:"opencode-server",conversationId:a})))},C=M=>{M&&w.has(M)||(M&&w.add(M),n.enqueue(Qe(M)),M&&u?.requestId===M&&(u=void 0))},T=async()=>{if(i)return i;s??=(async()=>{let M=await(this.deps.createServer??Pp)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(x||e.abortController?.signal.aborted)throw await M.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=M,i=new Si(M.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(M){throw s=void 0,M}},F=async(M,I)=>{!i||!a||await i.request("POST",`/permission/${encodeURIComponent(M)}/reply`,{reply:I})},q=async(M,I)=>{!i||!a||await i.request("POST",`/question/${encodeURIComponent(M)}/reply`,{answers:[[I]]})},L=async M=>{let I=Rp(M),_=Ap(I.properties);if(!(_&&_!==a)){if((I.type==="session.next.text.delta"||I.type==="message.part.delta")&&I.properties.field!=="reasoning"&&typeof I.properties.delta=="string"){n.enqueue(it(I.properties.delta));return}if(I.type==="session.next.tool.called"||I.type==="message.part.updated"){let W=oe(I.properties.part)?I.properties.part:void 0;if(I.type==="message.part.updated"&&W?.type!=="tool"){n.enqueue({type:"activity"});return}let ne=typeof I.properties.tool=="string"?I.properties.tool:typeof W?.tool=="string"?W.tool:"tool";n.enqueue(jn(ne,I.properties.input));return}if(I.type==="session.next.step.failed"||I.type==="session.error"){let W=oe(I.properties.error)&&typeof I.properties.error.message=="string"?I.properties.error.message:`${I.type} failed`;S&&!b&&(y?.abort(),Q(!1,"failed",W));return}if(I.type==="permission.asked"){if(l==="bypassPermissions"){let ne=typeof I.properties.id=="string"?I.properties.id:void 0;ne&&(await F(ne,"once").catch(()=>{}),C(ne));return}let W=Ip(I.properties);u={requestId:W.requestId,kind:"approval",options:W.options,actions:W.actions??[],state:W},n.enqueue(_e(W));return}if(I.type==="permission.replied"){let W=typeof I.properties.requestID=="string"?I.properties.requestID:void 0;C(W);return}if(I.type==="question.asked"){let W=xp(I.properties);u={requestId:W.requestId,kind:"question",options:W.options,actions:[],state:W},n.enqueue(_e(W));return}if(I.type==="question.replied"||I.type==="question.rejected"){let W=typeof I.properties.requestID=="string"?I.properties.requestID:void 0;C(W);return}(I.type?.startsWith("session.next.")||I.type?.startsWith("message.")||I.type==="session.status"||I.type==="session.idle")&&(Sp(I)&&(R=!0),n.enqueue({type:"activity"}))}},G=()=>{k||!i||(k=!0,i.streamEvents(L,m.signal).catch(M=>{!m.signal.aborted&&S&&!b&&(y?.abort(),Q(!1,"failed",_t(M)))}).finally(()=>{k=!1}))},se=async(M,I)=>await M.request("GET",`/session/${encodeURIComponent(I)}/message`),Ie=async(M,I,_,W,ne)=>{await M.request("POST",`/session/${encodeURIComponent(I)}/prompt_async`,yp(_,e.model,W),{signal:ne})},kt=async(M,I,_,W)=>{let ne=Date.now(),Me=!1,he=_,Ve,St=0,Ge,Fs=this.deps.turnTimeoutMs??ip;for(;;){if(W.aborted)throw new Error("wait aborted");let ec=await se(M,I).catch(()=>{}),je=vi(ec),qs=je.count>_&&!!je.result;qs&&je.count===he&&je.result===Ve?St+=1:(St=qs?1:0,he=je.count,Ve=je.result);let ei=!1;try{let en=await M.request("GET","/session/status",void 0,{signal:W,timeoutMs:Math.min(this.deps.requestTimeoutMs??wi,1e4)});ei=kp(en,I),Ge=void 0,ei||(Me=!0)}catch(en){if(W.aborted)throw new Error("wait aborted");Ge=_t(en)}if(ei&&(Me||je.count>_)||R&&je.count>_||St>=2&&Ge)return;if(Date.now()-ne>Fs){let en=Ge?` Last status error: ${Ge}`:"";throw new Error(`Timed out waiting for OpenCode session ${I} to become idle after ${Fs}ms.${en}`)}await Ia(250)}},Zt=async()=>{let M=await T();if(a){if(e.forkSession&&!p){let W=await M.request("POST",`/session/${encodeURIComponent(a)}/fork`,{});if(!W.id)throw new Error("OpenCode fork did not return a session id.");a=W.id,p=!0,c=!0}else c||(await se(M,a),c=!0);return D(),G(),a}let I=pp(e.model),_=await M.request("POST","/session",{...I?{model:I}:{},metadata:{client:"openclaw-code-agent"},permission:Pa(l)});if(!_.id)throw new Error("OpenCode did not return a session id.");return a=_.id,c=!0,D(),G(),a},Xt=async(M,I,_=M?"completed":"failed")=>{let W=I;if(M&&i&&a){let ne=await se(i,a).catch(()=>{});W=W??Mp(ne)}Q(M,_,W)},Zu=async M=>{S=!0,b=!1,A=!1,R=!1;try{let I=await T();if(x)return;let _=await Zt();if(x)return;n.enqueue(It()),d+=1;let W=f?void 0:e.systemPrompt,ne=await se(I,_).catch(()=>{}),Me=vi(ne).count,he=new AbortController;y=he,await Ie(I,_,M,W,he.signal),f=!0,await kt(I,_,Me,he.signal),y=void 0,b=!0,await Xt(!0)}catch(I){y=void 0,await Xt(!1,_t(I))}finally{S=!1,b=!1}},Xo=async(M,I={})=>{let _=u;if(!_||_.kind!=="question"||I.requestId&&I.requestId!==_.requestId)return!1;let W=M.trim();if(!W)return!1;let ne=_.state?.questions??[];if(ne.length>0){let Me=_.state?.activeQuestionIndex??0,he=ne[Me];if(!he||I.questionId&&I.questionId!==he.id)return!1;_.answers={..._.answers,[he.id]:{answers:[W]}};let Ve=Me+1;return Ve<ne.length?(_.state=Tp(_.state,Ve,_.answers),_.options=_.state.options,n.enqueue(_e(_.state)),!0):(await q(_.requestId,Cp(ne,_.answers)),C(_.requestId),!0)}return await q(_.requestId,W),C(_.requestId),!0},Xu=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{for await(let M of Xu){if(x)break;let I=cp(M).trim();if(I){if(u?.kind==="question"){await Xo(I);continue}if(await Zu(I),x)break}}}catch(M){x||(S||(A=!1),Q(!1,"failed",_t(M)))}finally{m.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(M){a&&await(await T()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:Pa(M)}),l=M,n.enqueue(xt(M))},async submitPendingInputOption(M,I={}){let _=u;if(!_||I.requestId&&I.requestId!==_.requestId)return!1;if(_.kind==="approval"){let St=_.actions[M],Ge=St?.kind==="approval"?St.responseDecision:void 0;return Ge?(await F(_.requestId,Ge),C(_.requestId),!0):!1}let W=_.state?.questions??[],ne=_.state?.activeQuestionIndex??0,Me=W[ne];if(I.questionId&&I.questionId!==Me?.id)return!1;let he=Me?.options[M],Ve=he?.value??he?.label??_.options[M];return Ve?await Xo(Ve,I):!1},async submitPendingInputText(M){return await Xo(M)},async interrupt(){if(x=!0,m.abort(),y?.abort(),S||(A=!1),Q(!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 bi(t){Pi.set(t.name,t)}function mn(t){let e=Pi.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...Pi.keys()].join(", ")}`);return e}function Ta(){return mn(le())}var Pi,Ri=H(()=>{Zs();wa();xa();ae();Pi=new Map;bi(new Qn);bi(new rr);bi(new ir)});function $(t){return t.backendRef?.conversationId??t.harnessSessionId}function V(t){return t.id??t.sessionId??t.name??$(t)??t.harnessSessionId}function _p(t){return t.harnessSessionId}function fe(t){let e=[V(t),$(t),_p(t)].filter(n=>!!n);return[...new Set(e)]}function Ai(t){return t.harnessName??t.persistedHarness??le()}function fn(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return mn(Ai(t)).capabilities.worktrees}catch{return"plugin-managed"}}function Ii(t){return t==="native-execution"}function sr(t){return t==="native-restore"}function $p(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function ue(t){let e=fn(t);return(Ii(e)||sr(e))&&$p(t)}var ee=H(()=>{ae();Ri()});import{execFileSync as ie}from"child_process";import*as wr from"fs";import{tmpdir as dm}from"os";import{dirname as Ya,join as lm}from"path";function um(t){try{return ie("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Pr(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(E.worktreeDir)return E.worktreeDir;if(t){let e=um(t);if(e)return lm(e,".worktrees")}return dm()}function Za(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100).replace(/[-.]+$/,"")||"session"}function br(t){try{let e=ie("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")?Ya(e):void 0}catch{return}}function cm(){if(Sr!==void 0)return Sr;try{return ie("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Sr=!0,!0}catch{return Sr=!1,!1}}function we(){if(vr!==void 0)return vr;try{return ie("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),vr=!0,!0}catch{return vr=!1,!1}}function _i(t){if(!cm())return!1;try{return ie("git",["rev-parse","--git-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Xa(t){try{let e=mm(t);if(!e)return`${Pr(t)}`,!0;let n=wr.statfsSync(e),r=n.bavail*n.bsize;return fm(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function Sn(t,e){try{return ie("git",["-C",t,"rev-parse","--verify",e],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function pm(t){let e=t;for(;;){if(wr.existsSync(e))return e;let n=Ya(e);if(n===e)return;e=n}}function mm(t){return pm(Pr(t))}function fm(t){return t>=104857600}function $e(t){let e=process.env.OPENCLAW_WORKTREE_BASE_BRANCH?.trim();if(e)return e;try{let r=ie("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 ie("git",["-C",t,"rev-parse","--verify","main"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"main"}catch{}try{return ie("git",["-C",t,"rev-parse","--verify","master"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"master"}catch{return"main"}}function Ze(t){try{let n=ie("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 vn(t,e,n){try{let r=ie("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10);return Number.isFinite(o)?o:void 0}catch{return}}function ed(t,e,n){try{let r=ie("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 dt(t,e,n){try{return ie("git",["-C",t,"merge-base","--is-ancestor",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Rr(t,e,n){try{let r=ie("git",["-C",t,"merge-tree","--write-tree",n,e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),o=ie("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 ye(t,e){try{return ie("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 td(t,e){if(e)return e;let n;try{n=ie("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}try{let r=ie("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 Sr,vr,Wt=H(()=>{ae()});import{execFileSync as Nt}from"child_process";import{randomBytes as gm}from"crypto";import{appendFileSync as hm,existsSync as od,mkdirSync as nd,readFileSync as ym,rmSync as $i}from"fs";import{relative as km,sep as rd}from"path";function Sm(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function vm(t){try{return Nt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function wm(t){return t===0?"":`-${t}-${gm(8).toString("hex")}`}function Pm(t,e){let n=vm(t);if(!n)return;let r=km(n,e);if(!r||r.startsWith("..")||r.includes(`..${rd}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(rd).join("/").replace(/\/$/,"")}/`;try{let s=od(o)?ym(o,"utf-8"):"";s.split(/\r?\n/).map(d=>d.trim()).some(d=>d===i||d===`/${i}`)||hm(o,`${s.endsWith(`
14
14
  `)||s.length===0?"":`
15
15
  `}${i}
16
- `,"utf-8")}catch(s){`${i}${o}${s instanceof Error?s.message:String(s)}`}}function _i(t,e,n={}){let r=Ja(e),o=vr(t);km(t,o),el(o,{recursive:!0});let i=n.allowExistingBranch===!0,s,a,l=10,d=!1;for(let c=0;c<l;c++){let p=ym(c),f=`${o}/openclaw-worktree-${r}${p}`,m=`agent/${r}${p}`;if(!i&&hn(t,m))continue;let y=!1;do{y=!1;try{el(f,{recursive:!1}),s=f,a=m;break}catch(k){if(gm(k,"EEXIST")){if(i&&c===0&&!d)try{Mi(f,{recursive:!0,force:!0}),d=!0,y=!0}catch(S){throw new Error(`Failed to recreate existing worktree branch ${m}: could not clear blocked path ${f}: ${S instanceof Error?S.message:String(S)}`)}else if(i&&c===0)throw new Error(`Failed to recreate existing worktree branch ${m}: path ${f} remains blocked after one cleanup attempt`);continue}throw k}}while(y);if(s&&a)break}if(!s||!a)throw new Error(`Failed to create unique worktree directory and branch after ${l} attempts`);let u=hn(t,a);try{u?Wt("git",["-C",t,"worktree","add",s,a],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):Wt("git",["-C",t,"worktree","add","-b",a,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{Mi(s,{recursive:!0,force:!0})}catch{}throw c}return s}function st(t){if(!nl(t))return[];try{let e=Wt("git",["-C",t,"status","--porcelain","--untracked-files=all"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e?e.split(`
17
- `).map(n=>n.trim()).filter(Boolean):[]}catch{return[]}}function at(t){return st(t).length>0}function pe(t,e,n={}){let r=n.destructive===!0,o=st(e);if(o.length>0&&!r)return`${e}${o[0]}`,!1;try{return Wt("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 Mi(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 br(t){try{Wt("git",["-C",t,"worktree","prune"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(e){let n=e instanceof Error?e.message.split(/\r?\n/,1)[0]:String(e);`${t}${n}`}}var $i=H(()=>{Ot()});import{execFileSync as Q}from"child_process";import{existsSync as Sm}from"fs";function Nt(t){return(t.warnings??[]).filter(e=>!(t.stashPopConflict&&e.startsWith("Failed to pop auto-stash after merge"))).map(e=>`Recovery warning: ${e}`)}function $e(t,e){let n=Nt(e);return n.length===0?t:`${t}
16
+ `,"utf-8")}catch(s){`${i}${o}${s instanceof Error?s.message:String(s)}`}}function Ei(t,e,n={}){let r=Za(e),o=Pr(t);Pm(t,o),nd(o,{recursive:!0});let i=n.allowExistingBranch===!0,s,a,d=10,l=!1;for(let c=0;c<d;c++){let p=wm(c),f=`${o}/openclaw-worktree-${r}${p}`,m=`agent/${r}${p}`;if(!i&&Sn(t,m))continue;let y=!1;do{y=!1;try{nd(f,{recursive:!1}),s=f,a=m;break}catch(k){if(Sm(k,"EEXIST")){if(i&&c===0&&!l)try{$i(f,{recursive:!0,force:!0}),l=!0,y=!0}catch(S){throw new Error(`Failed to recreate existing worktree branch ${m}: could not clear blocked path ${f}: ${S instanceof Error?S.message:String(S)}`)}else if(i&&c===0)throw new Error(`Failed to recreate existing worktree branch ${m}: path ${f} remains blocked after one cleanup attempt`);continue}throw k}}while(y);if(s&&a)break}if(!s||!a)throw new Error(`Failed to create unique worktree directory and branch after ${d} attempts`);let u=Sn(t,a);try{u?Nt("git",["-C",t,"worktree","add",s,a],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):Nt("git",["-C",t,"worktree","add","-b",a,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{$i(s,{recursive:!0,force:!0})}catch{}throw c}return s}function lt(t){if(!od(t))return[];try{let e=Nt("git",["-C",t,"status","--porcelain","--untracked-files=all"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e?e.split(`
17
+ `).map(n=>n.trim()).filter(Boolean):[]}catch{return[]}}function ut(t){return lt(t).length>0}function pe(t,e,n={}){let r=n.destructive===!0,o=lt(e);if(o.length>0&&!r)return`${e}${o[0]}`,!1;try{return Nt("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 $i(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 Ar(t){try{Nt("git",["-C",t,"worktree","prune"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(e){let n=e instanceof Error?e.message.split(/\r?\n/,1)[0]:String(e);`${t}${n}`}}var Di=H(()=>{Wt()});import{execFileSync as J}from"child_process";import{existsSync as bm}from"fs";function Lt(t){return(t.warnings??[]).filter(e=>!(t.stashPopConflict&&e.startsWith("Failed to pop auto-stash after merge"))).map(e=>`Recovery warning: ${e}`)}function Ee(t,e){let n=Lt(e);return n.length===0?t:`${t}
18
18
  ${n.map(r=>`⚠️ ${r}`).join(`
19
- `)}`}function Rr(t){return t instanceof Error?t.message:String(t)}function Le(t,e,n){try{let r=Q("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10),s=Q("git",["-C",t,"diff","--shortstat",`${n}...${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),a=0,l=0,d=0,u=s.match(/(\d+)\s+files?\s+changed/);u&&(a=parseInt(u[1],10));let c=s.match(/(\d+)\s+insertions?\(/);c&&(l=parseInt(c[1],10));let p=s.match(/(\d+)\s+deletions?\(/);p&&(d=parseInt(p[1],10));let m=Q("git",["-C",t,"diff","--name-only","--diff-filter=ACMR",`${n}...${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
20
- `).map(S=>S.trim()).filter(Boolean),k=Q("git",["-C",t,"log",`${n}..${e}`,"--format=%h|%s|%an","-n","5"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
21
- `).filter(Boolean).map(S=>{let[b,A,x]=S.split("|");return{hash:b||"",message:A||"",author:x||""}});return{commits:o,filesChanged:a,insertions:l,deletions:d,changedFiles:m,commitMessages:k}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function Ar(t,e,n="origin"){try{return Q("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 rl(t){try{return Q("git",["-C",t,"status","--porcelain"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).split(`
22
- `).some(n=>n.length>0&&!n.startsWith("??")&&!n.startsWith("!!"))}catch{return!1}}function Ir(t,e,n,r="merge",o){let i=!1,s,a=[],l=c=>a.length>0?{...c,warnings:[...a]}:c,d=(c,p)=>{a.push(`${c}: ${Rr(p)}`)},u=c=>{if(i)try{Q("git",["-C",c,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(p){d("Failed to pop auto-stash during recovery",p)}};try{if(r==="squash"){if(Q("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),rl(t)){let y;try{y=Q("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(k){return l({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Rr(k)}. Commit or stash changes manually, then retry.`})}if(!y.includes("No local changes to save")){i=!0;try{s=Q("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(k){d("Failed to determine auto-stash ref",k)}}}Q("git",["-C",t,"merge","--squash",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Q("git",["-C",t,"commit","-m",`Squash merge ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let m=!1;if(i)try{Q("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(y){m=!0,d("Failed to pop auto-stash after merge",y)}return l({success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:m||void 0})}let c=o&&Sm(o),p=c?o:t;if(c||Q("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),rl(t)){let m;try{m=Q("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(y){try{Q("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(k){d(`Failed to check out ${n} after auto-stash failure`,k)}return l({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Rr(y)}. Commit or stash changes manually, then retry.`})}if(!m.includes("No local changes to save")){i=!0;try{s=Q("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(y){d("Failed to determine auto-stash ref",y)}}}try{Q("git",["-C",p,"rebase",n],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{try{Q("git",["-C",p,"rebase","--abort"],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){d("Failed to abort rebase during recovery",m)}try{Q("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){d(`Failed to check out ${n} during recovery`,m)}return u(t),l({success:!1,rebaseConflict:!0,stashed:i||void 0,stashRef:s,error:[`Rebase of ${e} onto ${n} hit conflicts.`,"To resolve manually:",` cd ${p}`,` 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(`
23
- `)})}Q("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Q("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let f=!1;if(i)try{Q("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){f=!0,d("Failed to pop auto-stash after merge",m)}return l({success:!0,fastForward:!0,stashed:i||void 0,stashRef:s,stashPopConflict:f||void 0})}catch(c){try{Q("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(p){d(`Failed to check out ${n} during recovery`,p)}return u(t),l({success:!1,error:Rr(c),stashed:i||void 0,stashRef:s})}}var ol=H(()=>{});import{execFileSync as kn}from"child_process";function il(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function sl(t,e,n){let r=Be(t,e,n);if(r.exists&&r.state==="open"&&r.url)return{success:!0,prUrl:r.url,warnings:["A PR already exists for this branch; reused the existing open PR."]};if(r.exists&&r.url)return{success:!1,error:`A PR already exists for ${e}, but it is ${r.state}: ${r.url}`}}function al(t){try{return kn("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function vm(t,e,n){if(!n)return e;let r=al(t);return r?`${r}:${e}`:e}function ll(t,e,n,r,o,i,s={}){if(!Te())return{success:!1,error:"GitHub CLI (gh) is not available"};let a;try{return a=["pr","create","--base",n],(s.draft??!0)&&a.push("--draft"),i&&a.push("--repo",i),a.push("--head",vm(t,e,i)),r&&o?a.push("--title",r,"--body",o):a.push("--fill-verbose"),{success:!0,prUrl:kn("gh",a,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}}catch(l){let d=l instanceof Error?l.message:String(l);if(il(d))return sl(t,e,i)??{success:!1,error:d};if((s.draft??!0)&&a&&/draft/i.test(d))try{let u=a.filter(f=>f!=="--draft");return{success:!0,prUrl:kn("gh",u,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),warnings:["Target repo does not support draft PRs; created as regular (non-draft) PR instead."]}}catch(u){let c=u instanceof Error?u.message:String(u);return il(c)?sl(t,e,i)??{success:!1,error:`Draft PR creation failed (${d}); non-draft retry also failed: ${c}`}:{success:!1,error:`Draft PR creation failed (${d}); non-draft retry also failed: ${c}`}}return{success:!1,error:d}}}function Be(t,e,n){if(!Te())return{exists:!1,state:"none"};try{let r=["pr","list","--head",e,"--state","all","--json","url,number,title,state,headRepositoryOwner,headRefName"];n&&r.push("--repo",n);let i=kn("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=n?al(t)?.toLowerCase():void 0,l=a?s.find(c=>c.headRefName===e&&c.headRepositoryOwner?.login?.toLowerCase()===a):s[0];if(!l)return{exists:!1,state:"none"};let d=l.state.toLowerCase();return{exists:!0,state:d==="open"?"open":d==="merged"?"merged":d==="closed"?"closed":"none",url:l.url,number:l.number,title:l.title}}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function dl(t,e,n,r){if(!Te())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),kn("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 lt(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 Ei=H(()=>{Ot()});import{existsSync as Di}from"fs";function ul(){return new Date().toISOString()}function wm(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:ul(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function Pm(t){let e=cl(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&Di(e)?_e(e):void 0)}function cl(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function Je(t,e={}){let n=wm(t),r=ul(),o=new Set,i=cl(t),s=!!(i&&Di(i)),a=!!(t.worktreePath&&Di(t.worktreePath)),l=t.worktreeBranch,d=Pm(t),u=!1,c=!1,p=!1,f=!1,m,y,k="none",S=t.worktreePrUrl,b=t.worktreePrNumber;if(s||o.add("repo_missing"),l||o.add("branch_missing"),!a&&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"),s&&i&&l&&(u=hn(i,l),u||o.add("branch_missing")),a&&t.worktreePath&&(c=at(t.worktreePath),c&&o.add("dirty_worktree_entries")),s&&i&&u&&l&&d){let $=Za(i,l,d);m=$?.ahead,y=$?.behind,p=Dt(i,l,d),p?o.add("topology_merged"):(f=Pr(i,l,d),f&&o.add("merge_noop_content_already_on_base"),!f&&(m??0)>0&&o.add("unique_content"))}else d||o.add("base_branch_missing");if(e.includePrSync&&s&&i&&l){let $=Be(i,l,t.worktreePrTargetRepo??n.targetRepo);k=$.state,S=$.url??S,b=$.number??b}k==="open"&&o.add("pr_open"),k==="merged"&&!p&&!f&&o.add("pr_merged_not_reflected_locally");let A;p?A="merged":f&&(A="released");let x=e.activeSession||c,R=n.state;!x&&A?R=A:!u&&n.state==="pending_decision"&&(R="cleanup_failed");let h=R==="merged"||R==="released",w=e.activeSession||c||!h&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||k==="open"||o.has("pr_merged_not_reflected_locally"),L=!w&&(R==="merged"||R==="released"||n.state==="dismissed"||n.state==="no_change"),ne={checkedAt:r,repoExists:s,branchExists:u,worktreeExists:a,activeSession:e.activeSession===!0,dirtyTracked:c,topologyMerged:p,releaseNoopMerge:f,branchAheadCount:m,baseAheadCount:y,prState:k,prUrl:S,prNumber:b,reasons:[...o]};return{lifecycle:n,evidence:ne,derivedState:R,cleanupSafe:L,preserve:w,reasons:[...o]}}var Sn=H(()=>{Ot();Ei();$i()});var ke=H(()=>{Ot();$i();ol();Ei();Sn()});function Wr(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function Nr(t,e={}){let n=e.updatedAt??new Date().toISOString(),r={pendingWorktreeDecisionSince:e.pendingSince??n,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision",worktreeLifecycle:Wr(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function Ol(t,e,n,r={}){let o=r.updatedAt??new Date().toISOString();return{autoMergeConflictResolutionAttemptCount:n,autoMergeResolverSessionId:e,pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,lifecycle:"terminal",worktreeState:"merge_conflict_resolving",worktreeLifecycle:Wr(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function Bt(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,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:Wr(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function Wl(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:Wr(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 Rn=H(()=>{});function Ft(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?U(n):r?U(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 An(t){return[...t.persistedSession?fe(t.persistedSession):[],...t.activeSession?fe(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function gf(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 Lr(t,e,n={}){let{activeSession:r,persistedSession:o}=gf(t,e),i=Je({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 Br(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=E(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:E(o),harnessSessionId:o.harnessSessionId});return Array.from(r.values())}function Fr(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function ut(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 qr(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 In=H(()=>{X();Sn()});function Ll(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
19
+ `)}`}function Ir(t){return t instanceof Error?t.message:String(t)}function Be(t,e,n){try{let r=J("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10),s=J("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 m=J("git",["-C",t,"diff","--name-only","--diff-filter=ACMR",`${n}...${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
20
+ `).map(S=>S.trim()).filter(Boolean),k=J("git",["-C",t,"log",`${n}..${e}`,"--format=%h|%s|%an","-n","5"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
21
+ `).filter(Boolean).map(S=>{let[b,A,x]=S.split("|");return{hash:b||"",message:A||"",author:x||""}});return{commits:o,filesChanged:a,insertions:d,deletions:l,changedFiles:m,commitMessages:k}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function xr(t,e,n="origin"){try{return J("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 id(t){try{return J("git",["-C",t,"status","--porcelain"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).split(`
22
+ `).some(n=>n.length>0&&!n.startsWith("??")&&!n.startsWith("!!"))}catch{return!1}}function Tr(t,e,n,r="merge",o){let i=!1,s,a=[],d=c=>a.length>0?{...c,warnings:[...a]}:c,l=(c,p)=>{a.push(`${c}: ${Ir(p)}`)},u=c=>{if(i)try{J("git",["-C",c,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(p){l("Failed to pop auto-stash during recovery",p)}};try{if(r==="squash"){if(J("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),id(t)){let y;try{y=J("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(k){return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Ir(k)}. Commit or stash changes manually, then retry.`})}if(!y.includes("No local changes to save")){i=!0;try{s=J("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(k){l("Failed to determine auto-stash ref",k)}}}J("git",["-C",t,"merge","--squash",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),J("git",["-C",t,"commit","-m",`Squash merge ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let m=!1;if(i)try{J("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(y){m=!0,l("Failed to pop auto-stash after merge",y)}return d({success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:m||void 0})}let c=o&&bm(o),p=c?o:t;if(c||J("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),id(t)){let m;try{m=J("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(y){try{J("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(k){l(`Failed to check out ${n} after auto-stash failure`,k)}return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Ir(y)}. Commit or stash changes manually, then retry.`})}if(!m.includes("No local changes to save")){i=!0;try{s=J("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(y){l("Failed to determine auto-stash ref",y)}}}try{J("git",["-C",p,"rebase",n],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{try{J("git",["-C",p,"rebase","--abort"],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){l("Failed to abort rebase during recovery",m)}try{J("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){l(`Failed to check out ${n} during recovery`,m)}return u(t),d({success:!1,rebaseConflict:!0,stashed:i||void 0,stashRef:s,error:[`Rebase of ${e} onto ${n} hit conflicts.`,"To resolve manually:",` cd ${p}`,` 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(`
23
+ `)})}J("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),J("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let f=!1;if(i)try{J("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){f=!0,l("Failed to pop auto-stash after merge",m)}return d({success:!0,fastForward:!0,stashed:i||void 0,stashRef:s,stashPopConflict:f||void 0})}catch(c){try{J("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(p){l(`Failed to check out ${n} during recovery`,p)}return u(t),d({success:!1,error:Ir(c),stashed:i||void 0,stashRef:s})}}var sd=H(()=>{});import{execFileSync as Bt}from"child_process";function ld(t){let e=t.toLowerCase();return e==="open"?"open":e==="merged"?"merged":e==="closed"?"closed":"none"}function ad(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function dd(t,e,n){let r=Fe(t,e,n);if(r.exists&&r.state==="open"&&r.url)return{success:!0,prUrl:r.url,warnings:["A PR already exists for this branch; reused the existing open PR."]};if(r.exists&&r.url)return{success:!1,error:`A PR already exists for ${e}, but it is ${r.state}: ${r.url}`}}function ud(t){try{return Bt("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function Rm(t,e,n){if(!n)return e;let r=ud(t);return r?`${r}:${e}`:e}function cd(t,e,n,r,o,i,s={}){if(!we())return{success:!1,error:"GitHub CLI (gh) is not available"};let a;try{return a=["pr","create","--base",n],(s.draft??!0)&&a.push("--draft"),i&&a.push("--repo",i),a.push("--head",Rm(t,e,i)),r&&o?a.push("--title",r,"--body",o):a.push("--fill-verbose"),{success:!0,prUrl:Bt("gh",a,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}}catch(d){let l=d instanceof Error?d.message:String(d);if(ad(l))return dd(t,e,i)??{success:!1,error:l};if((s.draft??!0)&&a&&/draft/i.test(l))try{let u=a.filter(f=>f!=="--draft");return{success:!0,prUrl:Bt("gh",u,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),warnings:["Target repo does not support draft PRs; created as regular (non-draft) PR instead."]}}catch(u){let c=u instanceof Error?u.message:String(u);return ad(c)?dd(t,e,i)??{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${c}`}:{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${c}`}}return{success:!1,error:l}}}function Fe(t,e,n){if(!we())return{exists:!1,state:"none"};try{let r=["pr","list","--head",e,"--state","all","--json","url,number,title,state,headRepositoryOwner,headRefName,baseRefName"];n&&r.push("--repo",n);let i=Bt("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=n?ud(t)?.toLowerCase():void 0,d=s.find(c=>c.headRefName===e&&(!a||c.headRepositoryOwner?.login?.toLowerCase()===a));if(!d)return{exists:!1,state:"none"};let u={exists:!0,state:ld(d.state),url:d.url,number:d.number,title:d.title};return d.headRefName!==void 0&&(u.headRefName=d.headRefName),d.baseRefName!==void 0&&(u.baseRefName=d.baseRefName),u}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function Ft(t,e,n){if(!we())return{exists:!1,state:"none"};try{let r=["pr","view",e,"--json","url,number,title,state,headRefName,baseRefName"];n&&r.push("--repo",n);let o=Bt("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim()),s={exists:!0,state:ld(i.state),url:i.url,number:i.number,title:i.title};return i.headRefName!==void 0&&(s.headRefName=i.headRefName),i.baseRefName!==void 0&&(s.baseRefName=i.baseRefName),s}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function pd(t,e,n,r){if(!we())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),Bt("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 ct(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 Oi=H(()=>{Wt()});import{existsSync as Wi}from"fs";function md(){return new Date().toISOString()}function Am(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:md(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function Im(t){let e=fd(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&Wi(e)?$e(e):void 0)}function fd(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function Xe(t,e={}){let n=Am(t),r=md(),o=new Set,i=fd(t),s=!!(i&&Wi(i)),a=!!(t.worktreePath&&Wi(t.worktreePath)),d=t.worktreeBranch,l=Im(t),u=!1,c=!1,p=!1,f=!1,m=!1,y,k,S="none",b=t.worktreePrUrl,A=t.worktreePrNumber;if(s||o.add("repo_missing"),d||o.add("branch_missing"),!a&&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"),s&&i&&d&&(u=Sn(i,d),u||o.add("branch_missing")),a&&t.worktreePath&&(c=ut(t.worktreePath),c&&o.add("dirty_worktree_entries")),s&&i&&u&&d&&l){let T=ed(i,d,l);y=T?.ahead,k=T?.behind,p=dt(i,d,l),p?o.add("topology_merged"):(f=Rr(i,d,l),f&&o.add("merge_noop_content_already_on_base"),!f&&(y??0)>0&&o.add("unique_content"));let F=Ze(i);if(e.includePrSync&&t.worktreePrUrl&&F&&F!==d&&F!==l){let q=Ft(i,t.worktreePrUrl,t.worktreePrTargetRepo??n.targetRepo);m=!!((q.state==="open"||q.state==="merged")&&q.headRefName===F&&q.baseRefName===l&&dt(i,d,F)),m&&(o.delete("unique_content"),o.add(`released_by_branch:${F}`))}}else l||o.add("base_branch_missing");if(e.includePrSync&&s&&i&&d){let T=Fe(i,d,t.worktreePrTargetRepo??n.targetRepo);S=T.state,b=T.url??b,A=T.number??A}S==="open"&&o.add("pr_open"),S==="merged"&&!p&&!f&&o.add("pr_merged_not_reflected_locally");let x=e.includePrSync&&n.state==="pr_open"&&S!=="open";x&&o.add("stale_pr_open");let R;p?R="merged":(f||m)&&(R="released");let h=e.activeSession||c,w=n.state;!h&&R?w=R:x?w="pending_decision":!u&&n.state==="pending_decision"&&(w="cleanup_failed");let N=w==="merged"||w==="released",Q=e.activeSession||c||!N&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||S==="open"||o.has("pr_merged_not_reflected_locally"),D=!Q&&(w==="merged"||w==="released"||n.state==="dismissed"||n.state==="no_change"),C={checkedAt:r,repoExists:s,branchExists:u,worktreeExists:a,activeSession:e.activeSession===!0,dirtyTracked:c,topologyMerged:p,releaseNoopMerge:f,representedByTargetPrBranch:m,branchAheadCount:y,baseAheadCount:k,prState:S,prUrl:b,prNumber:A,reasons:[...o]};return{lifecycle:n,evidence:C,derivedState:w,cleanupSafe:D,preserve:Q,reasons:[...o]}}var wn=H(()=>{Wt();Oi();Di()});var ke=H(()=>{Wt();Di();sd();Oi();wn()});function Lr(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function Br(t,e={}){let n=e.updatedAt??new Date().toISOString(),r={pendingWorktreeDecisionSince:e.pendingSince??n,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision",worktreeLifecycle:Lr(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function Ld(t,e,n,r={}){let o=r.updatedAt??new Date().toISOString();return{autoMergeConflictResolutionAttemptCount:n,autoMergeResolverSessionId:e,pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,lifecycle:"terminal",worktreeState:"merge_conflict_resolving",worktreeLifecycle:Lr(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function Kt(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,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:Lr(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function Bd(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:Lr(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 In=H(()=>{});function Ut(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?V(n):r?V(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 xn(t){return[...t.persistedSession?fe(t.persistedSession):[],...t.activeSession?fe(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function Sf(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 Fr(t,e,n={}){let{activeSession:r,persistedSession:o}=Sf(t,e),i=Xe({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 qr(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=$(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:$(o),harnessSessionId:o.harnessSessionId});return Array.from(r.values())}function Kr(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function mt(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 Ur(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"stale_pr_open":return"stale PR-open metadata";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.startsWith("released_by_branch:")?`represented by ${t.slice(19)}`:t.startsWith("represented_by_branch:")?`represented by ${t.slice(22)}`:t.replaceAll("_"," ")}}var Tn=H(()=>{ee();wn()});function qd(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
24
24
  `).split(`
25
25
  `).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?`
26
- `:" ").replace(/[ \t]+/g," ").trim()||void 0}function qt(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function Tn(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 Gr(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 Sf(t){let e=Ll(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=Tn(n).replace(/\s+/g," ").trim();return r?qt(r,180):void 0}function Bl(t){return Tn(t.trim()).replace(/\s+/g," ").trim()}function vf(t,e){return t?.commitMessages.map(n=>Bl(n.message)).filter(Boolean).slice(0,e)??[]}function zi(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function Fl(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function wf(t){let e=Sf(t.prompt),n=t.diffSummary;return{sessionName:t.sessionName,branchName:t.branchName,objective:e,stats:n?{commits:n.commits,filesChanged:n.filesChanged,insertions:n.insertions,deletions:n.deletions}:void 0,changedFiles:n?.changedFiles??[],commitSubjects:vf(n,5),validation:zi(),notes:Fl()}}function Vr(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 ql(t,e){let n=Ll(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 xn(t,e,n){let r=t.toLowerCase();return ql(e,n.objective).some(o=>r.includes(o))}function Nl(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function Qi(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 l=new Set([...o].map(p=>p.match(/\.([A-Za-z0-9]+)$/)?.[1]?.toLowerCase()).filter(p=>!!p)),d=String.raw`[A-Za-z0-9][\w.-]*\.([A-Za-z0-9]+)`,u=t.matchAll(new RegExp(`[\\\`"'](${d})[\\\`"']`,"g"));for(let p of u){let f=p[1],m=p[2]?.toLowerCase();if(m!==void 0&&l.has(m)&&!o.has(f)&&!Nl(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+)?(${d})\b`,"gi"))].some(p=>{let f=p[1],m=p[2]?.toLowerCase();return m!==void 0&&l.has(m)&&!o.has(f)&&!Nl(f)})}function Fe(t){return Tn(t).replace(/\s+/g," ").trim()}function Pf(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||!Vr(r.summary,5,180)||!Vr(r.changes,10,160)||!Vr(r.validation,5,160)||!Vr(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(a=>Gr(a)||xn(a,n,e)))return;let i={title:Fe(r.title),summary:r.summary.map(Fe),changes:r.changes.map(Fe),validation:r.validation.map(Fe),notes:r.notes.map(Fe)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(a=>!a||Gr(a)||xn(a,n,e))&&!s.some(a=>Qi(a,e)))return i}function bf(t,e){let n=qt(Tn(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),r=qt(`OpenClaw agent changes: ${n}`,90),o=["Deterministic fallback metadata generated because no LLM PR metadata provider is configured.",`Session: ${n}.`,...t.objective?[`Objective: ${t.objective}`]:[],...t.stats?[`Scope: ${t.stats.commits} commits, ${t.stats.filesChanged} files changed (+${t.stats.insertions} / -${t.stats.deletions}).`]:["Scope: Diff summary was unavailable when the PR body was generated."]],i=t.changedFiles.length>0?t.changedFiles.slice(0,10).map(f=>`\`${f}\``):["Review the pushed worktree branch for the full set of changes."],s=t.changedFiles.length>10?[`...and ${t.changedFiles.length-10} more changed files.`]:[],a=["Fallback metadata is conservative; review the diff and CI/checks before marking the draft PR ready.",...t.notes],l={title:r,summary:o,changes:[...i,...s],validation:t.validation,notes:a},d=!1,u=!1,c=f=>{let m=Fe(f);if(xn(m,e,t)){d=!0;let y=ql(e,t.objective);for(let k of y){let S=new RegExp(k.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");m=m.replace(S,"[redacted prompt detail]")}m=Fe(m)}return Qi(m,t)&&(u=!0,m="[redacted file reference outside change set]"),m=Fe(m),(xn(m,e,t)||Gr(m))&&(d=!0,m="[redacted prompt detail]"),m};if(l={title:c(l.title)||qt(`OpenClaw agent changes: ${n}`,90),summary:l.summary.map(c).filter(f=>f&&f.length>0),changes:l.changes.map(c).filter(f=>f&&f.length>0),validation:l.validation.map(c).filter(f=>f&&f.length>0),notes:l.notes.map(c).filter(f=>f&&f.length>0)},l.summary.length===0&&(l.summary=["Deterministic fallback metadata generated because no LLM PR metadata provider is configured."]),l.changes.length===0&&(l.changes=["Review the pushed worktree branch for the full set of changes."]),l.validation.length===0&&(l.validation=zi()),l.notes.length===0&&(l.notes=Fl()),d||u){let f="Some content was stripped from fallback metadata due to safety checks (prompt leak guard or references to files outside the diff).";l.notes.some(m=>m.toLowerCase().includes("stripped")||m.toLowerCase().includes("sanitized"))||(l.notes=[...l.notes,f])}let p=[l.title,...l.summary,...l.changes,...l.validation,...l.notes];if(p.some(f=>!f)||p.some(f=>Gr(f)||xn(f,e,t))||p.some(f=>Qi(f,t))){let f=qt(Tn(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);l={title:qt(`OpenClaw agent changes: ${f}`,90),summary:["Deterministic fallback metadata (sanitized for safety)."],changes:t.changedFiles.length>0?t.changedFiles.slice(0,5).map(m=>`\`${m}\``):["See the worktree branch diff for the full set of changes."],validation:zi(),notes:["Fallback metadata was hardened because prompt-leak or unknown-file checks were triggered after initial construction.","Review the actual diff, session output, and CI before merging."]}}if(t.branchName){let f=Fe(t.branchName);l.notes.some(m=>m.toLowerCase().includes(f.toLowerCase()))||(l.notes=[...l.notes,`Branch: ${f}`])}return l}async function jr(t){let e=wf({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:bf(e,t.prompt),evidence:e};try{let n=await t.provider.generatePrMetadata(e),r=Pf(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 Hr(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} ${Bl(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(`
27
- `)}var Ji=H(()=>{});var Kl={};Zu(Kl,{buildPrCompletionWakeOutcomeKey:()=>Zi,buildPrMetadata:()=>jr,buildPrOutcomeDetailLines:()=>Yi,formatPrBody:()=>Hr,makeAgentPrTool:()=>Cn});import{existsSync as Rf}from"fs";function Af(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Yi(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 Zi(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 Cn(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:g.Object({session:g.String({description:"Session name or ID to create/update PR for"}),title:g.Optional(g.String({description:"PR title (default: auto-generated from session name)"})),body:g.Optional(g.String({description:"PR body (default: auto-generated from commit summary)"})),base_branch:g.Optional(g.String({description:"Base branch for the PR (default: detected from repo)"})),force_new:g.Optional(g.Boolean({description:"Force creation of a new PR even if one exists (default: false)"})),target_repo:g.Optional(g.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(!Af(r))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, title?, body?, base_branch?, force_new? }."}],meta:{success:!1,state:"error"}};if(!Te())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:l,sessionName:d,branchName:u}=o;if(!a||!l)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"}};Rf(a)||`${a}${u}${l}`;let c=r.base_branch??_e(l),p=b=>{let A=Wl({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:b.prUrl,prNumber:b.prNumber,baseBranch:c,targetRepo:b.targetRepo,disposition:b.disposition});for(let x of An(o))v.updatePersistedSession(x,A)},f=Xa(l,r.target_repo??s?.worktreePrTargetRepo),m=v.resolveRepoPolicy(l),y=Be(l,u,f),k=y.exists&&y.state==="open";if(m?.policy==="never-pr"&&!k)return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${m.identity?.repoRoot??l}.`}],meta:{success:!1,state:"error"}};if(m&&!m.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${m.identity?.repoRoot??l}. Provider: ${m.provider}.`}],meta:{success:!1,state:"error"}};if(!Ar(l,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let S=Be(l,u,f);if(r.force_new&&S.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${S.state}).
26
+ `:" ").replace(/[ \t]+/g," ").trim()||void 0}function Vt(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function Mn(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 Hr(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 bf(t){let e=qd(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=Mn(n).replace(/\s+/g," ").trim();return r?Vt(r,180):void 0}function Kd(t){return Mn(t.trim()).replace(/\s+/g," ").trim()}function Rf(t,e){return t?.commitMessages.map(n=>Kd(n.message)).filter(Boolean).slice(0,e)??[]}function Ji(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function Ud(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function Af(t){let e=bf(t.prompt),n=t.diffSummary;return{sessionName:t.sessionName,branchName:t.branchName,objective:e,stats:n?{commits:n.commits,filesChanged:n.filesChanged,insertions:n.insertions,deletions:n.deletions}:void 0,changedFiles:n?.changedFiles??[],commitSubjects:Rf(n,5),validation:Ji(),notes:Ud()}}function jr(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 Vd(t,e){let n=qd(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 Cn(t,e,n){let r=t.toLowerCase();return Vd(e,n.objective).some(o=>r.includes(o))}function Fd(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function Yi(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],m=p[2]?.toLowerCase();if(m!==void 0&&d.has(m)&&!o.has(f)&&!Fd(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],m=p[2]?.toLowerCase();return m!==void 0&&d.has(m)&&!o.has(f)&&!Fd(f)})}function qe(t){return Mn(t).replace(/\s+/g," ").trim()}function If(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||!jr(r.summary,5,180)||!jr(r.changes,10,160)||!jr(r.validation,5,160)||!jr(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(a=>Hr(a)||Cn(a,n,e)))return;let i={title:qe(r.title),summary:r.summary.map(qe),changes:r.changes.map(qe),validation:r.validation.map(qe),notes:r.notes.map(qe)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(a=>!a||Hr(a)||Cn(a,n,e))&&!s.some(a=>Yi(a,e)))return i}function xf(t,e){let n=Vt(Mn(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),r=Vt(`OpenClaw agent changes: ${n}`,90),o=["Deterministic fallback metadata generated because no LLM PR metadata provider is configured.",`Session: ${n}.`,...t.objective?[`Objective: ${t.objective}`]:[],...t.stats?[`Scope: ${t.stats.commits} commits, ${t.stats.filesChanged} files changed (+${t.stats.insertions} / -${t.stats.deletions}).`]:["Scope: Diff summary was unavailable when the PR body was generated."]],i=t.changedFiles.length>0?t.changedFiles.slice(0,10).map(f=>`\`${f}\``):["Review the pushed worktree branch for the full set of changes."],s=t.changedFiles.length>10?[`...and ${t.changedFiles.length-10} more changed files.`]:[],a=["Fallback metadata is conservative; review the diff and CI/checks before marking the draft PR ready.",...t.notes],d={title:r,summary:o,changes:[...i,...s],validation:t.validation,notes:a},l=!1,u=!1,c=f=>{let m=qe(f);if(Cn(m,e,t)){l=!0;let y=Vd(e,t.objective);for(let k of y){let S=new RegExp(k.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");m=m.replace(S,"[redacted prompt detail]")}m=qe(m)}return Yi(m,t)&&(u=!0,m="[redacted file reference outside change set]"),m=qe(m),(Cn(m,e,t)||Hr(m))&&(l=!0,m="[redacted prompt detail]"),m};if(d={title:c(d.title)||Vt(`OpenClaw agent changes: ${n}`,90),summary:d.summary.map(c).filter(f=>f&&f.length>0),changes:d.changes.map(c).filter(f=>f&&f.length>0),validation:d.validation.map(c).filter(f=>f&&f.length>0),notes:d.notes.map(c).filter(f=>f&&f.length>0)},d.summary.length===0&&(d.summary=["Deterministic fallback metadata generated because no LLM PR metadata provider is configured."]),d.changes.length===0&&(d.changes=["Review the pushed worktree branch for the full set of changes."]),d.validation.length===0&&(d.validation=Ji()),d.notes.length===0&&(d.notes=Ud()),l||u){let f="Some content was stripped from fallback metadata due to safety checks (prompt leak guard or references to files outside the diff).";d.notes.some(m=>m.toLowerCase().includes("stripped")||m.toLowerCase().includes("sanitized"))||(d.notes=[...d.notes,f])}let p=[d.title,...d.summary,...d.changes,...d.validation,...d.notes];if(p.some(f=>!f)||p.some(f=>Hr(f)||Cn(f,e,t))||p.some(f=>Yi(f,t))){let f=Vt(Mn(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);d={title:Vt(`OpenClaw agent changes: ${f}`,90),summary:["Deterministic fallback metadata (sanitized for safety)."],changes:t.changedFiles.length>0?t.changedFiles.slice(0,5).map(m=>`\`${m}\``):["See the worktree branch diff for the full set of changes."],validation:Ji(),notes:["Fallback metadata was hardened because prompt-leak or unknown-file checks were triggered after initial construction.","Review the actual diff, session output, and CI before merging."]}}if(t.branchName){let f=qe(t.branchName);d.notes.some(m=>m.toLowerCase().includes(f.toLowerCase()))||(d.notes=[...d.notes,`Branch: ${f}`])}return d}async function zr(t){let e=Af({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:xf(e,t.prompt),evidence:e};try{let n=await t.provider.generatePrMetadata(e),r=If(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 Qr(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} ${Kd(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(`
27
+ `)}var Zi=H(()=>{});var Gd={};nc(Gd,{buildPrCompletionWakeOutcomeKey:()=>es,buildPrMetadata:()=>zr,buildPrOutcomeDetailLines:()=>Xi,formatPrBody:()=>Qr,makeAgentPrTool:()=>_n});import{existsSync as Tf}from"fs";function Cf(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Xi(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 es(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 _n(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:g.Object({session:g.String({description:"Session name or ID to create/update PR for"}),title:g.Optional(g.String({description:"PR title (default: auto-generated from session name)"})),body:g.Optional(g.String({description:"PR body (default: auto-generated from commit summary)"})),base_branch:g.Optional(g.String({description:"Base branch for the PR (default: detected from repo)"})),force_new:g.Optional(g.Boolean({description:"Force creation of a new PR even if one exists (default: false)"})),target_repo:g.Optional(g.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(!Cf(r))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, title?, body?, base_branch?, force_new? }."}],meta:{success:!1,state:"error"}};if(!we())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=Ut(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"}};Tf(a)||`${a}${u}${d}`;let c=r.base_branch??$e(d),p=b=>{let A=Bd({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:b.prUrl,prNumber:b.prNumber,baseBranch:c,targetRepo:b.targetRepo,disposition:b.disposition});for(let x of xn(o))v.updatePersistedSession(x,A)},f=td(d,r.target_repo??s?.worktreePrTargetRepo),m=v.resolveRepoPolicy(d),y=Fe(d,u,f),k=y.exists&&y.state==="open";if(m?.policy==="never-pr"&&!k)return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${m.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};if(m&&!m.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${m.identity?.repoRoot??d}. Provider: ${m.provider}.`}],meta:{success:!1,state:"error"}};if(!xr(d,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let S=Fe(d,u,f);if(r.force_new&&S.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${S.state}).
28
28
 
29
29
  Existing PR: ${S.url}
30
30
 
31
- 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(S.exists&&S.state==="open"){let b=Le(l,u,c);if(b&&b.commits>0){let A=b.commitMessages.slice(0,5).map(w=>`• ${w.hash} ${w.message} (${w.author})`).join(`
31
+ 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(S.exists&&S.state==="open"){let b=Be(d,u,c);if(b&&b.commits>0){let A=b.commitMessages.slice(0,5).map(w=>`• ${w.hash} ${w.message} (${w.author})`).join(`
32
32
  `),x=b.commits>5?`
33
33
  ...and ${b.commits-5} more commits`:"",R=["🔄 **New commits pushed**","",`${b.commits} new commits (+${b.insertions} / -${b.deletions})`,"","### Latest commits:",A+x,"","---","🤖 [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)"].join(`
34
- `);if(dl(l,S.number,R,f)){p({prUrl:S.url,prNumber:S.number,targetRepo:f});let w=lt({kind:"pr-updated",branch:u,prUrl:S.url});return v.notifyWorktreeOutcome(o.notificationTarget,w,{completionWakeOutcomeKey:Zi({action:"updated",branchName:u,prUrl:S.url,prNumber:S.number,targetRepo:f,diffSummary:b}),detailLines:Yi({action:"updated",branchName:u,baseBranch:c,prUrl:S.url,prNumber:S.number,targetRepo:f,commits:b.commits,insertions:b.insertions,deletions:b.deletions})}),{content:[{type:"text",text:`${w}
34
+ `);if(pd(d,S.number,R,f)){p({prUrl:S.url,prNumber:S.number,targetRepo:f});let w=ct({kind:"pr-updated",branch:u,prUrl:S.url});return v.notifyWorktreeOutcome(o.notificationTarget,w,{completionWakeOutcomeKey:es({action:"updated",branchName:u,prUrl:S.url,prNumber:S.number,targetRepo:f,diffSummary:b}),detailLines:Xi({action:"updated",branchName:u,baseBranch:c,prUrl:S.url,prNumber:S.number,targetRepo:f,commits:b.commits,insertions:b.insertions,deletions:b.deletions})}),{content:[{type:"text",text:`${w}
35
35
 
36
36
  📝 Added comment detailing ${b.commits} new commits (+${b.insertions} / -${b.deletions})`}],meta:{success:!0,state:"pr_updated"}}}else return{content:[{type:"text",text:`⚠️ Pushed to ${S.url} but failed to add comment.
37
37
 
38
38
  ${b.commits} new commits (+${b.insertions} / -${b.deletions})`}],meta:{success:!0,state:"pr_open"}}}else return p({prUrl:S.url,prNumber:S.number,targetRepo:f}),{content:[{type:"text",text:`ℹ️ PR already exists and is up to date: ${S.url}
39
39
 
40
- No new commits to push.`}],meta:{success:!0,state:"pr_open"}}}else if(S.exists&&S.state==="merged"){let b={...Bt({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{resolutionSource:"agent_pr",clearResolverSessionId:!0}),worktreePrUrl:S.url,worktreePrNumber:S.number,worktreeDisposition:"merged",worktreeDecisionSnoozedUntil:void 0};for(let A of An(o))v.updatePersistedSession(A,b);return{content:[{type:"text",text:`✅ PR was already merged: ${S.url}
40
+ No new commits to push.`}],meta:{success:!0,state:"pr_open"}}}else if(S.exists&&S.state==="merged"){let b={...Kt({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{resolutionSource:"agent_pr",clearResolverSessionId:!0}),worktreePrUrl:S.url,worktreePrNumber:S.number,worktreeDisposition:"merged",worktreeDecisionSnoozedUntil:void 0};for(let A of xn(o))v.updatePersistedSession(A,b);return{content:[{type:"text",text:`✅ PR was already merged: ${S.url}
41
41
 
42
42
  The worktree branch ${u} can be cleaned up with agent_merge(delete_branch=true).`}],meta:{success:!0,state:"merged"}}}else{if(S.exists&&S.state==="closed")return{content:[{type:"text",text:`⚠️ A PR exists but was closed without merging: ${S.url}
43
43
 
@@ -47,229 +47,229 @@ What would you like to do?
47
47
  2. Close and delete the branch with agent_merge(delete_branch=true), then start a new session/worktree
48
48
  3. Manually delete the closed PR on GitHub, then call agent_pr(force_new=true) to create a fresh PR
49
49
 
50
- (This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{if(m?.policy==="never-pr")return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${m.identity?.repoRoot??l}.`}],meta:{success:!1,state:"error"}};let b=!r.title||!r.body?Le(l,u,c):void 0,A;if(!r.title||!r.body){let w=await jr({sessionName:d,branchName:u,prompt:o.prompt,diffSummary:b,provider:e.metadataProvider});if(w.ok===!1)return{content:[{type:"text",text:`❌ ${w.error}`}],meta:{success:!1,state:"error"}};A=w.metadata}let x=r.title??A.title,R=r.body;R||(R=Hr({sessionName:d,metadata:A,diffSummary:b}));let h=ll(l,u,c,x,R,f,{draft:!0});if(h.success&&h.prUrl){let w=Be(l,u,f);p({prUrl:h.prUrl,prNumber:w.number,targetRepo:f,disposition:"pr-opened"});let L=lt({kind:"pr-opened",branch:u,targetRepo:f,prUrl:h.prUrl});return v.notifyWorktreeOutcome(o.notificationTarget,L,{completionWakeOutcomeKey:Zi({action:"opened",branchName:u,prUrl:h.prUrl,prNumber:w.number,targetRepo:f}),detailLines:Yi({action:"opened",branchName:u,baseBranch:c,prUrl:h.prUrl,prNumber:w.number,targetRepo:f})}),{content:[{type:"text",text:h.warnings&&h.warnings.length>0?`${L}
50
+ (This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{if(m?.policy==="never-pr")return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${m.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};let b=!r.title||!r.body?Be(d,u,c):void 0,A;if(!r.title||!r.body){let w=await zr({sessionName:l,branchName:u,prompt:o.prompt,diffSummary:b,provider:e.metadataProvider});if(w.ok===!1)return{content:[{type:"text",text:`❌ ${w.error}`}],meta:{success:!1,state:"error"}};A=w.metadata}let x=r.title??A.title,R=r.body;R||(R=Qr({sessionName:l,metadata:A,diffSummary:b}));let h=cd(d,u,c,x,R,f,{draft:!0});if(h.success&&h.prUrl){let w=Fe(d,u,f);p({prUrl:h.prUrl,prNumber:w.number,targetRepo:f,disposition:"pr-opened"});let N=ct({kind:"pr-opened",branch:u,targetRepo:f,prUrl:h.prUrl});return v.notifyWorktreeOutcome(o.notificationTarget,N,{completionWakeOutcomeKey:es({action:"opened",branchName:u,prUrl:h.prUrl,prNumber:w.number,targetRepo:f}),detailLines:Xi({action:"opened",branchName:u,baseBranch:c,prUrl:h.prUrl,prNumber:w.number,targetRepo:f})}),{content:[{type:"text",text:h.warnings&&h.warnings.length>0?`${N}
51
51
 
52
- ⚠️ ${h.warnings.join("; ")}`:L}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${h.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var zr=H(()=>{re();F();ke();Ji();Rn();In();Ji()});import{readdirSync as Pk,statSync as bk,rmSync as Rk}from"fs";import{execFileSync as Ak}from"child_process";import{join as Hu}from"path";re();F();function tc(t){return t.length>80?`${t.slice(0,80)}...`:t}function nc(t){return t.worktreePath?!t.originalWorkdir||t.originalWorkdir===t.worktreePath?`${t.worktreePath} (worktree)`:`${t.worktreePath} (worktree of ${t.originalWorkdir})`:t.workdir}function rc(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"}`,...t.repoIntegrationPolicy?[` Repo policy: ${t.repoIntegrationPolicy}${t.repoProvider?` (${t.repoProvider})`:""}`]:[],` Resolved workdir: ${nc(t)}`,` Model: ${t.model??"default"}`,` Prompt: "${tc(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(`
53
- `)}function Bn(t,e){return rc({...t,sessionId:e.id,sessionName:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,worktreeStrategy:e.worktreeStrategy??"off",repoIntegrationPolicy:e.repoIntegrationPolicy,repoProvider:e.repoProvider,worktreePath:e.worktreePath,originalWorkdir:e.originalWorkdir})}ae();function vt(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}}X();function ir(t){return"id"in t?t.id:t.sessionId}function pn(t){return t.status==="completed"||t.killReason==="done"}function Cp(t){return!pn(t)||!E(t)?!1:t.backendRef?.kind==="codex-app-server"||t.backendRef?.kind==="opencode-server"}function Mp(t){return(t.killReason==="shutdown"||t.killReason==="startup-timeout")&&!E(t)}function mn(t){if(t.status==="running")return{kind:"direct",reason:"already_running"};let e=ir(t);if(pn(t)&&!Cp(t))return{kind:"unavailable",reason:"completed",stableSessionId:e};let n=E(t);if(n){let r="harnessName"in t?void 0:t,{resumeSessionId:o,clearedPersistedCodexResume:i}=vt({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 Mp(t)?{kind:"relaunch",stableSessionId:e}:{kind:"unavailable",reason:"missing_backend_state",stableSessionId:e}}ae();Zn();import{existsSync as Ma}from"fs";X();function xa(t){return t==null?void 0:String(t).trim()||void 0}function _p(t){return t.trim().replace(/^['"`](.*)['"`]$/s,"$1").trim()}function $p(t){let e=t.split(/\n\s*\n/,1)[0]?.split(`
54
- `).map(n=>n.trim()).filter(Boolean)??[];if(e.length!==0)for(let n of e){let r=n.match(/^(Workdir|Repo):\s*(.+)$/),o=_p(r?.[2]??"");if(o.startsWith("/")&&Ma(o))return o}}function Ta(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&&xa(t.originThreadId)===xa(e.originThreadId)}function Ca(t){return t.slice(0,3).map(e=>` - ${e.name} [${e.ref}] | status=${e.status}${e.lifecycle?` | lifecycle=${e.lifecycle}`:""}`).join(`
55
- `)}function Ep(t,e){let n=[],r=[],o=new Set;for(let i of t.list?.("all")??[]){if(!Ta(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||!Ta(i,e))continue;let s=U(i)??i.harnessSessionId,a=i.sessionId??E(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 sr(t,e,n){let r=t.workdir||$p(t.prompt)||e.workspaceDir||D.defaultWorkdir||process.cwd();if(!Ma(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=t.harness??de(),i=yt(o),s=t.model??i,a=We(o,s),l=t.model!==void 0,d=Fn(o);if(!a&&(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(a&&!It(o,a))return{kind:"error",text:`Error: Model "${s}" is not supported for harness "${o}". Use a bare Codex model id such as "gpt-5.5".`};if(a&&d&&d.length>0&&!Jn(o,a,d))return{kind:"error",text:l?`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 u=Yn(o,a,d),c=qn(e),p=rn(e,c||tt(r)),f=e.sessionKey||void 0,m=js(f)??di(e);if(!t.resume_session_id&&!t.force_new_session){let h=Ep(n,{workdir:r,originSessionKey:f,originChannel:p,originThreadId:m});if(h.resumable.length>0||h.active.length>0){let w=h.resumable.length>0?["Linked resumable session(s) already exist for this thread/workdir:",Ca(h.resumable),"","Resume the latest one with:",` agent_respond(session='${h.resumable[0].ref}', message='<next instruction>')`,"Fork from it with:",` agent_launch(prompt='<new task>', resume_session_id='${h.resumable[0].ref}', fork_session=true)`].join(`
56
- `):"",L=h.active.length>0?[h.resumable.length>0?"Linked active session(s):":"Linked active session(s) already exist for this thread/workdir:",Ca(h.active),"","Send a follow-up instead of launching a duplicate:",` agent_respond(session='${h.active[0].ref}', message='<next instruction>')`].join(`
57
- `):"";return{kind:"blocked",text:["Resume-first protection blocked a fresh launch.","",w,L,["If you intentionally want a brand-new independent session here, call:"," agent_launch(prompt='<new task>', force_new_session=true)"].join(`
52
+ ⚠️ ${h.warnings.join("; ")}`:N}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${h.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var Jr=H(()=>{re();K();ke();Zi();In();Tn();Zi()});import{readdirSync as xk,statSync as Tk,rmSync as Ck}from"fs";import{execFileSync as Mk}from"child_process";import{join as Yu}from"path";re();K();function ic(t){return t.length>80?`${t.slice(0,80)}...`:t}function sc(t){return t.worktreePath?!t.originalWorkdir||t.originalWorkdir===t.worktreePath?`${t.worktreePath} (worktree)`:`${t.worktreePath} (worktree of ${t.originalWorkdir})`:t.workdir}function ac(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"}`,...t.repoIntegrationPolicy?[` Repo policy: ${t.repoIntegrationPolicy}${t.repoProvider?` (${t.repoProvider})`:""}`]:[],` Resolved workdir: ${sc(t)}`,` Model: ${t.model??"default"}`,` Prompt: "${ic(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(`
53
+ `)}function qn(t,e){return ac({...t,sessionId:e.id,sessionName:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,worktreeStrategy:e.worktreeStrategy??"off",repoIntegrationPolicy:e.repoIntegrationPolicy,repoProvider:e.repoProvider,worktreePath:e.worktreePath,originalWorkdir:e.originalWorkdir})}ae();function bt(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}}ee();function ar(t){return"id"in t?t.id:t.sessionId}function gn(t){return t.status==="completed"||t.killReason==="done"}function Ep(t){return!gn(t)||!$(t)?!1:t.backendRef?.kind==="codex-app-server"||t.backendRef?.kind==="opencode-server"}function Dp(t){return(t.killReason==="shutdown"||t.killReason==="startup-timeout")&&!$(t)}function hn(t){if(t.status==="running")return{kind:"direct",reason:"already_running"};let e=ar(t);if(gn(t)&&!Ep(t))return{kind:"unavailable",reason:"completed",stableSessionId:e};let n=$(t);if(n){let r="harnessName"in t?void 0:t,{resumeSessionId:o,clearedPersistedCodexResume:i}=bt({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 Dp(t)?{kind:"relaunch",stableSessionId:e}:{kind:"unavailable",reason:"missing_backend_state",stableSessionId:e}}ae();er();import{existsSync as $a}from"fs";ee();function Ca(t){return t==null?void 0:String(t).trim()||void 0}function Op(t){return t.trim().replace(/^['"`](.*)['"`]$/s,"$1").trim()}function Wp(t){let e=t.split(/\n\s*\n/,1)[0]?.split(`
54
+ `).map(n=>n.trim()).filter(Boolean)??[];if(e.length!==0)for(let n of e){let r=n.match(/^(Workdir|Repo):\s*(.+)$/),o=Op(r?.[2]??"");if(o.startsWith("/")&&$a(o))return o}}function Ma(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&&Ca(t.originThreadId)===Ca(e.originThreadId)}function _a(t){return t.slice(0,3).map(e=>` - ${e.name} [${e.ref}] | status=${e.status}${e.lifecycle?` | lifecycle=${e.lifecycle}`:""}`).join(`
55
+ `)}function Np(t,e){let n=[],r=[],o=new Set;for(let i of t.list?.("all")??[]){if(!Ma(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||!Ma(i,e))continue;let s=V(i)??i.harnessSessionId,a=i.sessionId??$(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 dr(t,e,n){let r=t.workdir||Wp(t.prompt)||e.workspaceDir||E.defaultWorkdir||process.cwd();if(!$a(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=t.harness??le(),i=vt(o),s=t.model??i,a=Ne(o,s),d=t.model!==void 0,l=Kn(o);if(!a&&(o!=="opencode"||l&&l.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(a&&!Ct(o,a))return{kind:"error",text:`Error: Model "${s}" is not supported for harness "${o}". Use a bare Codex model id such as "gpt-5.5".`};if(a&&l&&l.length>0&&!Zn(o,a,l))return{kind:"error",text:d?`Error: Model "${s}" is not allowed. Permitted models: ${l.join(", ")}`:`Error: Default model "${s||"undefined"}" is not in allowedModels (${l.join(", ")}). Update your plugin config to set a compatible defaultModel.`};let u=Xn(o,a,l),c=Un(e),p=an(e,c||ot(r)),f=e.sessionKey||void 0,m=zs(f)??ci(e);if(!t.resume_session_id&&!t.force_new_session){let h=Np(n,{workdir:r,originSessionKey:f,originChannel:p,originThreadId:m});if(h.resumable.length>0||h.active.length>0){let w=h.resumable.length>0?["Linked resumable session(s) already exist for this thread/workdir:",_a(h.resumable),"","Resume the latest one with:",` agent_respond(session='${h.resumable[0].ref}', message='<next instruction>')`,"Fork from it with:",` agent_launch(prompt='<new task>', resume_session_id='${h.resumable[0].ref}', fork_session=true)`].join(`
56
+ `):"",N=h.active.length>0?[h.resumable.length>0?"Linked active session(s):":"Linked active session(s) already exist for this thread/workdir:",_a(h.active),"","Send a follow-up instead of launching a duplicate:",` agent_respond(session='${h.active[0].ref}', message='<next instruction>')`].join(`
57
+ `):"";return{kind:"blocked",text:["Resume-first protection blocked a fresh launch.","",w,N,["If you intentionally want a brand-new independent session here, call:"," agent_launch(prompt='<new task>', force_new_session=true)"].join(`
58
58
  `)].filter(Boolean).join(`
59
59
 
60
- `)}}}let y=t.resume_session_id,k=y?n.resolve?.(y):void 0,S=y?n.getPersistedSession?.(y):void 0;if(y){let h=n.resolveBackendConversationId?.(y)??n.resolveHarnessSessionId?.(y);if(!h)return{kind:"error",text:`Error: Could not resolve resume_session_id "${y}" to a session ID. Use agent_sessions to list available sessions.`};y=h}let{resumeSessionId:b,clearedPersistedCodexResume:A}=vt({requestedResumeSessionId:y,activeSession:k?{harnessSessionId:k.backendConversationId??k.harnessSessionId}:void 0,persistedSession:S?{harness:S.harness,backendRef:S.backendRef}:void 0}),x=t.permission_mode??D.permissionMode,R=t.plan_approval??D.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:u,permissionMode:x,planApproval:R,originChannel:p,originThreadId:m,originSessionKey:f,route:St(e,p,f),resumeSessionId:b,resolvedResumeId:y,clearedPersistedCodexResume:A,reasoningEffort:je(o),fastMode:kt(o)}}X();function fn(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function ar(t){let e=fn(t);return e?` | ${e}`:""}function xe(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 Dp=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 $a(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!Dp.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var _a={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function Op(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 Ea(t){let e=_a[t.phase]??_a[t.status]??"❓",n=xe(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}"`];if(t.worktreePath&&t.worktreeBranch&&s.push(` 🌿 Worktree: ${t.worktreeBranch} ${Op(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&&t.runtimeRecovery){let l=t.runtimeRecovery?.reason?` (${t.runtimeRecovery.reason})`:"";s.push(` ♻️ Recovered: persisted metadata only; no live process to kill${l}`),s.push(` 🩺 Recovery: raw=${t.runtimeRecovery.rawStatus??"unknown"}/${t.runtimeRecovery.rawLifecycle??"unknown"}/${t.runtimeRecovery.rawRuntimeState??"unknown"} → normalized=${t.runtimeRecovery.normalizedStatus}/${t.runtimeRecovery.normalizedLifecycle??"unknown"}/${t.runtimeRecovery.normalizedRuntimeState??"unknown"}`)}else t.recovered&&s.push(" 💾 Persisted: no live runtime process in this Gateway");t.harness?s.push(` 🧰 Harness | model: ${fn({harness:t.harness,model:t.model})}`):t.model&&s.push(` 🧰 Harness | model: ${t.model}`);let a=E(t);return a&&s.push(` 🔗 Backend ID: ${a}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
61
- `)}function lr(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?xe(n):"n/a"}`];if(t.mostExpensive){let a=t.mostExpensive;s.push("","🏆 Notable session",` ${a.name} [${a.id}]`,` 📝 "${a.prompt}"`)}return s.join(`
62
- `)}function le(t,e){return e<=0?"":t.length<=e?t:e<=3?".".repeat(e):t.slice(0,e-3)+"..."}function Da(t,e){let n=t.split(`
60
+ `)}}}let y=t.resume_session_id,k=y?n.resolve?.(y):void 0,S=y?n.getPersistedSession?.(y):void 0;if(y){let h=n.resolveBackendConversationId?.(y)??n.resolveHarnessSessionId?.(y);if(!h)return{kind:"error",text:`Error: Could not resolve resume_session_id "${y}" to a session ID. Use agent_sessions to list available sessions.`};y=h}let{resumeSessionId:b,clearedPersistedCodexResume:A}=bt({requestedResumeSessionId:y,activeSession:k?{harnessSessionId:k.backendConversationId??k.harnessSessionId}:void 0,persistedSession:S?{harness:S.harness,backendRef:S.backendRef}:void 0}),x=t.permission_mode??E.permissionMode,R=t.plan_approval??E.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:u,permissionMode:x,planApproval:R,originChannel:p,originThreadId:m,originSessionKey:f,route:Pt(e,p,f),resumeSessionId:b,resolvedResumeId:y,clearedPersistedCodexResume:A,reasoningEffort:He(o),fastMode:wt(o)}}ee();function yn(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function lr(t){let e=yn(t);return e?` | ${e}`:""}function Te(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 Lp=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 Da(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!Lp.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var Ea={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function Bp(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 Oa(t){let e=Ea[t.phase]??Ea[t.status]??"❓",n=Te(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}"`];if(t.worktreePath&&t.worktreeBranch&&s.push(` 🌿 Worktree: ${t.worktreeBranch} ${Bp(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&&t.runtimeRecovery){let d=t.runtimeRecovery?.reason?` (${t.runtimeRecovery.reason})`:"";s.push(` ♻️ Recovered: persisted metadata only; no live process to kill${d}`),s.push(` 🩺 Recovery: raw=${t.runtimeRecovery.rawStatus??"unknown"}/${t.runtimeRecovery.rawLifecycle??"unknown"}/${t.runtimeRecovery.rawRuntimeState??"unknown"} → normalized=${t.runtimeRecovery.normalizedStatus}/${t.runtimeRecovery.normalizedLifecycle??"unknown"}/${t.runtimeRecovery.normalizedRuntimeState??"unknown"}`)}else t.recovered&&s.push(" 💾 Persisted: no live runtime process in this Gateway");t.harness?s.push(` 🧰 Harness | model: ${yn({harness:t.harness,model:t.model})}`):t.model&&s.push(` 🧰 Harness | model: ${t.model}`);let a=$(t);return a&&s.push(` 🔗 Backend ID: ${a}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
61
+ `)}function ur(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?Te(n):"n/a"}`];if(t.mostExpensive){let a=t.mostExpensive;s.push("","🏆 Notable session",` ${a.name} [${a.id}]`,` 📝 "${a.prompt}"`)}return s.join(`
62
+ `)}function de(t,e){return e<=0?"":t.length<=e?t:e<=3?".".repeat(e):t.slice(0,e-3)+"..."}function Wa(t,e){let n=t.split(`
63
63
  `),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(`
64
- `)}function Oa(t,e){let n=t.split(`
64
+ `)}function Na(t,e){let n=t.split(`
65
65
  `),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(`
66
- `)}var rt,gn,Ct=!1;function Wa(t){try{return t?.config?.current?.()}catch{return}}function Mt(t,e){if(t&&typeof t=="object"){rt=t,arguments.length>=2?(gn=e,Ct=!0):Ct||(gn=Wa(rt),Ct=!0);return}rt=void 0,gn=void 0,Ct=!1}function _t(){return rt}function Na(){return rt?.tasks?.managedFlows??rt?.taskFlow}function La(){return Ct||(gn=Wa(rt),Ct=!0),gn}var Wp="openclaw-code-agent",Np=160,dr={create(){},progress(){},finalize(){}};function ur(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function Lp(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function Bp(t){let e=t.prompt.trim().replace(/\s+/g," ");return le(e||t.name,Np)}function Fp(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 qp(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 Ai(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 Kp(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 Up(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 Ba(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var xi=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:Wp,goal:Bp(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:Ii(e,"created",n),createdAt:e.startedAt,updatedAt:r}),this.lastProgressKey=this.progressKey(e,n)}catch(o){ur("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=Fp(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=Ii(e,"progress",n),i=Date.now(),s=Kp(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=Ba(this.flow,s),this.lastProgressKey=r}catch(o){ur("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=qp(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":Ai(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...Ii(e,"terminal",r),terminalStatus:n,terminalSummary:Ai(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:Ai(e.status,e.killReason),updatedAt:o,endedAt:o});Lp("finalize",s),this.flow=Ba(this.flow,s),this.finalized=!0}catch(o){ur("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function cr(t){if(!t.sessionKey?.trim())return dr;try{let e=Na()?.fromToolContext;if(typeof e!="function")return dr;let n=e(t);return Up(n)?new xi(n):dr}catch(e){return ur("resolve",e),dr}}function Vp(t){return t instanceof Error?t.message:String(t)}function Fa(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function Gp(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function jp(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function Hp(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function qa(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:g.Object({prompt:g.String({description:"The task prompt to execute"}),name:g.Optional(g.String({description:"Short human-readable name for the session (kebab-case, e.g. 'fix-auth'). Auto-generated from prompt if omitted."})),workdir:g.Optional(g.String({description:"Working directory (defaults to cwd)"})),model:g.Optional(g.String({description:"Model name to use"})),system_prompt:g.Optional(g.String({description:"Additional system prompt"})),allowed_tools:g.Optional(g.Array(g.String(),{description:"List of allowed tools"})),resume_session_id:g.Optional(g.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:g.Optional(g.Boolean({description:"When resuming, fork to a new session instead of continuing the existing one. Use with resume_session_id."})),force_new_session:g.Optional(g.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:g.Optional(g.Union([g.Literal("default"),g.Literal("plan"),g.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:g.Optional(g.Union([g.Literal("ask"),g.Literal("delegate"),g.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:g.Optional(g.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode'). Defaults to the plugin defaultHarness."})),worktree_strategy:g.Optional(g.Union([g.Literal("off"),g.Literal("manual"),g.Literal("ask"),g.Literal("delegate"),g.Literal("auto-merge"),g.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:g.Optional(g.String({description:"Base branch for worktree merge/PR operations (default: auto-detected or 'main')"})),worktree_pr_target_repo:g.Optional(g.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(!Gp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=sr(n,t,v);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};let{workdir:o,harness:i,resolvedModel:s,permissionMode:a,planApproval:l,originChannel:d,originThreadId:u,originSessionKey:c,route:p,resumeSessionId:f,resolvedResumeId:m,clearedPersistedCodexResume:y,reasoningEffort:k,fastMode:S}=r,b=n.resume_session_id?v.resolve(n.resume_session_id)??v.getPersistedSession(n.resume_session_id):void 0,A=!n.fork_session&&b?mn(b):void 0;if(A?.kind==="direct")return{content:[{type:"text",text:`Session ${b.name} [${Fa(b,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(A?.kind==="unavailable")return{content:[{type:"text",text:`Resume unavailable for session ${b.name} [${Fa(b,n.resume_session_id)}] (${A.reason}). Use agent_launch(prompt='<new task>') for a fresh session or set fork_session=true to fork from prior context.`}]};let x=n.worktree_strategy??D.defaultWorktreeStrategy??"off",R=n.fork_session?void 0:A?.kind==="resume"||A?.kind==="relaunch"?A.stableSessionId:void 0;if(x!=="off"&&Hp(v)&&v.checkRepoPolicyForLaunch(o,n.worktree_strategy).ok===!1)return{content:[{type:"text",text:v.requestRepoPolicyForLaunch({route:p,prompt:n.prompt,workdir:o,name:n.name,model:s,reasoningEffort:k,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:A?.kind==="resume"?A.resumeSessionId:f,resumeWorktreeFrom:m,sessionIdOverride:R,clearedPersistedCodexResume:y,forkSession:f?n.fork_session:!1,forceNewSession:n.force_new_session,permissionMode:a,planApproval:l,harness:i,worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo,originAgentId:t.agentId||void 0})}]};let h=v.spawn({prompt:n.prompt,sessionIdOverride:R,name:n.name,workdir:o,model:s,reasoningEffort:k,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:A?.kind==="resume"?A.resumeSessionId:f,resumeWorktreeFrom:m,forkSession:f?n.fork_session:!1,multiTurn:!0,permissionMode:a,planApproval:l,codexApprovalPolicy:i==="codex"?"never":void 0,originChannel:d,originThreadId:u,originAgentId:t.agentId||void 0,originSessionKey:c,route:p,harness:i,taskLifecycle:cr(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:jp(v)?v.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:l,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,clearedPersistedCodexResume:y},h):Bn({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:l,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:y},{id:h.id,name:h.name,model:h.model,reasoningEffort:h.reasoningEffort??je(i),fastMode:h.fastMode??S,worktreeStrategy:h.worktreeStrategy??n.worktree_strategy??D.defaultWorktreeStrategy??"off",repoIntegrationPolicy:h.repoIntegrationPolicy,repoProvider:h.repoProvider,worktreePath:h.worktreePath,originalWorkdir:h.originalWorkdir})}]}}catch(r){let o=Vp(r),i=o.includes("Max sessions")?"":`
66
+ `)}var st,kn,$t=!1;function La(t){try{return t?.config?.current?.()}catch{return}}function Et(t,e){if(t&&typeof t=="object"){st=t,arguments.length>=2?(kn=e,$t=!0):$t||(kn=La(st),$t=!0);return}st=void 0,kn=void 0,$t=!1}function Dt(){return st}function Ba(){return st?.tasks?.managedFlows??st?.taskFlow}function Fa(){return $t||(kn=La(st),$t=!0),kn}var Fp="openclaw-code-agent",qp=160,cr={create(){},progress(){},finalize(){}};function pr(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function Kp(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function Up(t){let e=t.prompt.trim().replace(/\s+/g," ");return de(e||t.name,qp)}function Vp(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 Gp(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 jp(t){return t.lifecycle==="awaiting_plan_decision"||t.lifecycle==="awaiting_user_input"||t.lifecycle==="awaiting_worktree_decision"||t.lifecycle==="suspended"}function Ti(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 Hp(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 qa(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var Ci=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:Fp,goal:Up(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:Ti(e,"created",n),createdAt:e.startedAt,updatedAt:r}),this.lastProgressKey=this.progressKey(e,n)}catch(o){pr("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=Vp(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=Ti(e,"progress",n),i=Date.now(),s=jp(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=qa(this.flow,s),this.lastProgressKey=r}catch(o){pr("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=Gp(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":xi(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...Ti(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:i,updatedAt:o,endedAt:o}):this.taskFlow.fail({flowId:this.flow.flowId,expectedRevision:this.flow.revision,stateJson:i,blockedSummary:xi(e.status,e.killReason),updatedAt:o,endedAt:o});Kp("finalize",s),this.flow=qa(this.flow,s),this.finalized=!0}catch(o){pr("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function mr(t){if(!t.sessionKey?.trim())return cr;try{let e=Ba()?.fromToolContext;if(typeof e!="function")return cr;let n=e(t);return Hp(n)?new Ci(n):cr}catch(e){return pr("resolve",e),cr}}function zp(t){return t instanceof Error?t.message:String(t)}function Ka(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function Qp(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function Jp(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function Yp(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function Ua(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:g.Object({prompt:g.String({description:"The task prompt to execute"}),name:g.Optional(g.String({description:"Short human-readable name for the session (kebab-case, e.g. 'fix-auth'). Auto-generated from prompt if omitted."})),workdir:g.Optional(g.String({description:"Working directory (defaults to cwd)"})),model:g.Optional(g.String({description:"Model name to use"})),system_prompt:g.Optional(g.String({description:"Additional system prompt"})),allowed_tools:g.Optional(g.Array(g.String(),{description:"List of allowed tools"})),resume_session_id:g.Optional(g.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:g.Optional(g.Boolean({description:"When resuming, fork to a new session instead of continuing the existing one. Use with resume_session_id."})),force_new_session:g.Optional(g.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:g.Optional(g.Union([g.Literal("default"),g.Literal("plan"),g.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:g.Optional(g.Union([g.Literal("ask"),g.Literal("delegate"),g.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:g.Optional(g.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode'). Defaults to the plugin defaultHarness."})),worktree_strategy:g.Optional(g.Union([g.Literal("off"),g.Literal("manual"),g.Literal("ask"),g.Literal("delegate"),g.Literal("auto-merge"),g.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:g.Optional(g.String({description:"Base branch for worktree merge/PR operations (default: auto-detected or 'main')"})),worktree_pr_target_repo:g.Optional(g.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(!Qp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=dr(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:m,clearedPersistedCodexResume:y,reasoningEffort:k,fastMode:S}=r,b=n.resume_session_id?v.resolve(n.resume_session_id)??v.getPersistedSession(n.resume_session_id):void 0,A=!n.fork_session&&b?hn(b):void 0;if(A?.kind==="direct")return{content:[{type:"text",text:`Session ${b.name} [${Ka(b,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(A?.kind==="unavailable")return{content:[{type:"text",text:`Resume unavailable for session ${b.name} [${Ka(b,n.resume_session_id)}] (${A.reason}). Use agent_launch(prompt='<new task>') for a fresh session or set fork_session=true to fork from prior context.`}]};let x=n.worktree_strategy??E.defaultWorktreeStrategy??"off",R=n.fork_session?void 0:A?.kind==="resume"||A?.kind==="relaunch"?A.stableSessionId:void 0;if(x!=="off"&&Yp(v)&&v.checkRepoPolicyForLaunch(o,n.worktree_strategy).ok===!1)return{content:[{type:"text",text:v.requestRepoPolicyForLaunch({route:p,prompt:n.prompt,workdir:o,name:n.name,model:s,reasoningEffort:k,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:A?.kind==="resume"?A.resumeSessionId:f,resumeWorktreeFrom:m,sessionIdOverride:R,clearedPersistedCodexResume:y,forkSession:f?n.fork_session:!1,forceNewSession:n.force_new_session,permissionMode:a,planApproval:d,harness:i,worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo,originAgentId:t.agentId||void 0})}]};let h=v.spawn({prompt:n.prompt,sessionIdOverride:R,name:n.name,workdir:o,model:s,reasoningEffort:k,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:A?.kind==="resume"?A.resumeSessionId:f,resumeWorktreeFrom:m,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:mr(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:Jp(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:y},h):qn({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:y},{id:h.id,name:h.name,model:h.model,reasoningEffort:h.reasoningEffort??He(i),fastMode:h.fastMode??S,worktreeStrategy:h.worktreeStrategy??n.worktree_strategy??E.defaultWorktreeStrategy??"off",repoIntegrationPolicy:h.repoIntegrationPolicy,repoProvider:h.repoProvider,worktreePath:h.worktreePath,originalWorkdir:h.originalWorkdir})}]}}catch(r){let o=zp(r),i=o.includes("Max sessions")?"":`
67
67
 
68
- Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}re();F();ae();import{existsSync as Oi,readFileSync as ml}from"fs";import{EventEmitter as bm}from"events";import{webcrypto as Ua}from"node:crypto";var Ka="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var zp=128,ot,$t;function Qp(t){if(t<0||t>1024)throw new RangeError("Wrong ID size");!ot||ot.length<t?(ot=Buffer.allocUnsafe(t*zp),Ua.getRandomValues(ot),$t=0):$t+t>ot.length&&(Ua.getRandomValues(ot),$t=0),$t+=t}function pr(t=21){Qp(t|=0);let e="";for(let n=$t-t;n<$t;n++)e+=Ka[ot[n]&63];return e}Pi();ae();X();var Va={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function Y(t,e){return Object.hasOwn(t,e)}var Ga=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function Jp(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 ce(t){return{...t,approvalExecutionState:Jp(t)}}function Ti(t,e){switch(e.type){case"initialize":return ce({...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"?ce({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?ce({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):ce({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return ce({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return ce({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return ce({...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 ce({...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 ce({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return ce({...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 ce({...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 ce({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return ce({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return ce({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":Ga.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return ce({...t,deliveryState:e.deliveryState})}}function ja(t,e){let n={...t,...Y(e,"lifecycle")?{lifecycle:e.lifecycle}:{},...Y(e,"approvalState")?{approvalState:e.approvalState}:{},...Y(e,"approvalExecutionState")?{approvalExecutionState:e.approvalExecutionState}:{},...Y(e,"worktreeState")?{worktreeState:e.worktreeState}:{},...Y(e,"runtimeState")?{runtimeState:e.runtimeState}:{},...Y(e,"deliveryState")?{deliveryState:e.deliveryState}:{},...Y(e,"requestedPermissionMode")?{requestedPermissionMode:e.requestedPermissionMode}:{},...Y(e,"currentPermissionMode")?{currentPermissionMode:e.currentPermissionMode}:{},...Y(e,"pendingPlanApproval")?{pendingPlanApproval:e.pendingPlanApproval}:{},...Y(e,"planApprovalContext")?{planApprovalContext:e.planApprovalContext}:{},...Y(e,"planDecisionVersion")?{planDecisionVersion:e.planDecisionVersion}:{},...Y(e,"actionablePlanDecisionVersion")?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...Y(e,"canonicalPlanPromptVersion")?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...Y(e,"approvalPromptRequiredVersion")?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...Y(e,"approvalPromptVersion")?{approvalPromptVersion:e.approvalPromptVersion}:{},...Y(e,"approvalPromptStatus")?{approvalPromptStatus:e.approvalPromptStatus}:{},...Y(e,"approvalPromptTransport")?{approvalPromptTransport:e.approvalPromptTransport}:{},...Y(e,"approvalPromptMessageKind")?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...Y(e,"approvalPromptLastAttemptAt")?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...Y(e,"approvalPromptDeliveredAt")?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...Y(e,"approvalPromptFailedAt")?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{},...Y(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"}),Y(e,"pendingWorktreeDecisionSince")&&e.pendingWorktreeDecisionSince!==void 0||n.worktreeState==="pending_decision"?n=Ti(n,{type:"worktree.decision_requested"}):Ga.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),ce(n)}var mr=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{createHash as Yp}from"crypto";import{appendFileSync as Zp}from"fs";import{tmpdir as Xp}from"os";import{join as em}from"path";var Ha=2e3,tm=/^[A-Za-z0-9_.-]+$/;function nm(t){return tm.test(t)?t:`hashed+${Yp("sha256").update(t,"utf8").digest("hex")}`}function it(t){return em(Xp(),`openclaw-agent-${nm(t)}.txt`)}function rm(t,e){if(!e)return;let n=e.split(`
69
- `),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function za(t,e,n){rm(t,n),t.length>Ha&&t.splice(0,t.length-Ha);try{Zp(it(e),n,"utf-8")}catch{}return t}var fr=class{timers=new Map;get size(){return this.timers.size}set(e,n,r){this.clear(e);let o=setTimeout(()=>{this.timers.get(e)===o&&this.timers.delete(e),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 gr=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?`
70
- ${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,l=o;(n==="plan"||r==="plan")&&!l&&!i&&(this.deps.markPendingPlanApproval("plan-mode"),l=!0);let d=l||this.lastTurnHadQuestion||!!s;if(this.turnInProgress=a,d&&!this.waitingForInputFired)this.waitingForInputFired=!0,l||this.deps.markAwaitingUserInput(),this.deps.emitTurnEnd(!0);else if(!a&&!d){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 hr=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}};ke();var Rm=120*1e3;function xr(t){return t instanceof Error?t.message:String(t)}function Am(t,e){JSON.stringify({component:"Session",event:t,at:new Date().toISOString(),...e})}function Im(t){return t?{backendRefKind:t.kind,hasBackendConversationId:!!t.conversationId,hasBackendRunId:!!t.runId,hasBackendWorktreeId:!!t.worktreeId,hasBackendWorktreePath:!!t.worktreePath}:{}}var Tr=class extends bm{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;repoIntegrationPolicy;repoIntegrationPolicySource;repoProvider;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 fr;constructor(e,n){super(),this.id=e.sessionIdOverride??pr(8),this.name=n,this.harness=e.harness?un(e.harness):Ia(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??yt(this.harness.name),this.reasoningEffort=e.reasoningEffort??je(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??kt(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??D.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??D.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.repoIntegrationPolicy=e.repoIntegrationPolicy,this.repoIntegrationPolicySource=e.repoIntegrationPolicySource,this.repoProvider=e.repoProvider,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 gr({appendOutput:r=>za(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 hr({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??=Et(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 E(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,repoIntegrationPolicy:this.repoIntegrationPolicy,repoIntegrationPolicySource:this.repoIntegrationPolicySource,repoProvider:this.repoProvider,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 turnInProgress(){return this.turnRuntime.turnInProgress}set turnInProgress(e){this.turnRuntime.turnInProgress=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(!Va[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(i=>`- ${i}`).join(`
68
+ Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}re();K();ae();import{existsSync as Ni,readFileSync as hd}from"fs";import{EventEmitter as xm}from"events";import{webcrypto as Ga}from"node:crypto";var Va="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var Zp=128,Ye,Ot;function Xp(t){if(t<0)throw new RangeError("Wrong ID size");try{!Ye||Ye.length<t?(Ye=Buffer.allocUnsafe(t*Zp),Ga.getRandomValues(Ye),Ot=0):Ot+t>Ye.length&&(Ga.getRandomValues(Ye),Ot=0)}catch(e){throw Ye=void 0,e}Ot+=t}function fr(t=21){Xp(t|=0);let e="";for(let n=Ot-t;n<Ot;n++)e+=Va[Ye[n]&63];return e}Ri();ae();ee();var ja={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function Z(t,e){return Object.hasOwn(t,e)}var Ha=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function em(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 ce(t){return{...t,approvalExecutionState:em(t)}}function Mi(t,e){switch(e.type){case"initialize":return ce({...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"?ce({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?ce({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):ce({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return ce({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return ce({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return ce({...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 ce({...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 ce({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return ce({...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 ce({...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 ce({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return ce({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return ce({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":Ha.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return ce({...t,deliveryState:e.deliveryState})}}function za(t,e){let n={...t,...Z(e,"lifecycle")?{lifecycle:e.lifecycle}:{},...Z(e,"approvalState")?{approvalState:e.approvalState}:{},...Z(e,"approvalExecutionState")?{approvalExecutionState:e.approvalExecutionState}:{},...Z(e,"worktreeState")?{worktreeState:e.worktreeState}:{},...Z(e,"runtimeState")?{runtimeState:e.runtimeState}:{},...Z(e,"deliveryState")?{deliveryState:e.deliveryState}:{},...Z(e,"requestedPermissionMode")?{requestedPermissionMode:e.requestedPermissionMode}:{},...Z(e,"currentPermissionMode")?{currentPermissionMode:e.currentPermissionMode}:{},...Z(e,"pendingPlanApproval")?{pendingPlanApproval:e.pendingPlanApproval}:{},...Z(e,"planApprovalContext")?{planApprovalContext:e.planApprovalContext}:{},...Z(e,"planDecisionVersion")?{planDecisionVersion:e.planDecisionVersion}:{},...Z(e,"actionablePlanDecisionVersion")?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...Z(e,"canonicalPlanPromptVersion")?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...Z(e,"approvalPromptRequiredVersion")?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...Z(e,"approvalPromptVersion")?{approvalPromptVersion:e.approvalPromptVersion}:{},...Z(e,"approvalPromptStatus")?{approvalPromptStatus:e.approvalPromptStatus}:{},...Z(e,"approvalPromptTransport")?{approvalPromptTransport:e.approvalPromptTransport}:{},...Z(e,"approvalPromptMessageKind")?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...Z(e,"approvalPromptLastAttemptAt")?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...Z(e,"approvalPromptDeliveredAt")?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...Z(e,"approvalPromptFailedAt")?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{},...Z(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"}),Z(e,"pendingWorktreeDecisionSince")&&e.pendingWorktreeDecisionSince!==void 0||n.worktreeState==="pending_decision"?n=Mi(n,{type:"worktree.decision_requested"}):Ha.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),ce(n)}var gr=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{createHash as tm}from"crypto";import{appendFileSync as nm}from"fs";import{tmpdir as rm}from"os";import{join as om}from"path";var Qa=2e3,im=/^[A-Za-z0-9_.-]+$/;function sm(t){return im.test(t)?t:`hashed+${tm("sha256").update(t,"utf8").digest("hex")}`}function at(t){return om(rm(),`openclaw-agent-${sm(t)}.txt`)}function am(t,e){if(!e)return;let n=e.split(`
69
+ `),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function Ja(t,e,n){am(t,n),t.length>Qa&&t.splice(0,t.length-Qa);try{nm(at(e),n,"utf-8")}catch{}return t}var hr=class{timers=new Map;get size(){return this.timers.size}set(e,n,r){this.clear(e);let o=setTimeout(()=>{this.timers.get(e)===o&&this.timers.delete(e),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 yr=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?`
70
+ ${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 kr=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}};ke();var Tm=120*1e3;function Cr(t){return t instanceof Error?t.message:String(t)}function Cm(t,e){JSON.stringify({component:"Session",event:t,at:new Date().toISOString(),...e})}function Mm(t){return t?{backendRefKind:t.kind,hasBackendConversationId:!!t.conversationId,hasBackendRunId:!!t.runId,hasBackendWorktreeId:!!t.worktreeId,hasBackendWorktreePath:!!t.worktreePath}:{}}var Mr=class extends xm{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;repoIntegrationPolicy;repoIntegrationPolicySource;repoProvider;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 hr;constructor(e,n){super(),this.id=e.sessionIdOverride??fr(8),this.name=n,this.harness=e.harness?mn(e.harness):Ta(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??vt(this.harness.name),this.reasoningEffort=e.reasoningEffort??He(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??wt(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.repoIntegrationPolicy=e.repoIntegrationPolicy,this.repoIntegrationPolicySource=e.repoIntegrationPolicySource,this.repoProvider=e.repoProvider,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 yr({appendOutput:r=>Ja(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 kr({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??=Ze(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 $(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,repoIntegrationPolicy:this.repoIntegrationPolicy,repoIntegrationPolicySource:this.repoIntegrationPolicySource,repoProvider:this.repoProvider,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 turnInProgress(){return this.turnRuntime.turnInProgress}set turnInProgress(e){this.turnRuntime.turnInProgress=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(!ja[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=lt(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(i=>`- ${i}`).join(`
71
71
  `),r=e.length>20?`
72
72
  - ...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(`
73
- `);return this.messageStream.push(this.harness.buildUserMessage(o,this.backendConversationId??"")),!0}async start(){this.logDiagnostic("harness.launch.start",{model:this.model,hasWorkdir:!!this.workdir,hasResumeSessionId:!!this.resumeSessionId,forkSessionRequested:this.forkSession===!0,hasBackendRef:!!this.backendRef});try{let e;this.multiTurn?(this.messageStream=new mr,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:Us(),canUseTool:this.canUseTool});this.harnessHandle=n,this.logDiagnostic("harness.launch.created",{hasStreamInput:!!n.streamInput,hasInterrupt:!!n.interrupt,hasPermissionModeSwitch:!!n.setPermissionMode}),this.setTimer("startup",Rm,()=>{this._status==="starting"&&this.kill("startup-timeout")})}catch(e){let n=e instanceof Error?e.message:String(e);this.logDiagnostic("harness.launch.error",{error:n}),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;this.logDiagnostic("harness.stream.error",{error:n}),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: ${xr(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${xr(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.]
73
+ `);return this.messageStream.push(this.harness.buildUserMessage(o,this.backendConversationId??"")),!0}async start(){this.logDiagnostic("harness.launch.start",{model:this.model,hasWorkdir:!!this.workdir,hasResumeSessionId:!!this.resumeSessionId,forkSessionRequested:this.forkSession===!0,hasBackendRef:!!this.backendRef});try{let e;this.multiTurn?(this.messageStream=new gr,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:Gs(),canUseTool:this.canUseTool});this.harnessHandle=n,this.logDiagnostic("harness.launch.created",{hasStreamInput:!!n.streamInput,hasInterrupt:!!n.interrupt,hasPermissionModeSwitch:!!n.setPermissionMode}),this.setTimer("startup",Tm,()=>{this._status==="starting"&&this.kill("startup-timeout")})}catch(e){let n=e instanceof Error?e.message:String(e);this.logDiagnostic("harness.launch.error",{error:n}),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;this.logDiagnostic("harness.stream.error",{error:n}),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: ${Cr(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${Cr(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.]
74
74
 
75
75
  ${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.]
76
76
 
77
- ${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}${xr(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,n){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputOption)return!1;let r=await this.harnessHandle.submitPendingInputOption(e,n);return r&&(this.waitingForInputFired=!1),r}canSubmitPendingInputOption(){return!!(this.pendingInputState&&this.harnessHandle?.submitPendingInputOption)}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=(D.idleTimeoutMinutes??15)*60*1e3;this.setTimer("idle",e,()=>{this._status==="running"&&(this.logDiagnostic("idle_timeout.fire",{idleTimeoutMinutes:D.idleTimeoutMinutes??15}),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}${xr(e)}`}),this.abortController.abort(),this.applyControlEvent({type:"terminal.entered",suspended:this.lifecycle==="suspended"})}transitionToTerminal(e,n={}){this.isActive&&(this.logDiagnostic("terminal.transition",{nextStatus:e,reason:n.reason,error:n.error,currentStatus:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState}),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){let n=0;for await(let r of e){if(!this.isActive)break;this.resetIdleTimer(),n+=1,this.harnessEvents.applyMessage(r,{pendingPlanApproval:this.pendingPlanApproval,currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState})}this.logDiagnostic("harness.stream.end",{messageCount:n,activeAtEnd:this.isActive,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState})}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=Ti(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=ja(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)}logDiagnostic(e,n={}){let{backendRef:r,harnessSessionId:o,...i}=n;Am(e,{sessionId:this.id,name:this.name,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState,harness:this.harnessName,hasHarnessSessionId:!!this.harnessSessionId,...Im(this.backendRef),...i})}};var xm=50,Tm=1,Cm=new Set(["starting","running","completed","failed","killed"]),Mm=5,_m=1440*60*1e3,Cr=new Set(["merged","released","dismissed","no_change"]);function $m(t){let e=Number(t);return!Number.isFinite(e)||e<Tm?xm:Math.floor(e)}function Em(t){return typeof t=="string"&&Cm.has(t)}function Dm(t){let e=t.split(`
78
- `);return e.at(-1)===""&&e.pop(),e}function Wi(t){return t.backendRef?.conversationId??t.harnessSessionId}function Om(t,e){return e&&Cr.has(e)&&(!t||!Cr.has(t))?e:t??e}function Wm(t,e){return e&&Cr.has(e.state)&&(!t||!Cr.has(t.state))?e:t??e}function fl(t,e,n){let r=ml(t,"utf-8"),o=Dm(r);return e.full?o:o.slice(-n)}function Nm(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=it(t.id);if(!Oi(r))return null;try{return fl(r,e,n)}catch{return null}}function Lm(t){let e=xe(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(`
79
- `)}function gl(t,e){let n=t.name||t.sessionId||Wi(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(`
80
- `)}function Bm(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function Fm(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 pl(t,e){let n=gl(t,Fm(t)),r=Wi(t),o=r?`
77
+ ${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}${Cr(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,n){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputOption)return!1;let r=await this.harnessHandle.submitPendingInputOption(e,n);return r&&(this.waitingForInputFired=!1),r}canSubmitPendingInputOption(){return!!(this.pendingInputState&&this.harnessHandle?.submitPendingInputOption)}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.logDiagnostic("idle_timeout.fire",{idleTimeoutMinutes:E.idleTimeoutMinutes??15}),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}${Cr(e)}`}),this.abortController.abort(),this.applyControlEvent({type:"terminal.entered",suspended:this.lifecycle==="suspended"})}transitionToTerminal(e,n={}){this.isActive&&(this.logDiagnostic("terminal.transition",{nextStatus:e,reason:n.reason,error:n.error,currentStatus:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState}),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){let n=0;for await(let r of e){if(!this.isActive)break;this.resetIdleTimer(),n+=1,this.harnessEvents.applyMessage(r,{pendingPlanApproval:this.pendingPlanApproval,currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState})}this.logDiagnostic("harness.stream.end",{messageCount:n,activeAtEnd:this.isActive,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState})}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=Mi(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=za(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)}logDiagnostic(e,n={}){let{backendRef:r,harnessSessionId:o,...i}=n;Cm(e,{sessionId:this.id,name:this.name,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState,harness:this.harnessName,hasHarnessSessionId:!!this.harnessSessionId,...Mm(this.backendRef),...i})}};var _m=50,$m=1,Em=new Set(["starting","running","completed","failed","killed"]),Dm=5,Om=1440*60*1e3,_r=new Set(["merged","released","dismissed","no_change"]);function Wm(t){let e=Number(t);return!Number.isFinite(e)||e<$m?_m:Math.floor(e)}function Nm(t){return typeof t=="string"&&Em.has(t)}function Lm(t){let e=t.split(`
78
+ `);return e.at(-1)===""&&e.pop(),e}function Li(t){return t.backendRef?.conversationId??t.harnessSessionId}function Bm(t,e){return e&&_r.has(e)&&(!t||!_r.has(t))?e:t??e}function Fm(t,e){return e&&_r.has(e.state)&&(!t||!_r.has(t.state))?e:t??e}function yd(t,e,n){let r=hd(t,"utf-8"),o=Lm(r);return e.full?o:o.slice(-n)}function qm(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=at(t.id);if(!Ni(r))return null;try{return yd(r,e,n)}catch{return null}}function Km(t){let e=Te(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(`
79
+ `)}function kd(t,e){let n=t.name||t.sessionId||Li(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(`
80
+ `)}function Um(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function Vm(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 gd(t,e){let n=kd(t,Vm(t)),r=Li(t),o=r?`
81
81
  Backend session: ${r}`:"";return`${n}
82
- (no persisted output available: ${e})${o}`}function qm(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?`
82
+ (no persisted output available: ${e})${o}`}function Gm(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?`
83
83
  (no output yet)
84
84
  ${e.join(`
85
85
  `)}`:`
86
- (no output yet)`}function Mr(t,e,n={}){let r=$m(n.lines),o=t.resolve(e);if(!o){let d=t.getPersistedSession(e);if(d?.outputPath&&Oi(d.outputPath))try{let u=fl(d.outputPath,n,r).join(`
87
- `),c=gl(d,Bm(d));return u?`${c}
86
+ (no output yet)`}function $r(t,e,n={}){let r=Wm(n.lines),o=t.resolve(e);if(!o){let l=t.getPersistedSession(e);if(l?.outputPath&&Ni(l.outputPath))try{let u=yd(l.outputPath,n,r).join(`
87
+ `),c=kd(l,Um(l));return u?`${c}
88
88
  ${u}`:`${c}
89
- (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 d?.outputPath?pl(d,`output file is missing at ${d.outputPath}`):d?pl(d,"no outputPath is stored for this recovered session"):`Error: Session "${e}" not found.`}let i=Nm(o,n,r),s=i&&i.length>0?i:n.full?o.getOutput():o.getOutput(r),a=Lm(o),l=s.length===0?`${a}${qm(o)}`:`${a}
89
+ (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?gd(l,`output file is missing at ${l.outputPath}`):l?gd(l,"no outputPath is stored for this recovered session"):`Error: Session "${e}" not found.`}let i=qm(o,n,r),s=i&&i.length>0?i:n.full?o.getOutput():o.getOutput(r),a=Km(o),d=s.length===0?`${a}${Gm(o)}`:`${a}
90
90
  ${s.join(`
91
- `)}`;if(o.pendingPlanApproval&&o.planFilePath)try{if(Oi(o.planFilePath)){let d=ml(o.planFilePath,"utf-8"),u="─".repeat(60);return`${l}
91
+ `)}`;if(o.pendingPlanApproval&&o.planFilePath)try{if(Ni(o.planFilePath)){let l=hd(o.planFilePath,"utf-8"),u="─".repeat(60);return`${d}
92
92
  ${u}
93
93
  Plan file: ${o.planFilePath}
94
94
  ${u}
95
- ${d}`}}catch{}return l}function _r(t,e="all",n,r={}){let o=t.listPersistedSessions()??[],s=Km(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()-_m;s=s.filter(l=>(l.startedAt??0)>=a)}else s=s.slice(0,Mm);return s.length===0?"No sessions found.":s.map(a=>Ea(a)).join(`
95
+ ${l}`}}catch{}return d}function Er(t,e="all",n,r={}){let o=t.listPersistedSessions()??[],s=jm(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()-Om;s=s.filter(d=>(d.startedAt??0)>=a)}else s=s.slice(0,Dm);return s.length===0?"No sessions found.":s.map(a=>Oa(a)).join(`
96
96
 
97
- `)}function Km(t,e){let n=new Map;for(let r of e){if(!Em(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=Wi(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,runtimeRecovery:r.runtimeRecovery})}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:Om(r.worktreeState,o?.worktreeState),worktreeLifecycle:Wm(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 Um(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 hl(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:g.Object({status:g.Optional(g.Union([g.Literal("all"),g.Literal("running"),g.Literal("completed"),g.Literal("failed"),g.Literal("killed")],{description:'Filter by status (default "all")'})),full:g.Optional(g.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=Um(n),o=t?.workspaceDir?tt(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:_r(v,r,o,{full:i})}]}}}}re();F();function $r(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 Vm(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 yl(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:g.Object({session:g.String({description:"Session name or ID to terminate"}),reason:g.Optional(g.Union([g.Literal("completed"),g.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?Vm(n)?{content:[{type:"text",text:$r(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."}]}}}}re();F();function Gm(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Er(t){return{name:"agent_output",description:"Show recent output from a coding agent session (by name or ID).",parameters:g.Object({session:g.String({description:"Session name or ID to get output from"}),lines:g.Optional(g.Number({description:"Number of recent lines to show (default 50)"})),full:g.Optional(g.Boolean({description:"Show all available output"}))}),async execute(e,n){return v?Gm(n)?{content:[{type:"text",text:Mr(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."}]}}}}re();F();ae();X();var jm=10;function Li(t){return t instanceof Error?t.message:String(t)}function dt(t){return U(t)??t.harnessSessionId??"unknown-session"}function Hm(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return ir(t)??U(t)??E(t)}function kl(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!E(t)}function zm(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 vn(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='${dt(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='${dt(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='${dt(t)}', fork_session=true, prompt='<new task>').`:`Use agent_respond(session='${dt(t)}', message='<next instruction>') to continue the running session.`,o=n?` ${n}`:"";return{text:`Resume unavailable for session ${t.name} [${dt(t)}] (${e}).${o} ${r}`,isError:!0}}async function Sl(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:ir(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} [${dt(e)}]: ${Li(r)}`,isError:!0}}}var Qm=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
97
+ `)}function jm(t,e){let n=new Map;for(let r of e){if(!Nm(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=Li(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,runtimeRecovery:r.runtimeRecovery})}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:Bm(r.worktreeState,o?.worktreeState),worktreeLifecycle:Fm(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 Hm(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 Sd(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:g.Object({status:g.Optional(g.Union([g.Literal("all"),g.Literal("running"),g.Literal("completed"),g.Literal("failed"),g.Literal("killed")],{description:'Filter by status (default "all")'})),full:g.Optional(g.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=Hm(n),o=t?.workspaceDir?ot(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:Er(v,r,o,{full:i})}]}}}}re();K();function Dr(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 zm(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 vd(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:g.Object({session:g.String({description:"Session name or ID to terminate"}),reason:g.Optional(g.Union([g.Literal("completed"),g.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?zm(n)?{content:[{type:"text",text:Dr(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."}]}}}}re();K();function Qm(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Or(t){return{name:"agent_output",description:"Show recent output from a coding agent session (by name or ID).",parameters:g.Object({session:g.String({description:"Session name or ID to get output from"}),lines:g.Optional(g.Number({description:"Number of recent lines to show (default 50)"})),full:g.Optional(g.Boolean({description:"Show all available output"}))}),async execute(e,n){return v?Qm(n)?{content:[{type:"text",text:$r(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."}]}}}}re();K();ae();ee();var Jm=10;function Fi(t){return t instanceof Error?t.message:String(t)}function pt(t){return V(t)??t.harnessSessionId??"unknown-session"}function Ym(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return ar(t)??V(t)??$(t)}function wd(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!$(t)}function Zm(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 Pn(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='${pt(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='${pt(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='${pt(t)}', fork_session=true, prompt='<new task>').`:`Use agent_respond(session='${pt(t)}', message='<next instruction>') to continue the running session.`,o=n?` ${n}`:"";return{text:`Resume unavailable for session ${t.name} [${pt(t)}] (${e}).${o} ${r}`,isError:!0}}async function Pd(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:ar(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`,"notification",`agent-respond-relaunched:${o.id}:${o.startedAt}`),{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} [${pt(e)}]: ${Fi(r)}`,isError:!0}}}var Xm=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
98
98
 
99
- `;function vl(t){let e=t?.replace(/\s+/g," ").trim();if(e)return le(e,240)}function Ni(t){if(t.approvalState==="changes_requested"&&!Dr(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 Dr(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function Jm(t){return Ni(t)?!1:Dr(t)||t.currentPermissionMode==="plan"}function Ym(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 Zm(t){return(t.planDecisionVersion??0)+1}function wl(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:Zm(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 Pl(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function Bi(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=wl(o,"rejected");return n?(Pl(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 Fi(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=wl(o,"changes_requested");n&&Pl(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function Xm(t,e,n,r={}){let o=mn(e);if(!(o.kind==="resume"||kl(e)))return;let s=!!(r.approve&&Jm(e)),a=s?vl(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?Sl(t,e,n):vn(e,o.reason);let l={prompt:s?Qm+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:Hm(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},d=await t.spawnAndAwaitRunning(l,{notifyLaunch:!1});return s?(t.notifySession(d,`👍 [${d.name}] Plan approved (resumed)`,"plan-approved"),{text:`Plan approved for session ${d.name} [${d.id}]. Session resumed in bypassPermissions mode. Use agent_output to see the response.`}):(t.notifySession(d,`▶️ [${d.name}] Auto-resumed`),{text:`Auto-resumed session ${d.name} [${d.id}]. Use agent_output to see the response.`})}catch(l){return vn(e,"missing_backend_state",`Backend resume failed: ${Li(l)}`)}}async function we(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"}:mn(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?zm(e.message):void 0;if(s==="approve")return we(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return Fi(t,n?.id??r?.sessionId??e.session);if(s==="reject")return Bi(t,n?.id??r?.sessionId??e.session);if(e.approve){let l=Ni(o);if(l)return{text:l,isError:!0}}if(i.kind==="resume"||kl(o)){let l=await Xm(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(l)return l}else{if(i.kind==="relaunch")return Sl(t,o,e.message);if(i.kind==="unavailable")return vn(o,i.reason)}if(!n)return pn(r)?vn(r,"completed"):{text:`Error: Session ${r.name} [${dt(r)}] is not running (status: ${r.status}). Cannot send a message to a non-running session.`,isError:!0};if(n.status!=="running")return pn(n)?vn(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=D.maxAutoResponds??jm;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 m=Ni(n);if(m)return{text:m,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let y=le(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${y}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let m=le(e.message,80);return{text:[`Pending input answered for session ${n.name} [${n.id}].`,` Message: "${m}"`,"Use agent_output to see the response."].join(`
100
- `)}}let d=!1;e.interrupt&&(d=await n.interrupt());let u=!!(e.approve&&Dr(n)),c=u?vl(e.approvalRationale):void 0,p="";if(e.approve&&Dr(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=c):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?p=`
99
+ `;function bd(t){let e=t?.replace(/\s+/g," ").trim();if(e)return de(e,240)}function Bi(t){if(t.approvalState==="changes_requested"&&!Wr(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 Wr(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function ef(t){return Bi(t)?!1:Wr(t)||t.currentPermissionMode==="plan"}function tf(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 nf(t){return(t.planDecisionVersion??0)+1}function Rd(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:nf(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 Ad(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function qi(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=Rd(o,"rejected");return n?(Ad(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 Ki(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=Rd(o,"changes_requested");n&&Ad(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function rf(t,e,n,r={}){let o=hn(e);if(!(o.kind==="resume"||wd(e)))return;let s=!!(r.approve&&ef(e)),a=s?bd(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?Pd(t,e,n):Pn(e,o.reason);let d={prompt:s?Xm+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:Ym(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",`agent-respond-plan-approved-resumed:${l.id}:${l.startedAt}:${o.resumeSessionId}:v${e.planDecisionVersion??"unknown"}`),{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`,"notification",`agent-respond-auto-resumed:${l.id}:${l.startedAt}:${o.resumeSessionId}`),{text:`Auto-resumed session ${l.name} [${l.id}]. Use agent_output to see the response.`})}catch(d){return Pn(e,"missing_backend_state",`Backend resume failed: ${Fi(d)}`)}}async function Pe(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"}:hn(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?Zm(e.message):void 0;if(s==="approve")return Pe(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return Ki(t,n?.id??r?.sessionId??e.session);if(s==="reject")return qi(t,n?.id??r?.sessionId??e.session);if(e.approve){let d=Bi(o);if(d)return{text:d,isError:!0}}if(i.kind==="resume"||wd(o)){let d=await rf(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(d)return d}else{if(i.kind==="relaunch")return Pd(t,o,e.message);if(i.kind==="unavailable")return Pn(o,i.reason)}if(!n)return gn(r)?Pn(r,"completed"):{text:`Error: Session ${r.name} [${pt(r)}] is not running (status: ${r.status}). Cannot send a message to a non-running session.`,isError:!0};if(n.status!=="running")return gn(n)?Pn(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??Jm;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 m=Bi(n);if(m)return{text:m,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let y=de(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${y}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let m=de(e.message,80);return{text:[`Pending input answered for session ${n.name} [${n.id}].`,` Message: "${m}"`,"Use agent_output to see the response."].join(`
100
+ `)}}let l=!1;e.interrupt&&(l=await n.interrupt());let u=!!(e.approve&&Wr(n)),c=u?bd(e.approvalRationale):void 0,p="";if(e.approve&&Wr(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=c):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?p=`
101
101
  ℹ️ approve=true was set but session is already in bypassPermissions mode.`:e.approve?p=`
102
102
  ⚠️ approve=true was set but session has no pending plan approval.`:(n.pendingPlanApproval||n.approvalState==="changes_requested")&&(p=`
103
- ℹ️ 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&&Ym(t,n),u)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let m=le(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${m}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let f=le(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}].`,d?" (redirected active turn first)":e.interrupt?" (no active turn to interrupt)":"",` Message: "${f}"`,p,"Use agent_output to see the response."].filter(Boolean).join(`
104
- `)}}catch(l){return{text:`Error sending message to session ${n.name} [${n.id}]: ${Li(l)}`,isError:!0}}}function ef(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 bl(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:g.Object({session:g.String({description:"Session name or ID to respond to"}),message:g.String({description:"The message to send to the session"}),interrupt:g.Optional(g.Boolean({description:"If true, interrupt the current turn before sending the message. Useful to redirect the session mid-response."})),userInitiated:g.Optional(g.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:g.Optional(g.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:g.Optional(g.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(!ef(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, message, interrupt?, userInitiated?, approve?, approval_rationale? }."}]};let r=await we(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}]}}}}re();F();function tf(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Rl(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:g.Object({session:g.String({description:"Session name or ID awaiting plan approval"}),summary:g.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(!tf(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}]}}}}re();F();function nf(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Al(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:g.Object({session:g.String({description:"Delegated session name or ID awaiting a worktree decision"}),summary:g.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(!nf(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}]}}}}re();F();ae();var qi=["off","manual","ask","delegate","auto-merge","auto-pr"],Or=new Set(qi),rf=["pr-required","pr-allowed","never-pr","manual"],Il=new Set(rf),of=["low","medium","high","xhigh","max"],xl=new Set(of);function sf(t){return typeof t=="string"&&Or.has(t)}var af=g.Union(qi.map(t=>g.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 lf(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||sf(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 df(t,e){let n=St(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 uf(t,e){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=df(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 Tl(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:g.Object({offer_id:g.String({description:"Stable offer identifier, for example 'plugin-readiness-v2026.5.5'."}),offer_text:g.String({description:"Final user-facing text to deliver."}),plan_prompt:g.String({description:"Prompt to seed into the plan-only session when the user clicks Start Plan."}),plan_workdir:g.String({description:"Working directory for the planning session."}),plan_worktree_strategy:g.Optional(af),plan_name:g.Optional(g.String({description:"Optional explicit session name for the planning session."})),target_channel:g.Optional(g.String({description:"Optional explicit route like 'telegram|<chat-id>'."})),target_thread_id:g.Optional(g.Union([g.String(),g.Number()],{description:"Optional explicit topic/thread id."})),target_session_key:g.Optional(g.String({description:"Optional explicit session key for wake routing."}))}),async execute(e,n){return lf(n)?uf(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}re();F();function Cl(t){return{name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics: session counts by status, average duration, and notable sessions.",parameters:g.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:lr(r,o)}]}}}}re();F();Ot();import{execFileSync as cf}from"child_process";var Ui=[{policy:"pr-required",label:"Require PR",title:"Require PR",description:"Direct merge is disabled; follow-through must use a pull request."},{policy:"pr-allowed",label:"Merge or PR",title:"Merge or PR",description:"Use the requested strategy; direct merge and pull requests are both allowed."},{policy:"never-pr",label:"No PR",title:"No PR",description:"Do not create pull requests; keep follow-through local/direct."},{policy:"manual",label:"Manual",title:"Manual",description:"Create isolated worktrees, but require an explicit human follow-up decision every time."}],pf=new Map(Ui.map(t=>[t.policy,t]));function wn(t){return t?Ui:Ui.filter(e=>e.policy==="never-pr"||e.policy==="manual")}function Ml(t){return pf.get(t)??{policy:t,label:t,title:t,description:"Custom repo integration policy."}}function Lt(t,e){if(!(e||t!=="pr-required"&&t!=="pr-allowed"))return`Policy ${t} requires PR automation, but no supported PR provider is available. Choose never-pr or manual.`}function Vi(t){let{policy:e,prAvailable:n}=t;return{merge:e!=="pr-required"&&e!=="manual",pr:e!=="never-pr"&&e!=="manual"&&n}}function Ki(t,e){try{return cf("git",e,{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function _l(t){if(!t)return;let e=t.trim().replace(/\/+$/,"").replace(/\.git$/i,""),n=e.match(/^git@([^:]+):(.+)$/);if(n)return`https://${n[1].toLowerCase()}/${n[2].toLowerCase()}`;let r=e.match(/^https?:\/\/([^/]+)\/(.+)$/i);return r?`https://${r[1].toLowerCase()}/${r[2].toLowerCase()}`:e.toLowerCase()}function mf(t){return _l(t)?.startsWith("https://github.com/")?"github":"unsupported"}function Pn(t){let e=Ki(t,["rev-parse","--show-toplevel"]);if(!e)return;let n=Ki(e,["remote","get-url","origin"])??Ki(e,["remote","get-url","upstream"]),r=_l(n),o=mf(r);return{key:r?`${e}|${r}`:e,repoRoot:e,remoteUrl:r,provider:o}}function $l(t){if(t?.remoteUrl)return t.remoteUrl==="https://github.com/goldmar/openclaw-code-agent"?"pr-required":void 0}function Gi(t,e,n="stored",r=new Date().toISOString()){return{key:t.key,policy:e,repoRoot:t.repoRoot,remoteUrl:t.remoteUrl,provider:t.provider,createdAt:r,updatedAt:r,source:n}}function ji(t){return t.provider==="github"&&Te()}function El(t){let e=t.requestedStrategy,n=Vi(t);return!e||e==="off"||e==="manual"?{allowedActions:n}:t.policy?t.policy==="manual"?{strategy:e==="delegate"?"delegate":"ask",reason:"Repo policy requires manual follow-through.",allowedActions:{merge:!1,pr:!1}}:t.policy==="pr-required"?e==="auto-merge"?t.prAvailable?{strategy:"auto-pr",reason:"Repo policy requires a PR; auto-merge was downgraded to auto-pr.",allowedActions:n}:{strategy:"ask",blocked:!0,reason:"Repo policy requires a PR, but no supported PR provider is available.",allowedActions:n}:e==="auto-pr"?t.prAvailable?{strategy:"auto-pr",allowedActions:n}:{strategy:"ask",blocked:!0,reason:"Repo policy requires a PR, but no supported PR provider is available.",allowedActions:n}:{strategy:e,allowedActions:n}:t.policy==="never-pr"?e==="auto-pr"?t.existingOpenPr&&t.prAvailable?{strategy:"auto-pr",reason:"Repo policy forbids new PR creation; updating the existing open PR is allowed.",allowedActions:n}:{strategy:"ask",reason:"Repo policy forbids PR creation; auto-pr was downgraded to an explicit worktree decision.",allowedActions:n}:{strategy:e,allowedActions:n}:e==="auto-pr"&&!t.prAvailable?{strategy:"ask",reason:"No supported PR provider is available; auto-pr was downgraded to an explicit worktree decision.",allowedActions:n}:{strategy:e,allowedActions:n}:{strategy:e==="auto-merge"||e==="auto-pr"?"ask":e,blocked:!0,reason:"Repo integration policy is unknown.",allowedActions:{merge:!1,pr:!1}}}function Hi(t,e,n=t.provider==="github"){let r=wn(n);return[`Repo integration policy is not set for ${t.repoRoot}.`,"","OCA will create isolated worktrees, but it needs one repo policy before worktree follow-through can run.",`Requested worktree strategy: ${e}`,`Provider: ${t.provider}${n?"":" (PR automation unavailable)"}`,"","Choose one available policy:",...r.map(o=>`- ${o.title}: ${o.description}`),"","If buttons are unavailable, set it manually. OCA will continue the pending launch automatically when exactly one matching launch is waiting; otherwise run the intended launch again:",...r.map(o=>`- agent_repo_policy(workdir="${t.repoRoot}", policy="${o.policy}")`)].join(`
105
- `)}function ff(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function bn(t){return t?[`Repo policy: ${t.policy}`,`Repo: ${t.repoRoot}`,`Provider: ${t.provider}`,...t.remoteUrl?[`Remote: ${t.remoteUrl}`]:[],`Updated: ${t.updatedAt}`].join(`
106
- `):"No stored repo policy found."}function Dl(t){return{name:"agent_repo_policy",description:"Inspect or set the repository integration policy that governs OCA worktree merge/PR follow-through.",parameters:g.Object({workdir:g.Optional(g.String({description:"Repository workdir. Defaults to the current workspace directory."})),policy:g.Optional(g.Union([g.Literal("pr-required"),g.Literal("pr-allowed"),g.Literal("never-pr"),g.Literal("manual")],{description:"Policy to set for this repo."})),reset:g.Optional(g.Boolean({description:"Remove the stored policy for this repo."})),list:g.Optional(g.Boolean({description:"List all stored repo policies."})),cleanup:g.Optional(g.Boolean({description:"Remove stored repo policies whose repoRoot no longer exists on disk."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=n&&typeof n=="object"?n:{};if(r.cleanup===!0){let a=v.cleanupRepoPolicies();return{content:[{type:"text",text:a.length===0?"No stale repo policies found.":[`Removed ${a.length} stale repo ${a.length===1?"policy":"policies"}.`,...a.map(d=>`${d.policy} | ${d.provider} | ${d.repoRoot}`)].join(`
107
- `)}]}}if(r.list===!0){let a=v.listRepoPolicies();return{content:[{type:"text",text:a.length===0?"No stored repo policies.":a.map(d=>`${d.policy} | ${d.provider} | ${d.repoRoot}${d.remoteUrl?` | ${d.remoteUrl}`:""}`).join(`
108
- `)}]}}let o=r.workdir??t?.workspaceDir;if(!o)return{content:[{type:"text",text:"Error: workdir is required when no workspace directory is available."}]};if(r.reset===!0)return{content:[{type:"text",text:v.resetRepoPolicy(o)?`Repo policy reset for ${o}.`:`No stored repo policy found for ${o}.`}]};if(r.policy!==void 0){if(!ff(r.policy))return{content:[{type:"text",text:"Error: policy must be one of pr-required, pr-allowed, never-pr, manual."}]};if(typeof v.resolveRepoPolicy=="function"){let d=v.resolveRepoPolicy(o);if(d.identity){let u=Lt(r.policy,d.prAvailable);if(u)return{content:[{type:"text",text:`Error: ${u}`}]}}}let a=v.setRepoPolicy(o,r.policy);if(!a)return{content:[{type:"text",text:`Error: ${o} is not a git repository.`}]};let l;try{l=typeof v.continueLaunchAfterManualRepoPolicy=="function"?v.continueLaunchAfterManualRepoPolicy(a.repoRoot,r.policy):{kind:"none"}}catch(d){let u=d instanceof Error?d.message:String(d);return{content:[{type:"text",text:[bn(a),"",`Repo policy saved, but the deferred launch failed: ${u}`,"The pending launch context was kept so you can retry the same agent_repo_policy call or run the intended launch again."].join(`
109
- `)}]}}return l.kind==="launched"?{content:[{type:"text",text:[bn(a),"",l.text].join(`
110
- `)}]}:l.kind==="ambiguous"?{content:[{type:"text",text:[bn(a),"",`Repo policy saved, but ${l.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
111
- `)}]}:{content:[{type:"text",text:bn(a)}]}}let i=v.resolveRepoPolicy(o);if(!i.identity)return{content:[{type:"text",text:`No git repository found for ${o}.`}]};let s=i.record;return s?{content:[{type:"text",text:bn(s)}]}:{content:[{type:"text",text:["Repo policy: unknown",`Repo: ${i.identity.repoRoot}`,`Provider: ${i.provider}${i.prAvailable?"":" (PR automation unavailable)"}`,...i.identity.remoteUrl?[`Remote: ${i.identity.remoteUrl}`]:[]].join(`
112
- `)}]}}}}re();ae();F();ke();Rn();In();import{existsSync as Kr}from"fs";function hf(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function yf(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 kf(t){return t.deleteBranchRequested?t.branchDeleted&&t.worktreeCleanedUp&&!t.worktreeAlreadyAbsent?{detailLine:"Branch and worktree cleaned up.",summaryFragment:" Branch and worktree cleaned up."}:t.branchDeleted&&t.worktreeAlreadyAbsent?{detailLine:"Branch deleted; worktree was already absent.",summaryFragment:" Branch deleted; worktree was already absent."}:t.branchDeleted?{detailLine:"Branch deleted; worktree cleanup failed.",summaryFragment:" Branch deleted; worktree cleanup failed."}:t.worktreeAlreadyAbsent?{detailLine:"Worktree was already absent; branch deletion failed.",summaryFragment:" Worktree was already absent; branch deletion failed."}:t.worktreeCleanedUp?{detailLine:"Worktree cleaned up; branch deletion failed.",summaryFragment:" Worktree cleaned up; branch deletion failed."}:{detailLine:"Branch deletion and worktree cleanup failed.",summaryFragment:" Branch deletion and worktree cleanup failed."}:t.worktreeCleanedUp&&!t.worktreeAlreadyAbsent?{detailLine:"Worktree cleaned up; branch deletion was not requested.",summaryFragment:" Worktree cleaned up; branch kept."}:t.worktreeAlreadyAbsent?{detailLine:"Worktree was already absent; branch deletion was not requested.",summaryFragment:" Worktree was already absent; branch kept."}:{detailLine:"Worktree cleanup failed; branch deletion was not requested.",summaryFragment:" Worktree cleanup failed; branch kept."}}function Ur(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:g.Object({session:g.String({description:"Session name or ID to merge"}),base_branch:g.Optional(g.String({description:"Base branch to merge into (default: main)"})),strategy:g.Optional(g.Union([g.Literal("merge"),g.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:g.Optional(g.Boolean({description:"Push the base branch after successful merge (default: false)"})),delete_branch:g.Optional(g.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(!hf(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:l}=r;if(!s||!a)return{content:[{type:"text",text:`Error: Session "${n.session}" does not have a worktree.`}]};if(!l)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.`}]};Kr(s)||`${s}${a}`;let d=a;if(!Kr(a))return{content:[{type:"text",text:`Error: originalWorkdir "${a}" does not exist.`}]};let u=n.base_branch??_e(d),c=u,p=n.strategy??"merge",f=n.push===!0,m=n.delete_branch!==!1,y=v.resolveRepoPolicy(d);if(y?.policy==="pr-required")return{content:[{type:"text",text:`❌ Merge blocked: repo policy requires a pull request for ${y.identity?.repoRoot??d}. Use agent_pr if PR automation is available.`}]};if(i?.worktreeLifecycle?.state==="merged"||i?.worktreeMerged)return{content:[{type:"text",text:`ℹ️ Session "${n.session}" is already merged.`}]};if((Kr(s)?yn(d,l,c):void 0)===0&&at(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${l} 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(`
113
- `)}]};let S={content:[{type:"text",text:"❌ Merge did not run (internal error)"}]};return await v.enqueueMerge(d,async()=>{let b=v.getPersistedSession(n.session);if(b?.worktreeLifecycle?.state==="merged"||b?.worktreeMerged){S={content:[{type:"text",text:`ℹ️ Session "${n.session}" was already merged while waiting in queue.`}]};return}let A=Le(d,l,u),x=Ir(d,l,c,p,s),R=Nt(x);if(x.success){let h=yf({mergeResult:x,repoDir:d,baseBranch:c});if(f&&!Ar(d,c)){let N=`⚠️ Merged ${l} → ${c} locally, but failed to push ${c}`;v.notifyWorktreeOutcome(r.notificationTarget,N,{detailLines:[`Branch ${l} 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.",...h,...R]}),S={content:[{type:"text",text:$e(N,x)}]};return}let w=!1,L=!1,ne=!Kr(s);L=ne?!0:pe(d,s),br(d),m&&(w=ye(d,l));let $=kf({deleteBranchRequested:m,branchDeleted:w,worktreeCleanedUp:L,worktreeAlreadyAbsent:ne});if(b){let N=new Date().toISOString();for(let V of An({...r,persistedSession:b}))v.updatePersistedSession(V,{...Bt({worktreeBaseBranch:u,worktreePrTargetRepo:b.worktreePrTargetRepo,worktreePushRemote:b.worktreePushRemote},{mergedAt:N,updatedAt:N,resolvedAt:N,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let T=lt({kind:"merge",branch:l,base:u,filesChanged:A?.filesChanged,insertions:A?.insertions,deletions:A?.deletions});v.notifyWorktreeOutcome(r.notificationTarget,T,{detailLines:[x.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",f?`Pushed ${c}.`:`Did not push ${c}; push was not requested.`,$.detailLine,...h,...R]});let j=`✅ ${x.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${l} → ${c}.${f?" Pushed.":""}${$.summaryFragment}`;x.stashPopConflict?j+=`
114
- ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${x.stashRef??"stash@{0}"}\` in ${d} to review stashed changes.`:x.stashed&&(j+=`
115
- (Pre-existing changes on ${c} were auto-stashed and restored.)`),j=$e(j,x),S={content:[{type:"text",text:j}]}}else if(x.rebaseConflict)S={content:[{type:"text",text:$e(`⚠️ Rebase conflicts — manual resolution required:
116
-
117
- ${x.error}`,x)}]};else if(x.conflictFiles&&x.conflictFiles.length>0){let h=["Resolve merge conflicts in the following files and commit the resolution:","",...x.conflictFiles.map(w=>`- ${w}`),"",`After resolving, commit with message: "Resolve merge conflicts from ${l}"`].join(`
118
- `);try{let w=v.spawn({prompt:h,workdir:d,name:`${n.session}-conflict-resolver`,harness:de(),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});S={content:[{type:"text",text:$e(`⚠️ Merge conflicts in ${x.conflictFiles.length} file(s) — spawned conflict resolver session: ${w.name}`,x)}]}}catch(w){S={content:[{type:"text",text:$e(`❌ Merge conflicts detected, but failed to spawn resolver: ${w instanceof Error?w.message:String(w)}`,x)}]}}}else{let h=x.dirtyError?`❌ Merge blocked: ${x.error}`:`❌ Merge failed: ${x.error??"unknown error"}`;S={content:[{type:"text",text:$e(h,x)}]}}}),S}}}zr();re();F();X();ke();In();function If(t){return!!t&&typeof t=="object"}function Ul(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:g.Object({workdir:g.Optional(g.String({description:"Restrict cleanup to sessions rooted in this repository"})),base_branch:g.Optional(g.String({description:"Override base branch for lifecycle resolution"})),mode:g.Optional(g.Union([g.Literal("preview_safe"),g.Literal("clean_safe"),g.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:g.Optional(g.Boolean({description:"Deprecated. Safe cleanup never removes live sessions."})),force:g.Optional(g.Boolean({description:"Deprecated alias for skip_session_check."})),dry_run:g.Optional(g.Boolean({description:"Show what would be cleaned without deleting anything."})),session:g.Optional(g.String({description:"Session name or ID to clean or dismiss."})),dismiss_session:g.Optional(g.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(!If(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=Br(v);if(r&&(a=a.filter(f=>Fr(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 l=[],d=[],u=[],c=[];for(let f of a){let{persistedSession:m,activeSession:y,resolvedLifecycle:k}=Lr(v,f,{baseBranch:n.base_branch});if(!k.cleanupSafe){if(s){let S=k.reasons.length>0?k.reasons.map(qr).join(", "):ut(k.derivedState);d.push(`${f.name} [kept: ${S}]`)}continue}if(l.push(`${f.name} (${ut(k.derivedState)})`),!i)try{let S=f.workdir;if(!((m??y)&&ue(m??y))&&f.worktreePath&&pe(S,f.worktreePath,{destructive:!1}),f.worktreeBranch&&ye(S,f.worktreeBranch),m){let A=k.derivedState==="merged"||k.derivedState==="released"?k.derivedState:k.lifecycle.state,x=new Date().toISOString(),R=A==="merged"?m.worktreeMergedAt:A==="dismissed"?m.worktreeDismissedAt:void 0;v.updatePersistedSession(f.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeMerged:A==="merged"?!0:m.worktreeMerged,worktreeMergedAt:A==="merged"?m.worktreeMergedAt??x:m.worktreeMergedAt,worktreeLifecycle:{...m.worktreeLifecycle??k.lifecycle,state:A,updatedAt:x,resolvedAt:m.worktreeLifecycle?.resolvedAt??R??x,resolutionSource:m.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??k.lifecycle.baseBranch??m.worktreeBaseBranch,targetRepo:m.worktreePrTargetRepo,pushRemote:m.worktreePushRemote,notes:k.reasons}})}u.push(`${f.name} (${ut(k.derivedState)})`)}catch(S){c.push(`${f.name}: ${S instanceof Error?S.message:String(S)}`)}}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"} (${l.length}): ${l.join(", ")||"(none)"}`),s&&p.push(` KEPT (${d.length}): ${d.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(`
119
- `)}]}}}}re();F();In();function xf(t){if(t==null)return!0;if(Array.isArray(t)||typeof t!="object")return!1;let e=t.session;return e===void 0||typeof e=="string"}function Vl(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:g.Object({session:g.Optional(g.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(!xf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n&&typeof n=="object"?n.session:void 0,o=Br(v);if(r&&(o=o.filter(s=>Fr(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:l}=Lr(v,s),d=l.cleanupSafe?"safe now":l.preserve?"preserve":"blocked";i.push(`Session: ${s.name} [${s.id}]`),i.push(` Branch: ${s.worktreeBranch??"(unknown)"} → ${l.lifecycle.baseBranch??a?.worktreeBaseBranch??"main"}`),i.push(` Repo: ${s.workdir}`),i.push(` Lifecycle:${ut(l.lifecycle.state)}`),l.derivedState!==l.lifecycle.state&&i.push(` Derived: ${ut(l.derivedState)}`),i.push(` Cleanup: ${d}`),l.evidence.prUrl&&i.push(` PR: ${l.evidence.prUrl} (${l.evidence.prState??"unknown"})`),(l.evidence.branchAheadCount!=null||l.evidence.baseAheadCount!=null)&&i.push(` Ahead: ${l.evidence.branchAheadCount??0} ahead / ${l.evidence.baseAheadCount??0} behind`),i.push(` Reasons: ${l.reasons.length>0?l.reasons.map(qr).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
120
- `).trim()}]}}}}re();F();ae();Zn();import{existsSync as Tf}from"fs";function Cf(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function Qr(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||D.defaultWorkdir||process.cwd();if(!Tf(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=Cf(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??de(),a=t.model??yt(s),l=We(s,a),d=Fn(s);if(!l&&(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(l&&!It(s,l))return{kind:"error",text:`Error: Model "${a}" is not supported for harness "${s}". Use a bare Codex model id such as "gpt-5.5".`};if(l&&!Jn(s,l,d))return{kind:"error",text:`Error: Model "${a}" is not allowed. Permitted models: ${d?.join(", ")}`};let u=Yn(s,l,d),c=e.sessionKey||void 0,p=qn(e),f=rn(e,p||tt(r)),m=St(e,f,c);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:u,reasoningEffort:je(s),fastMode:kt(s),systemPrompt:t.systemPrompt,allowedTools:t.allowedTools,maxIterations:t.maxIterations,permissionMode:t.permissionMode??"bypassPermissions",harness:s,loopMode:i,completionPromise:t.completionPromise,originChannel:f,originThreadId:m?.threadId,originAgentId:e.agentId||void 0,originSessionKey:c,route:m,verifierCommands:o}}function Jr(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(`
121
- `)}function Mf(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function Gl(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:g.Object({goal:g.String({description:"End goal for the autonomous task"}),verifier_commands:g.Optional(g.Array(g.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:g.Optional(g.String({description:"Short task name (kebab-case preferred)"})),workdir:g.Optional(g.String({description:"Working directory (defaults to cwd / configured workspace)"})),model:g.Optional(g.String({description:"Model name to use"})),system_prompt:g.Optional(g.String({description:"Additional system prompt"})),allowed_tools:g.Optional(g.Array(g.String(),{description:"Allowed tools for the underlying agent session"})),max_iterations:g.Optional(g.Number({description:"Maximum verifier-driven repair iterations",minimum:1})),goal_mode:g.Optional(g.Union([g.Literal("ralph"),g.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:g.Optional(g.String({description:"Exact completion promise for Ralph-mode loops. Defaults to 'DONE'."})),permission_mode:g.Optional(g.Union([g.Literal("default"),g.Literal("plan"),g.Literal("bypassPermissions")],{description:"Permission mode for the underlying agent session. Defaults to bypassPermissions for autonomous goal loops."})),harness:g.Optional(g.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode')."}))}),async execute(e,n){if(!z)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!Mf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=Qr({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 z.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:Jr(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}re();function Xi(t,e){return t.split(`
122
- `).map(n=>`${e}${n}`)}function jl(t,e){return t.length<=e?t:`${t.slice(0,e-3).trimEnd()}...`}function _f(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(`
123
- `);return o.length<=n?o:`...${o.slice(-(n-3))}`}function $f(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=>jl(o,180))}function Ef(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=>jl(n,180))}function Yr(t){let e=[],n=Ef(t.verifierSummary),r=$f(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(`
124
- `)}function es(t){if(t)return{phase:t.phase,awaitingInput:t.isAwaitingInput??!!t.pendingInputState,latestOutput:_f(t.getOutput(20))}}function ts(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(...Xi(n," ")),t.lastVerifierSummary&&(o.push(" Last verifier:"),o.push(...Xi(t.lastVerifierSummary," "))),e?.latestOutput&&(o.push(" Latest activity:"),o.push(...Xi(e.latestOutput," "))),t.waitingForUserReason&&o.push(` Waiting on user: ${t.waitingForUserReason}`),t.failureReason&&o.push(` Failure: ${t.failureReason}`),o.join(`
125
- `)}var Pe="Error: GoalController not initialized. The code-agent service must be running.";function Zr(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 ts(i,es(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 ts(i,es(s))}).join(`
126
-
127
- `)}function Xr(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 eo(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.`}}F();function Hl(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:g.Object({task:g.Optional(g.String({description:"Task name or ID. Omit to list all tasks."}))}),async execute(e,n){if(!z)return{content:[{type:"text",text:Pe}]};let r=n&&typeof n=="object"&&typeof n.task=="string"?n.task:void 0;return{content:[{type:"text",text:Zr(z,o=>v?.resolve(o),r)}]}}}}re();F();function Df(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function zl(t){return{name:"goal_stop",description:"Stop an explicit goal task and kill its underlying agent session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"})}),async execute(e,n){if(!z)return{content:[{type:"text",text:Pe}]};if(!Df(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=z.stopTask(n.task);return{content:[{type:"text",text:Xr(r,n.task)}]}}}}re();F();function Of(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function Ql(t){return{name:"goal_edit",description:"Edit the goal text for an active goal task without stopping or relaunching its session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"}),goal:g.String({description:"Replacement goal text"})}),async execute(e,n){if(!z)return{content:[{type:"text",text:Pe}]};if(!Of(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=z.editTask(n.task,n.goal);return{content:[{type:"text",text:eo(r,n.task)}]}}}}F();zr();import{createHash as Wf}from"crypto";var ee="code-agent";var Nf=new Set(["1","true","yes","on"]);function rs(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&Nf.has(t))}function be(t){if(!(typeof t!="string"||t.length===0))return Wf("sha256").update(t).digest("hex").slice(0,12)}function Jl(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function J(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=Jl(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>be(Jl(r))):void 0,buttonStyles:n.length>0?n.map(r=>typeof r.style=="string"?r.style:void 0):void 0}}function Ye(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Zl(t){let e=Ye(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(n)return n.map(r=>Ye(r)?.type).filter(r=>typeof r=="string"&&r.length>0)}function Xl(t){let e=Ye(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(!n)return;let r=n.map(o=>{let i=Ye(o);return i?.type!=="buttons"||!Array.isArray(i.buttons)?[]:i.buttons}).filter(o=>o.length>0);return r.length>0?r:void 0}function os(t){let e=Xl(t);return{presentationBlockTypes:Zl(t),...J(e)}}function is(t){let e=Ye(t),n=e?.interactive,r=Ye(e?.channelData),o=Ye(r?.telegram),i=Array.isArray(o?.buttons)?o.buttons:void 0;return{renderedPayloadKeys:e?Object.keys(e).sort():void 0,interactiveBlockTypes:Zl(n),...Yl("interactive",J(Xl(n))),...Yl("telegramChannelData",J(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function ed(t){let e=Ye(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:ns(e.messageId),chatId:ns(e.chatId),telegramThreadId:ns(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function ns(t){return typeof t=="string"||typeof t=="number"?t:void 0}function Yl(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 B(t,e){if(!rs())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:ee,...n})}`}var ss=new Set,td="⚠️ Could not submit that answer. The question prompt is still active; try again or reply with the answer.",Mn=new Map;async function id(t){try{await t}catch(e){let n=e instanceof Error?e.message:String(e);`${n}`}}async function nd(t,e,n){if(!t)return n();for(;;){let o=Mn.get(t)?.operation;if(!o)break;await id(o)}let r=Promise.resolve().then(n);Mn.set(t,{operation:r,tokenId:e});try{return await r}finally{Mn.get(t)?.operation===r&&Mn.delete(t)}}function Lf(t){let e=t.trim().replace(new RegExp(`^${ee}:`),"");return e||null}function Bf(t){return t.trim().startsWith(`${ee}:`)}async function to(t,e=!1){if(t.channel==="telegram")try{return(await Z(t,{alreadyAcknowledged:e,forceTelegramMarkupEdit:!0})).textDelivered}catch(r){let o=r instanceof Error?r.message:String(r);return`${o}`,!1}let n=t.respond;if(typeof n.clearComponents=="function")try{return await n.clearComponents(),!1}catch(r){if(pt(r))return!1;let o=r instanceof Error?r.message:String(r);`${o}`}if(typeof n.clearButtons=="function")try{await n.clearButtons()}catch(r){let o=r instanceof Error?r.message:String(r);`${o}`}else!e&&typeof n.acknowledge=="function"&&await n.acknowledge();return!1}async function qe(t,e=!1){await Z(t,{alreadyAcknowledged:e,forceTelegramMarkupEdit:t.channel==="telegram"})}function ro(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 rd(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return ds(ro(t))}function ds(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function oo(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function Ff(t){if(oo(t.kind))return`${t.sessionId}:v${t.planDecisionVersion??"unknown"}`}function qf(t){return t?t.approvalState==="approved"||!t.pendingPlanApproval:!1}function Kf(...t){let e;for(let n of t)n!=null&&(e=e==null?n:Math.max(e,n));return e}function Uf(t){if(t.actionablePlanDecisionVersion!=null)return t.actionablePlanDecisionVersion;let e=Kf(t.approvalPromptRequiredVersion,t.approvalPromptVersion);return e??t.canonicalPlanPromptVersion??t.planDecisionVersion}function as(t,e){if(!oo(t.kind))return;if(!e)return"This plan decision is stale because the session is no longer available.";let n=Uf(e);if(t.planDecisionVersion!=null&&n!=null&&t.planDecisionVersion!==n)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 sd(t,...e){return e.find(n=>typeof n=="string"&&t(n))}function no(...t){return sd(e=>e.trim().length>0,...t)}function od(...t){return sd(Bf,...t)}function Vf(t){let e="callback"in t?od(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0;if(e)return e;let n="interaction"in t?t.interaction:void 0,r=od(n?.data,n?.callback_data,n?.callbackData);if(r)return r;let o="callback"in t?no(t.callback?.payload):void 0;if(o)return o;let i=no(n?.payload);return i||(("callback"in t?no(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0)??no(n?.data,n?.callback_data,n?.callbackData)??"")}function _n(t,e=new Set){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean"||typeof t=="bigint")return String(t);if(t instanceof Error)return[t.name,t.message,_n(t.cause,e)].filter(Boolean).join(" ");if(typeof t!="object")return String(t);if(e.has(t))return"";e.add(t);let n=t;return[n.message,n.description,n.error,n.error_description,_n(n.cause,e),_n(n.response,e),_n(n.payload,e)].filter(Boolean).join(" ")}function pt(t){return/message is not modified/i.test(_n(t))}function Gf(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function ct(t){if(typeof t.clearButtons=="function")try{await t.clearButtons()}catch(e){if(pt(e))return;throw e}}async function Z(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:[]}),await ct(n),{textDelivered:!0}}catch(a){if(pt(a))return await ct(n),{textDelivered:!0};let l=a instanceof Error?a.message:String(a);`${l}`}if(o&&typeof n.editButtons=="function")try{return await n.editButtons({buttons:[]}),await ct(n),{textDelivered:!1}}catch(a){if(pt(a))return await ct(n),{textDelivered:!1};let l=a instanceof Error?a.message:String(a);`${l}`}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:[]}),await ct(n),{textDelivered:!1}}catch(a){if(pt(a))return await ct(n),{textDelivered:!1};let l=a instanceof Error?a.message:String(a);`${l}`}return await ct(n),{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(pt(s))return{textDelivered:typeof i=="string"};if(Gf(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(pt(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 jf(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 O(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}var ls=["plan-approve","plan-request-changes","plan-reject"];function Hf(t){switch(t){case"plan-approve":return"Approve";case"plan-request-changes":return"Revise";case"plan-reject":return"Reject";default:return"Continue"}}function zf(t){switch(t){case"plan-approve":return"primary";case"plan-reject":return"danger";default:return"secondary"}}function Qf(t,e){let n=t,o=(typeof n?.listActiveActionTokens=="function"?ls.flatMap(a=>n.listActiveActionTokens?.(a)??[]):[e]).filter(a=>oo(a.kind)&&a.sessionId===e.sessionId&&(e.planDecisionVersion==null||a.planDecisionVersion==null||a.planDecisionVersion===e.planDecisionVersion)).sort((a,l)=>ls.indexOf(a.kind)-ls.indexOf(l.kind)),i=new Set,s=o.filter(a=>i.has(a.kind)?!1:(i.add(a.kind),!0)).map(a=>({label:typeof a.label=="string"&&a.label.trim()?a.label:Hf(a.kind),callbackData:`${ee}:${a.id}`,style:zf(a.kind)}));return s.length>0?[s]:void 0}async function Jf(t,e,n,r){if(t.channel!=="telegram"){await O(t,e);return}let o=Qf(n,r);await t.respond.reply({text:o?`${e}
128
-
129
- Approval is still pending. Try again below.`:e,...o?{buttons:o}:{}})}function ad(t="telegram",e={}){let n=e.makeAgentMergeTool??Ur,r=e.makeAgentPrTool??Cn;return B("callback_handler_registered",{channel:t,namespace:ee}),{channel:t,namespace:ee,handler:async o=>{let i=await jf(o);if(!o.auth.isAuthorizedSender)return await O(o,"⛔ Unauthorized."),{handled:!0};let s=Vf(o),a=Lf(s);if(B("callback_received",{channel:o.channel,namespace:ee,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:be(a),isAuthorizedSender:o.auth.isAuthorizedSender}),!a)return await O(o,"⚠️ Unrecognized callback payload."),{handled:!0};if(!v)return await O(o,"⚠️ Code agent service not running."),{handled:!0};let l=v.getActionToken(a);if(B("callback_token_lookup_completed",{channel:o.channel,namespace:ee,tokenHash:be(a),tokenFound:!!l,actionKind:l?.kind,sessionId:l?.sessionId,planDecisionVersion:l?.planDecisionVersion}),!l)return await Z(o,{alreadyAcknowledged:i}),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(l.kind==="question-answer"&&l.consumedAt!=null)return await Z(o,{alreadyAcknowledged:i}),await O(o,"⚠️ That question button is no longer active. Use the latest question prompt."),{handled:!0};let d=l.sessionId,u=v.resolve?.(d)??v.getPersistedSession?.(d),c=u?.name??d,p=as(l,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:ee,tokenHash:be(a),actionKind:l.kind,sessionId:d,sessionName:c,planDecisionVersion:l.planDecisionVersion,valid:!p}),p)return oo(l.kind)?await qe(o,i):await Z(o,{alreadyAcknowledged:i}),await O(o,`⚠️ ${p}`),{handled:!0};if(l.kind==="question-answer"){if(l.optionIndex==null)return await Z(o,{alreadyAcknowledged:i}),await O(o,"⚠️ Invalid question-answer action."),{handled:!0};if(ss.has(a))return await O(o,"⚠️ That answer is already being submitted. If the question remains active, try again."),{handled:!0};ss.add(a);let y=!1;try{y=await v.resolvePendingInputOption(d,l.optionIndex,{requestId:l.pendingInputRequestId,questionId:l.pendingInputQuestionId})}catch(S){let b=S instanceof Error?S.message:String(S);return`${b}`,await O(o,td),{handled:!0}}finally{ss.delete(a)}if(!y)return await O(o,td),{handled:!0};let k=v.consumeActionToken(a);return B("callback_token_consume_completed",{channel:o.channel,namespace:ee,tokenHash:be(a),consumed:!!k,actionKind:k?.kind,sessionId:k?.sessionId,planDecisionVersion:k?.planDecisionVersion}),k?(await Z(o,{alreadyAcknowledged:i}),await O(o,"✅ Answer submitted."),{handled:!0}):(await Z(o,{alreadyAcknowledged:i}),await O(o,"✅ Answer submitted."),{handled:!0})}let f=Ff(l);if(f)for(;;){let y=Mn.get(f);if(!y)break;if(y.tokenId===a)return await qe(o,i),await O(o,"⚠️ This plan decision is already being processed."),{handled:!0};await id(y.operation);let k=v.getActionToken(a);if(!k)return await qe(o,i),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(d=k.sessionId,u=v.resolve?.(d)??v.getPersistedSession?.(d),c=u?.name??d,p=as(k,u),B("callback_plan_validation_completed",{channel:o.channel,namespace:ee,tokenHash:be(a),actionKind:k.kind,sessionId:d,sessionName:c,planDecisionVersion:k.planDecisionVersion,valid:!p,afterPlanDecisionLock:!0}),p)return await qe(o,i),await O(o,`⚠️ ${p}`),{handled:!0};l=k}if(l.kind==="plan-approve"){let y=l,k=!1,S=async(x=!1)=>{k||!x&&o.channel!=="telegram"||(await qe(o,i),k=!0)},b=await nd(f,a,async()=>(await S(),we(v,{session:y.sessionId,message:"Approved. Go ahead.",approve:!0,userInitiated:!0})));if(b.isError){let x=v.resolve?.(y.sessionId)??v.getPersistedSession?.(y.sessionId),R=qf(x);if(R){let h=v.consumeActionToken(a);B("callback_token_consume_completed",{channel:o.channel,namespace:ee,tokenHash:be(a),consumed:!!h,actionKind:h?.kind,sessionId:h?.sessionId??y.sessionId,planDecisionVersion:h?.planDecisionVersion,approvalAppliedAfterError:!0}),await S(!0)}return R?await O(o,`⚠️ ${b.text}`):await Jf(o,`⚠️ ${b.text}`,v,y),{handled:!0}}let A=v.consumeActionToken(a);return B("callback_token_consume_completed",{channel:o.channel,namespace:ee,tokenHash:be(a),consumed:!!A,actionKind:A?.kind,sessionId:A?.sessionId??y.sessionId,planDecisionVersion:A?.planDecisionVersion}),A?(await S(!0),{handled:!0}):(await S(!0),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0})}if(l.kind==="plan-reject"||l.kind==="plan-request-changes")return await nd(f,a,async()=>{let y=v.getActionToken(a);if(!y)return await qe(o,i),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};d=y.sessionId,u=v.resolve?.(d)??v.getPersistedSession?.(d),c=u?.name??d;let k=as(y,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:ee,tokenHash:be(a),actionKind:y.kind,sessionId:d,sessionName:c,planDecisionVersion:y.planDecisionVersion,valid:!k,afterPlanDecisionLock:!0}),k)return await qe(o,i),await O(o,`⚠️ ${k}`),{handled:!0};let S=v.consumeActionToken(a);if(B("callback_token_consume_completed",{channel:o.channel,namespace:ee,tokenHash:be(a),consumed:!!S,actionKind:S?.kind,sessionId:S?.sessionId,planDecisionVersion:S?.planDecisionVersion}),!S)return await qe(o,i),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(await qe(o,i),S.kind==="plan-reject"){let b=Bi(v,d);await O(o,`❌ ${b.text}`)}else{let b=Fi(v,d);await O(o,`✏️ ${b.text}`)}return{handled:!0}});let m=v.consumeActionToken(a);if(B("callback_token_consume_completed",{channel:o.channel,namespace:ee,tokenHash:be(a),consumed:!!m,actionKind:m?.kind,sessionId:m?.sessionId,planDecisionVersion:m?.planDecisionVersion}),!m)return await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:l.kind==="plan-offer-start"||l.kind==="plan-offer-dismiss"}),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};switch(m.kind){case"worktree-merge":{let y=await n().execute("callback",{session:d}),k=ro(y);if(rd(y)){await to(o,i);break}await O(o,k);break}case"worktree-decide-later":{let y=v.snoozeWorktreeDecision(d,{notifyUser:!1});if(ds(y)){let S=`⏭️ Snoozed 24h for [${c}]`;await to(o,i),await O(o,S)}else await O(o,y);break}case"worktree-dismiss":{let y=await v.dismissWorktree(d),k=ds(y);k&&await to(o,i),await O(o,k?"✅ Discarded":y);break}case"worktree-create-pr":case"worktree-update-pr":{let y=await r().execute("callback",{session:d}),k=ro(y);if(rd(y)){await to(o,i);break}await O(o,k);break}case"worktree-view-pr":{await Z(o,{alreadyAcknowledged:i});let y=v.getPersistedSession?.(d),k=l.targetUrl??y?.worktreePrUrl;await O(o,k?`PR: ${k}`:"⚠️ PR URL is no longer available.");break}case"plan-offer-start":{if(!m.launchPrompt||!m.launchWorkdir){await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"⚠️ This action is missing the plan launch context.");break}let y;try{y=v.launchPlanOffer({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,worktreeStrategy:m.launchWorktreeStrategy})}catch(k){let S=k instanceof Error?k.message:String(k);await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ Failed to start planning session: ${S}`);break}await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`▶️ Planning session started: ${y.name} [${y.id}]`);break}case"plan-offer-dismiss":{await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!m.repoPolicy||!m.repoPolicyWorkdir){await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"⚠️ This action is missing the repo policy context.");break}if(!m.launchPrompt||!m.launchWorkdir){await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"⚠️ This action is missing the launch context.");break}if(typeof v.resolveRepoPolicy=="function"){let S=v.resolveRepoPolicy(m.repoPolicyWorkdir);if(S.identity){let b=Lt(m.repoPolicy,S.prAvailable);if(b){await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ ${b}`);break}}}let y=v.setRepoPolicy(m.repoPolicyWorkdir,m.repoPolicy);if(!y){await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ Could not resolve a git repository for ${m.repoPolicyWorkdir}.`);break}v.clearRepoPolicyChoiceTokens(m.sessionId);let k;try{k=v.launchAfterRepoPolicyChoice({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,model:m.launchModel,reasoningEffort:m.launchReasoningEffort,fastMode:m.launchFastMode,systemPrompt:m.launchSystemPrompt,allowedTools:m.launchAllowedTools,resumeSessionId:m.launchResumeSessionId,resumeWorktreeFrom:m.launchResumeWorktreeFrom,sessionIdOverride:m.launchSessionIdOverride,clearedPersistedCodexResume:m.launchClearedPersistedCodexResume,forkSession:m.launchForkSession,forceNewSession:m.launchForceNewSession,permissionMode:m.launchPermissionMode,planApproval:m.launchPlanApproval,harness:m.launchHarness,worktreeStrategy:m.launchWorktreeStrategy,worktreeBaseBranch:m.launchWorktreeBaseBranch,worktreePrTargetRepo:m.launchWorktreePrTargetRepo,originAgentId:m.launchOriginAgentId}).text}catch(S){let b=S instanceof Error?S.message:String(S);await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ Repo policy saved, but launch failed: ${b}`);break}await Z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,[`✅ Repo policy saved: ${Ml(y.policy).title}.`,"",k].join(`
130
- `));break}case"session-restart":case"session-resume":{await Z(o,{alreadyAcknowledged:i});let y=await we(v,{session:d,message:"Continue where you left off.",userInitiated:!0});await O(o,y.isError?`⚠️ ${y.text}`:`▶️ ${y.text}`);break}case"view-output":{await Z(o,{alreadyAcknowledged:i});let y=await Er().execute("callback",{session:d,lines:50});await O(o,ro(y));break}default:{await Z(o,{alreadyAcknowledged:i}),await O(o,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}F();ae();function Kt(t){return ld(t).map(e=>e.value)}function ld(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:Yf(n),raw:n,start:r,end:r+n.length}})}function mt(t){let[e]=ld(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function Yf(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function Zf(t){return t instanceof Error?t.message:String(t)}function Xf(t){let e=Kt(t),n,r=e;return e[0]==="--name"&&e[1]&&(n=e[1],r=e.slice(2)),{name:n,prompt:r.join(" ").trim()}}function dd(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}=Xf(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=sr({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:cr(e)});return{text:v.formatLaunchResult({prompt:o,workdir:i.workdir,harness:i.harness,permissionMode:i.permissionMode??D.permissionMode,planApproval:i.planApproval},s)}}catch(i){let s=Zf(i),a=s.includes("Max sessions")?"":`
131
-
132
- Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${a}`}}}})}F();function ud(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:_r(v,"all",void 0,{full:n})}}})}F();function cd(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:$r(v,n,"killed")}:{text:"Usage: /agent_kill <name-or-id>"}}})}F();function pd(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>
133
- /agent_respond --interrupt <id-or-name> <message>`};let r=!1,o=n,i=mt(o);i?.value==="--interrupt"&&(r=!0,o=i.rest);let s=mt(o);if(!s)return{text:"Error: Missing message. Usage: /agent_respond <id-or-name> <message>"};let a=s.value,l=s.rest;return l.trim()?{text:(await we(v,{session:a,message:l,interrupt:r,userInitiated:!0})).text}:{text:"Error: Empty message. Usage: /agent_respond <id-or-name> <message>"}}})}F();function md(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:lr(e,n)}}})}F();function eg(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function fd(t){t.registerCommand({name:"agent_policy",description:"Inspect or set the current repo integration policy. Usage: /agent_policy [pr-required|pr-allowed|never-pr|manual|reset|list|cleanup]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let r=mt((e.args??"").trim())?.value;if(r==="list"){let a=v.listRepoPolicies();return{text:a.length===0?"No stored repo policies.":a.map(l=>`${l.policy} | ${l.provider} | ${l.repoRoot}`).join(`
134
- `)}}if(r==="cleanup"){let a=v.cleanupRepoPolicies();return{text:a.length===0?"No stale repo policies found.":[`Removed ${a.length} stale repo ${a.length===1?"policy":"policies"}.`,...a.map(l=>`${l.policy} | ${l.provider} | ${l.repoRoot}`)].join(`
135
- `)}}let o=e.workspaceDir;if(!o)return{text:"Error: workspaceDir is required."};if(r==="reset")return{text:v.resetRepoPolicy(o)?`Repo policy reset for ${o}.`:`No stored repo policy found for ${o}.`};if(r&&eg(r)){if(typeof v.resolveRepoPolicy=="function"){let d=v.resolveRepoPolicy(o);if(d.identity){let u=Lt(r,d.prAvailable);if(u)return{text:`Error: ${u}`}}}let a=v.setRepoPolicy(o,r);if(!a)return{text:`Error: ${o} is not a git repository.`};let l=`Repo policy set to ${a.policy} for ${a.repoRoot}.`;try{if(typeof v.continueLaunchAfterManualRepoPolicy!="function")return{text:l};let d=v.continueLaunchAfterManualRepoPolicy(a.repoRoot,r);if(d.kind==="launched")return{text:[l,"",d.text].join(`
136
- `)};if(d.kind==="ambiguous")return{text:[l,"",`Repo policy saved, but ${d.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
137
- `)}}catch(d){let u=d instanceof Error?d.message:String(d);return{text:[l,"",`Repo policy saved, but the deferred launch failed: ${u}`,"The pending launch context was kept so you can retry the same /agent_policy command or run the intended launch again."].join(`
138
- `)}}return{text:l}}let i=v.resolveRepoPolicy(o);if(!i.identity)return{text:`No git repository found for ${o}.`};let s=wn(i.prAvailable).map(a=>a.policy).join(", ");return{text:[`Repo policy: ${i.policy??"unknown"}`,`Repo: ${i.identity.repoRoot}`,`Provider: ${i.provider}${i.prAvailable?"":" (PR automation unavailable)"}`,...i.identity.remoteUrl?[`Remote: ${i.identity.remoteUrl}`]:[],"",`Set with /agent_policy ${s}.`].join(`
139
- `)}}})}F();var tg=50;function gd(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=Kt(n),o="",i=!1,s=tg;for(let l=0;l<r.length;l++)if(r[l]==="--full")i=!0;else if(r[l]==="--lines"&&l+1<r.length){let d=parseInt(r[l+1],10);!isNaN(d)&&d>0&&(s=d),l++}else o||(o=r[l]);return o?{text:Mr(v,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}F();var hd="Usage: /goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function yd(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(!z)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:hd};let r=Kt(n),o,i,s,a,l="bypassPermissions",d,u,c,p=[],f=[];for(let k=0;k<r.length;k++){let S=r[k];if(S==="--name"&&k+1<r.length)o=r[++k];else if(S==="--workdir"&&k+1<r.length)i=r[++k];else if(S==="--model"&&k+1<r.length)s=r[++k];else if(S==="--max-iterations"&&k+1<r.length){let b=parseInt(r[++k],10);!Number.isNaN(b)&&b>0&&(a=b)}else if(S==="--permission-mode"&&k+1<r.length){let b=r[++k];if(b==="default"||b==="plan"||b==="bypassPermissions")l=b;else return{text:`Error: Invalid permission mode "${b}".`}}else if(S==="--harness"&&k+1<r.length)d=r[++k];else if(S==="--mode"&&k+1<r.length){let b=r[++k];if(b==="ralph"||b==="verifier")u=b;else return{text:`Error: Invalid goal mode "${b}". Use ralph or verifier.`}}else if(S==="--completion-promise"&&k+1<r.length)c=r[++k];else if(S==="--verify"&&k+1<r.length){let b=r[++k].trim();if(!b)return{text:"Error: --verify commands must not be empty."};p.push(b)}else f.push(S)}let m=f.join(" ").trim();if(!m)return{text:hd};let y=Qr({goal:m,verifierCommands:p,name:o,workdir:i,model:s,maxIterations:a,permissionMode:l,harness:d,goalMode:u,completionPromise:c},e);if(y.kind!=="resolved")return{text:y.text};try{let k=await z.launchTask({goal:y.goal,name:y.name,workdir:y.workdir,model:y.model,reasoningEffort:y.reasoningEffort,fastMode:y.fastMode,maxIterations:y.maxIterations,permissionMode:y.permissionMode,harness:y.harness,loopMode:y.loopMode,completionPromise:y.completionPromise,originChannel:y.originChannel,originThreadId:y.originThreadId,originAgentId:y.originAgentId,originSessionKey:y.originSessionKey,route:y.route,verifierCommands:y.verifierCommands});return{text:Jr(k,y)}}catch(k){return{text:`Error launching goal task: ${k instanceof Error?k.message:String(k)}`}}}})}F();function kd(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(!z)return{text:Pe};let n=(e.args??"").trim();return{text:Zr(z,r=>v?.resolve(r),n)}}})}F();function Sd(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(!z)return{text:Pe};let n=(e.args??"").trim();if(!n)return{text:"Usage: /goal_stop <task-id-or-name>"};let r=z.stopTask(n);return{text:Xr(r,n)}}})}F();var vd="Usage: /goal_edit <task-id-or-name> <replacement-goal>";function wd(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(!z)return{text:Pe};let n=(e.args??"").trim();if(!n)return{text:vd};let r=mt(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:vd};let s=z.editTask(o,i);return{text:eo(s,o)}}})}import{execFile as gg}from"child_process";import{createHash as Wd}from"crypto";import{existsSync as $n,mkdirSync as ng,readFileSync as rg,renameSync as Rd,writeFileSync as og}from"fs";import{homedir as ig}from"os";import{dirname as sg,join as Ad}from"path";var ag=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function lg(t){let e=t.OPENCLAW_HOME?.trim();return e||Ad(ig(),".openclaw")}function dg(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||Ad(lg(t),"code-agent-goal-tasks.json")}function Id(t){return t instanceof Error?t.message:String(t)}function xd(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var ug=100;function Pd(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function cg(t){if(!$n(t))return;let e=Date.now(),n=Pd(t,e);if(!$n(n))return n;for(let r=1;r<=ug;r+=1){let o=Pd(t,e,r);if(!$n(o))return o}}function bd(t,e){try{let n=cg(t);return n?(Rd(t,n),`${e}${n}`,!0):($n(t),!1)}catch(n){return`${Id(n)}`,!1}}function pg(t){if(!xd(t))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 mg(t){if(!xd(t))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"||!ag.has(e.status))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:pg(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}}function fg(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=mg(n);if(!r)return;e.push(r)}return e}var io=class{path;tasks=new Map;constructor(e=process.env){this.path=dg(e),this.load()}load(){try{if(!$n(this.path))return;let e=rg(this.path,"utf8"),n=JSON.parse(e),r=fg(n);if(!r){bd(this.path,"invalid")&&this.save();return}this.tasks.clear();for(let o of r)this.tasks.set(o.id,o);this.save()}catch(e){if(e.code==="ENOENT")return;bd(this.path,"corrupt or unreadable")&&this.save()}}save(){try{ng(sg(this.path),{recursive:!0});let e=`${this.path}.tmp`;og(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),Rd(e,this.path)}catch(e){`${this.path}${Id(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)}};Ie();var hg=8,Nd=600*1e3,yg=4e3,us=1200,kg="DONE",Sg=["BASH_ENV","ENV"];function vg(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"goal-task"}function Ut(t,e){return t.length<=e?t:`${t.slice(0,e-3)}...`}function Ze(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(`
103
+ ℹ️ 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&&tf(t,n),u)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let m=de(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${m}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let f=de(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(`
104
+ `)}}catch(d){return{text:`Error sending message to session ${n.name} [${n.id}]: ${Fi(d)}`,isError:!0}}}function of(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 Id(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:g.Object({session:g.String({description:"Session name or ID to respond to"}),message:g.String({description:"The message to send to the session"}),interrupt:g.Optional(g.Boolean({description:"If true, interrupt the current turn before sending the message. Useful to redirect the session mid-response."})),userInitiated:g.Optional(g.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:g.Optional(g.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:g.Optional(g.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(!of(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, message, interrupt?, userInitiated?, approve?, approval_rationale? }."}]};let r=await Pe(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}]}}}}re();K();function sf(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function xd(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:g.Object({session:g.String({description:"Session name or ID awaiting plan approval"}),summary:g.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(!sf(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}]}}}}re();K();function af(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Td(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:g.Object({session:g.String({description:"Delegated session name or ID awaiting a worktree decision"}),summary:g.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(!af(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}]}}}}re();K();ae();var Ui=["off","manual","ask","delegate","auto-merge","auto-pr"],Nr=new Set(Ui),df=["pr-required","pr-allowed","never-pr","manual"],Cd=new Set(df),lf=["low","medium","high","xhigh","max"],Md=new Set(lf);function uf(t){return typeof t=="string"&&Nr.has(t)}var cf=g.Union(Ui.map(t=>g.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 pf(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||uf(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 mf(t,e){let n=Pt(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 ff(t,e){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=mf(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 _d(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:g.Object({offer_id:g.String({description:"Stable offer identifier, for example 'plugin-readiness-v2026.5.5'."}),offer_text:g.String({description:"Final user-facing text to deliver."}),plan_prompt:g.String({description:"Prompt to seed into the plan-only session when the user clicks Start Plan."}),plan_workdir:g.String({description:"Working directory for the planning session."}),plan_worktree_strategy:g.Optional(cf),plan_name:g.Optional(g.String({description:"Optional explicit session name for the planning session."})),target_channel:g.Optional(g.String({description:"Optional explicit route like 'telegram|<chat-id>'."})),target_thread_id:g.Optional(g.Union([g.String(),g.Number()],{description:"Optional explicit topic/thread id."})),target_session_key:g.Optional(g.String({description:"Optional explicit session key for wake routing."}))}),async execute(e,n){return pf(n)?ff(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}re();K();function $d(t){return{name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics: session counts by status, average duration, and notable sessions.",parameters:g.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:ur(r,o)}]}}}}re();K();Wt();import{execFileSync as gf}from"child_process";var Gi=[{policy:"pr-required",label:"Require PR",title:"Require PR",description:"Direct merge is disabled; follow-through must use a pull request."},{policy:"pr-allowed",label:"Merge or PR",title:"Merge or PR",description:"Use the requested strategy; direct merge and pull requests are both allowed."},{policy:"never-pr",label:"No PR",title:"No PR",description:"Do not create pull requests; keep follow-through local/direct."},{policy:"manual",label:"Manual",title:"Manual",description:"Create isolated worktrees, but require an explicit human follow-up decision every time."}],hf=new Map(Gi.map(t=>[t.policy,t]));function bn(t){return t?Gi:Gi.filter(e=>e.policy==="never-pr"||e.policy==="manual")}function Ed(t){return hf.get(t)??{policy:t,label:t,title:t,description:"Custom repo integration policy."}}function qt(t,e){if(!(e||t!=="pr-required"&&t!=="pr-allowed"))return`Policy ${t} requires PR automation, but no supported PR provider is available. Choose never-pr or manual.`}function ji(t){let{policy:e,prAvailable:n}=t;return{merge:e!=="pr-required"&&e!=="manual",pr:e!=="never-pr"&&e!=="manual"&&n}}function Vi(t,e){try{return gf("git",e,{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Dd(t){if(!t)return;let e=t.trim().replace(/\/+$/,"").replace(/\.git$/i,""),n=e.match(/^git@([^:]+):(.+)$/);if(n)return`https://${n[1].toLowerCase()}/${n[2].toLowerCase()}`;let r=e.match(/^https?:\/\/([^/]+)\/(.+)$/i);return r?`https://${r[1].toLowerCase()}/${r[2].toLowerCase()}`:e.toLowerCase()}function yf(t){return Dd(t)?.startsWith("https://github.com/")?"github":"unsupported"}function Rn(t){let e=Vi(t,["rev-parse","--show-toplevel"]);if(!e)return;let n=Vi(e,["remote","get-url","origin"])??Vi(e,["remote","get-url","upstream"]),r=Dd(n),o=yf(r);return{key:r?`${e}|${r}`:e,repoRoot:e,remoteUrl:r,provider:o}}function Od(t){if(t?.remoteUrl)return t.remoteUrl==="https://github.com/goldmar/openclaw-code-agent"?"pr-required":void 0}function Hi(t,e,n="stored",r=new Date().toISOString()){return{key:t.key,policy:e,repoRoot:t.repoRoot,remoteUrl:t.remoteUrl,provider:t.provider,createdAt:r,updatedAt:r,source:n}}function zi(t){return t.provider==="github"&&we()}function Wd(t){let e=t.requestedStrategy,n=ji(t);return!e||e==="off"||e==="manual"?{allowedActions:n}:t.policy?t.policy==="manual"?{strategy:e==="delegate"?"delegate":"ask",reason:"Repo policy requires manual follow-through.",allowedActions:{merge:!1,pr:!1}}:t.policy==="pr-required"?e==="auto-merge"?t.prAvailable?{strategy:"auto-pr",reason:"Repo policy requires a PR; auto-merge was downgraded to auto-pr.",allowedActions:n}:{strategy:"ask",blocked:!0,reason:"Repo policy requires a PR, but no supported PR provider is available.",allowedActions:n}:e==="auto-pr"?t.prAvailable?{strategy:"auto-pr",allowedActions:n}:{strategy:"ask",blocked:!0,reason:"Repo policy requires a PR, but no supported PR provider is available.",allowedActions:n}:{strategy:e,allowedActions:n}:t.policy==="never-pr"?e==="auto-pr"?t.existingOpenPr&&t.prAvailable?{strategy:"auto-pr",reason:"Repo policy forbids new PR creation; updating the existing open PR is allowed.",allowedActions:n}:{strategy:"ask",reason:"Repo policy forbids PR creation; auto-pr was downgraded to an explicit worktree decision.",allowedActions:n}:{strategy:e,allowedActions:n}:e==="auto-pr"&&!t.prAvailable?{strategy:"ask",reason:"No supported PR provider is available; auto-pr was downgraded to an explicit worktree decision.",allowedActions:n}:{strategy:e,allowedActions:n}:{strategy:e==="auto-merge"||e==="auto-pr"?"ask":e,blocked:!0,reason:"Repo integration policy is unknown.",allowedActions:{merge:!1,pr:!1}}}function Qi(t,e,n=t.provider==="github"){let r=bn(n);return[`Repo integration policy is not set for ${t.repoRoot}.`,"","OCA will create isolated worktrees, but it needs one repo policy before worktree follow-through can run.",`Requested worktree strategy: ${e}`,`Provider: ${t.provider}${n?"":" (PR automation unavailable)"}`,"","Choose one available policy:",...r.map(o=>`- ${o.title}: ${o.description}`),"","If buttons are unavailable, set it manually. OCA will continue the pending launch automatically when exactly one matching launch is waiting; otherwise run the intended launch again:",...r.map(o=>`- agent_repo_policy(workdir="${t.repoRoot}", policy="${o.policy}")`)].join(`
105
+ `)}function kf(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function An(t){return t?[`Repo policy: ${t.policy}`,`Repo: ${t.repoRoot}`,`Provider: ${t.provider}`,...t.remoteUrl?[`Remote: ${t.remoteUrl}`]:[],`Updated: ${t.updatedAt}`].join(`
106
+ `):"No stored repo policy found."}function Nd(t){return{name:"agent_repo_policy",description:"Inspect or set the repository integration policy that governs OCA worktree merge/PR follow-through.",parameters:g.Object({workdir:g.Optional(g.String({description:"Repository workdir. Defaults to the current workspace directory."})),policy:g.Optional(g.Union([g.Literal("pr-required"),g.Literal("pr-allowed"),g.Literal("never-pr"),g.Literal("manual")],{description:"Policy to set for this repo."})),reset:g.Optional(g.Boolean({description:"Remove the stored policy for this repo."})),list:g.Optional(g.Boolean({description:"List all stored repo policies."})),cleanup:g.Optional(g.Boolean({description:"Remove stored repo policies whose repoRoot no longer exists on disk."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=n&&typeof n=="object"?n:{};if(r.cleanup===!0){let a=v.cleanupRepoPolicies();return{content:[{type:"text",text:a.length===0?"No stale repo policies found.":[`Removed ${a.length} stale repo ${a.length===1?"policy":"policies"}.`,...a.map(l=>`${l.policy} | ${l.provider} | ${l.repoRoot}`)].join(`
107
+ `)}]}}if(r.list===!0){let a=v.listRepoPolicies();return{content:[{type:"text",text:a.length===0?"No stored repo policies.":a.map(l=>`${l.policy} | ${l.provider} | ${l.repoRoot}${l.remoteUrl?` | ${l.remoteUrl}`:""}`).join(`
108
+ `)}]}}let o=r.workdir??t?.workspaceDir;if(!o)return{content:[{type:"text",text:"Error: workdir is required when no workspace directory is available."}]};if(r.reset===!0)return{content:[{type:"text",text:v.resetRepoPolicy(o)?`Repo policy reset for ${o}.`:`No stored repo policy found for ${o}.`}]};if(r.policy!==void 0){if(!kf(r.policy))return{content:[{type:"text",text:"Error: policy must be one of pr-required, pr-allowed, never-pr, manual."}]};if(typeof v.resolveRepoPolicy=="function"){let l=v.resolveRepoPolicy(o);if(l.identity){let u=qt(r.policy,l.prAvailable);if(u)return{content:[{type:"text",text:`Error: ${u}`}]}}}let a=v.setRepoPolicy(o,r.policy);if(!a)return{content:[{type:"text",text:`Error: ${o} is not a git repository.`}]};let d;try{d=typeof v.continueLaunchAfterManualRepoPolicy=="function"?v.continueLaunchAfterManualRepoPolicy(a.repoRoot,r.policy):{kind:"none"}}catch(l){let u=l instanceof Error?l.message:String(l);return{content:[{type:"text",text:[An(a),"",`Repo policy saved, but the deferred launch failed: ${u}`,"The pending launch context was kept so you can retry the same agent_repo_policy call or run the intended launch again."].join(`
109
+ `)}]}}return d.kind==="launched"?{content:[{type:"text",text:[An(a),"",d.text].join(`
110
+ `)}]}:d.kind==="ambiguous"?{content:[{type:"text",text:[An(a),"",`Repo policy saved, but ${d.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
111
+ `)}]}:{content:[{type:"text",text:An(a)}]}}let i=v.resolveRepoPolicy(o);if(!i.identity)return{content:[{type:"text",text:`No git repository found for ${o}.`}]};let s=i.record;return s?{content:[{type:"text",text:An(s)}]}:{content:[{type:"text",text:["Repo policy: unknown",`Repo: ${i.identity.repoRoot}`,`Provider: ${i.provider}${i.prAvailable?"":" (PR automation unavailable)"}`,...i.identity.remoteUrl?[`Remote: ${i.identity.remoteUrl}`]:[]].join(`
112
+ `)}]}}}}re();ae();K();ke();In();Tn();import{existsSync as Vr}from"fs";function vf(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function wf(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 Pf(t){return t.deleteBranchRequested?t.branchDeleted&&t.worktreeCleanedUp&&!t.worktreeAlreadyAbsent?{detailLine:"Branch and worktree cleaned up.",summaryFragment:" Branch and worktree cleaned up."}:t.branchDeleted&&t.worktreeAlreadyAbsent?{detailLine:"Branch deleted; worktree was already absent.",summaryFragment:" Branch deleted; worktree was already absent."}:t.branchDeleted?{detailLine:"Branch deleted; worktree cleanup failed.",summaryFragment:" Branch deleted; worktree cleanup failed."}:t.worktreeAlreadyAbsent?{detailLine:"Worktree was already absent; branch deletion failed.",summaryFragment:" Worktree was already absent; branch deletion failed."}:t.worktreeCleanedUp?{detailLine:"Worktree cleaned up; branch deletion failed.",summaryFragment:" Worktree cleaned up; branch deletion failed."}:{detailLine:"Branch deletion and worktree cleanup failed.",summaryFragment:" Branch deletion and worktree cleanup failed."}:t.worktreeCleanedUp&&!t.worktreeAlreadyAbsent?{detailLine:"Worktree cleaned up; branch deletion was not requested.",summaryFragment:" Worktree cleaned up; branch kept."}:t.worktreeAlreadyAbsent?{detailLine:"Worktree was already absent; branch deletion was not requested.",summaryFragment:" Worktree was already absent; branch kept."}:{detailLine:"Worktree cleanup failed; branch deletion was not requested.",summaryFragment:" Worktree cleanup failed; branch kept."}}function Gr(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:g.Object({session:g.String({description:"Session name or ID to merge"}),base_branch:g.Optional(g.String({description:"Base branch to merge into (default: main)"})),strategy:g.Optional(g.Union([g.Literal("merge"),g.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:g.Optional(g.Boolean({description:"Push the base branch after successful merge (default: false)"})),delete_branch:g.Optional(g.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(!vf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=Ut(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.`}]};Vr(s)||`${s}${a}`;let l=a;if(!Vr(a))return{content:[{type:"text",text:`Error: originalWorkdir "${a}" does not exist.`}]};let u=n.base_branch??$e(l),c=u,p=n.strategy??"merge",f=n.push===!0,m=n.delete_branch!==!1,y=v.resolveRepoPolicy(l);if(y?.policy==="pr-required")return{content:[{type:"text",text:`❌ Merge blocked: repo policy requires a pull request for ${y.identity?.repoRoot??l}. Use agent_pr if PR automation is available.`}]};if(i?.worktreeLifecycle?.state==="merged"||i?.worktreeMerged)return{content:[{type:"text",text:`ℹ️ Session "${n.session}" is already merged.`}]};if((Vr(s)?vn(l,d,c):void 0)===0&&ut(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(`
113
+ `)}]};let S={content:[{type:"text",text:"❌ Merge did not run (internal error)"}]};return await v.enqueueMerge(l,async()=>{let b=v.getPersistedSession(n.session);if(b?.worktreeLifecycle?.state==="merged"||b?.worktreeMerged){S={content:[{type:"text",text:`ℹ️ Session "${n.session}" was already merged while waiting in queue.`}]};return}let A=Be(l,d,u),x=Tr(l,d,c,p,s),R=Lt(x);if(x.success){let h=wf({mergeResult:x,repoDir:l,baseBranch:c});if(f&&!xr(l,c)){let L=`⚠️ Merged ${d} → ${c} locally, but failed to push ${c}`;v.notifyWorktreeOutcome(r.notificationTarget,L,{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.",...h,...R]}),S={content:[{type:"text",text:Ee(L,x)}]};return}let w=!1,N=!1,Q=!Vr(s);N=Q?!0:pe(l,s),Ar(l),m&&(w=ye(l,d));let D=Pf({deleteBranchRequested:m,branchDeleted:w,worktreeCleanedUp:N,worktreeAlreadyAbsent:Q});if(b){let L=new Date().toISOString();for(let G of xn({...r,persistedSession:b}))v.updatePersistedSession(G,{...Kt({worktreeBaseBranch:u,worktreePrTargetRepo:b.worktreePrTargetRepo,worktreePushRemote:b.worktreePushRemote},{mergedAt:L,updatedAt:L,resolvedAt:L,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let C=ct({kind:"merge",branch:d,base:u,filesChanged:A?.filesChanged,insertions:A?.insertions,deletions:A?.deletions});v.notifyWorktreeOutcome(r.notificationTarget,C,{detailLines:[x.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",f?`Pushed ${c}.`:`Did not push ${c}; push was not requested.`,D.detailLine,...h,...R]});let q=`✅ ${x.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${d} → ${c}.${f?" Pushed.":""}${D.summaryFragment}`;x.stashPopConflict?q+=`
114
+ ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${x.stashRef??"stash@{0}"}\` in ${l} to review stashed changes.`:x.stashed&&(q+=`
115
+ (Pre-existing changes on ${c} were auto-stashed and restored.)`),q=Ee(q,x),S={content:[{type:"text",text:q}]}}else if(x.rebaseConflict)S={content:[{type:"text",text:Ee(`⚠️ Rebase conflicts — manual resolution required:
116
+
117
+ ${x.error}`,x)}]};else if(x.conflictFiles&&x.conflictFiles.length>0){let h=["Resolve merge conflicts in the following files and commit the resolution:","",...x.conflictFiles.map(w=>`- ${w}`),"",`After resolving, commit with message: "Resolve merge conflicts from ${d}"`].join(`
118
+ `);try{let w=v.spawn({prompt:h,workdir:l,name:`${n.session}-conflict-resolver`,harness:le(),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});S={content:[{type:"text",text:Ee(`⚠️ Merge conflicts in ${x.conflictFiles.length} file(s) — spawned conflict resolver session: ${w.name}`,x)}]}}catch(w){S={content:[{type:"text",text:Ee(`❌ Merge conflicts detected, but failed to spawn resolver: ${w instanceof Error?w.message:String(w)}`,x)}]}}}else{let h=x.dirtyError?`❌ Merge blocked: ${x.error}`:`❌ Merge failed: ${x.error??"unknown error"}`;S={content:[{type:"text",text:Ee(h,x)}]}}}),S}}}Jr();re();K();ee();ke();Tn();function Mf(t){return!!t&&typeof t=="object"}function jd(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:g.Object({workdir:g.Optional(g.String({description:"Restrict cleanup to sessions rooted in this repository"})),base_branch:g.Optional(g.String({description:"Override base branch for lifecycle resolution"})),mode:g.Optional(g.Union([g.Literal("preview_safe"),g.Literal("clean_safe"),g.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:g.Optional(g.Boolean({description:"Deprecated. Safe cleanup never removes live sessions."})),force:g.Optional(g.Boolean({description:"Deprecated alias for skip_session_check."})),dry_run:g.Optional(g.Boolean({description:"Show what would be cleaned without deleting anything."})),session:g.Optional(g.String({description:"Session name or ID to clean or dismiss."})),dismiss_session:g.Optional(g.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(!Mf(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=qr(v);if(r&&(a=a.filter(f=>Kr(f,r)),a.length===0)){let f=Ut(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:m,activeSession:y,resolvedLifecycle:k}=Fr(v,f,{baseBranch:n.base_branch});if(!k.cleanupSafe){if(s){let S=k.reasons.length>0?k.reasons.map(Ur).join(", "):mt(k.derivedState);l.push(`${f.name} [kept: ${S}]`)}continue}if(d.push(`${f.name} (${mt(k.derivedState)})`),!i)try{let S=f.workdir;if(!((m??y)&&ue(m??y))&&f.worktreePath&&pe(S,f.worktreePath,{destructive:!1}),f.worktreeBranch&&ye(S,f.worktreeBranch),m){let A=k.derivedState==="merged"||k.derivedState==="released"?k.derivedState:k.lifecycle.state,x=new Date().toISOString(),R=A==="merged"?m.worktreeMergedAt:A==="dismissed"?m.worktreeDismissedAt:void 0;v.updatePersistedSession(f.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeMerged:A==="merged"?!0:m.worktreeMerged,worktreeMergedAt:A==="merged"?m.worktreeMergedAt??x:m.worktreeMergedAt,worktreeLifecycle:{...m.worktreeLifecycle??k.lifecycle,state:A,updatedAt:x,resolvedAt:m.worktreeLifecycle?.resolvedAt??R??x,resolutionSource:m.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??k.lifecycle.baseBranch??m.worktreeBaseBranch,targetRepo:m.worktreePrTargetRepo,pushRemote:m.worktreePushRemote,notes:k.reasons}})}u.push(`${f.name} (${mt(k.derivedState)})`)}catch(S){c.push(`${f.name}: ${S instanceof Error?S.message:String(S)}`)}}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(`
119
+ `)}]}}}}re();K();Tn();function _f(t){if(t==null)return!0;if(Array.isArray(t)||typeof t!="object")return!1;let e=t.session;return e===void 0||typeof e=="string"}function Hd(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:g.Object({session:g.Optional(g.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(!_f(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n&&typeof n=="object"?n.session:void 0,o=qr(v);if(r&&(o=o.filter(s=>Kr(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}=Fr(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:${mt(d.lifecycle.state)}`),d.derivedState!==d.lifecycle.state&&i.push(` Derived: ${mt(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(Ur).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
120
+ `).trim()}]}}}}re();K();ae();er();import{existsSync as $f}from"fs";function Ef(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function Yr(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(!$f(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=Ef(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??le(),a=t.model??vt(s),d=Ne(s,a),l=Kn(s);if(!d&&(s!=="opencode"||l&&l.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(d&&!Ct(s,d))return{kind:"error",text:`Error: Model "${a}" is not supported for harness "${s}". Use a bare Codex model id such as "gpt-5.5".`};if(d&&!Zn(s,d,l))return{kind:"error",text:`Error: Model "${a}" is not allowed. Permitted models: ${l?.join(", ")}`};let u=Xn(s,d,l),c=e.sessionKey||void 0,p=Un(e),f=an(e,p||ot(r)),m=Pt(e,f,c);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:u,reasoningEffort:He(s),fastMode:wt(s),systemPrompt:t.systemPrompt,allowedTools:t.allowedTools,maxIterations:t.maxIterations,permissionMode:t.permissionMode??"bypassPermissions",harness:s,loopMode:i,completionPromise:t.completionPromise,originChannel:f,originThreadId:m?.threadId,originAgentId:e.agentId||void 0,originSessionKey:c,route:m,verifierCommands:o}}function Zr(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(`
121
+ `)}function Df(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function zd(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:g.Object({goal:g.String({description:"End goal for the autonomous task"}),verifier_commands:g.Optional(g.Array(g.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:g.Optional(g.String({description:"Short task name (kebab-case preferred)"})),workdir:g.Optional(g.String({description:"Working directory (defaults to cwd / configured workspace)"})),model:g.Optional(g.String({description:"Model name to use"})),system_prompt:g.Optional(g.String({description:"Additional system prompt"})),allowed_tools:g.Optional(g.Array(g.String(),{description:"Allowed tools for the underlying agent session"})),max_iterations:g.Optional(g.Number({description:"Maximum verifier-driven repair iterations",minimum:1})),goal_mode:g.Optional(g.Union([g.Literal("ralph"),g.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:g.Optional(g.String({description:"Exact completion promise for Ralph-mode loops. Defaults to 'DONE'."})),permission_mode:g.Optional(g.Union([g.Literal("default"),g.Literal("plan"),g.Literal("bypassPermissions")],{description:"Permission mode for the underlying agent session. Defaults to bypassPermissions for autonomous goal loops."})),harness:g.Optional(g.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode')."}))}),async execute(e,n){if(!z)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!Df(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=Yr({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 z.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:Zr(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}re();function ts(t,e){return t.split(`
122
+ `).map(n=>`${e}${n}`)}function Qd(t,e){return t.length<=e?t:`${t.slice(0,e-3).trimEnd()}...`}function Of(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(`
123
+ `);return o.length<=n?o:`...${o.slice(-(n-3))}`}function Wf(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=>Qd(o,180))}function Nf(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=>Qd(n,180))}function Xr(t){let e=[],n=Nf(t.verifierSummary),r=Wf(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(`
124
+ `)}function ns(t){if(t)return{phase:t.phase,awaitingInput:t.isAwaitingInput??!!t.pendingInputState,latestOutput:Of(t.getOutput(20))}}function rs(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(...ts(n," ")),t.lastVerifierSummary&&(o.push(" Last verifier:"),o.push(...ts(t.lastVerifierSummary," "))),e?.latestOutput&&(o.push(" Latest activity:"),o.push(...ts(e.latestOutput," "))),t.waitingForUserReason&&o.push(` Waiting on user: ${t.waitingForUserReason}`),t.failureReason&&o.push(` Failure: ${t.failureReason}`),o.join(`
125
+ `)}var be="Error: GoalController not initialized. The code-agent service must be running.";function eo(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 rs(i,ns(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 rs(i,ns(s))}).join(`
126
+
127
+ `)}function to(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 no(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.`}}K();function Jd(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:g.Object({task:g.Optional(g.String({description:"Task name or ID. Omit to list all tasks."}))}),async execute(e,n){if(!z)return{content:[{type:"text",text:be}]};let r=n&&typeof n=="object"&&typeof n.task=="string"?n.task:void 0;return{content:[{type:"text",text:eo(z,o=>v?.resolve(o),r)}]}}}}re();K();function Lf(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function Yd(t){return{name:"goal_stop",description:"Stop an explicit goal task and kill its underlying agent session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"})}),async execute(e,n){if(!z)return{content:[{type:"text",text:be}]};if(!Lf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=z.stopTask(n.task);return{content:[{type:"text",text:to(r,n.task)}]}}}}re();K();function Bf(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function Zd(t){return{name:"goal_edit",description:"Edit the goal text for an active goal task without stopping or relaunching its session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"}),goal:g.String({description:"Replacement goal text"})}),async execute(e,n){if(!z)return{content:[{type:"text",text:be}]};if(!Bf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=z.editTask(n.task,n.goal);return{content:[{type:"text",text:no(r,n.task)}]}}}}K();Jr();import{createHash as Ff}from"crypto";var te="code-agent";var qf=new Set(["1","true","yes","on"]);function is(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&qf.has(t))}function Re(t){if(!(typeof t!="string"||t.length===0))return Ff("sha256").update(t).digest("hex").slice(0,12)}function Xd(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function Y(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=Xd(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>Re(Xd(r))):void 0,buttonStyles:n.length>0?n.map(r=>typeof r.style=="string"?r.style:void 0):void 0}}function et(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function tl(t){let e=et(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(n)return n.map(r=>et(r)?.type).filter(r=>typeof r=="string"&&r.length>0)}function nl(t){let e=et(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(!n)return;let r=n.map(o=>{let i=et(o);return i?.type!=="buttons"||!Array.isArray(i.buttons)?[]:i.buttons}).filter(o=>o.length>0);return r.length>0?r:void 0}function ss(t){let e=nl(t);return{presentationBlockTypes:tl(t),...Y(e)}}function as(t){let e=et(t),n=e?.interactive,r=et(e?.channelData),o=et(r?.telegram),i=Array.isArray(o?.buttons)?o.buttons:void 0;return{renderedPayloadKeys:e?Object.keys(e).sort():void 0,interactiveBlockTypes:tl(n),...el("interactive",Y(nl(n))),...el("telegramChannelData",Y(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function rl(t){let e=et(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:os(e.messageId),chatId:os(e.chatId),telegramThreadId:os(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function os(t){return typeof t=="string"||typeof t=="number"?t:void 0}function el(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 B(t,e){if(!is())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:te,...n})}`}var ds=new Set,ol="⚠️ Could not submit that answer. The question prompt is still active; try again or reply with the answer.",$n=new Map;async function dl(t){try{await t}catch(e){let n=e instanceof Error?e.message:String(e);`${n}`}}async function il(t,e,n){if(!t)return n();for(;;){let o=$n.get(t)?.operation;if(!o)break;await dl(o)}let r=Promise.resolve().then(n);$n.set(t,{operation:r,tokenId:e});try{return await r}finally{$n.get(t)?.operation===r&&$n.delete(t)}}function Kf(t){let e=t.trim().replace(new RegExp(`^${te}:`),"");return e||null}function Uf(t){return t.trim().startsWith(`${te}:`)}async function ro(t,e=!1){if(t.channel==="telegram")try{return(await X(t,{alreadyAcknowledged:e,forceTelegramMarkupEdit:!0})).textDelivered}catch(r){let o=r instanceof Error?r.message:String(r);return`${o}`,!1}let n=t.respond;if(typeof n.clearComponents=="function")try{return await n.clearComponents(),!1}catch(r){if(gt(r))return!1;let o=r instanceof Error?r.message:String(r);`${o}`}if(typeof n.clearButtons=="function")try{await n.clearButtons()}catch(r){let o=r instanceof Error?r.message:String(r);`${o}`}else!e&&typeof n.acknowledge=="function"&&await n.acknowledge();return!1}async function Ke(t,e=!1){await X(t,{alreadyAcknowledged:e,forceTelegramMarkupEdit:t.channel==="telegram"})}function io(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 sl(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return cs(io(t))}function cs(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function so(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function Vf(t){if(so(t.kind))return`${t.sessionId}:v${t.planDecisionVersion??"unknown"}`}function Gf(t){return t?t.approvalState==="approved"||!t.pendingPlanApproval:!1}function jf(...t){let e;for(let n of t)n!=null&&(e=e==null?n:Math.max(e,n));return e}function Hf(t){if(t.actionablePlanDecisionVersion!=null)return t.actionablePlanDecisionVersion;let e=jf(t.approvalPromptRequiredVersion,t.approvalPromptVersion);return e??t.canonicalPlanPromptVersion??t.planDecisionVersion}function ls(t,e){if(!so(t.kind))return;if(!e)return"This plan decision is stale because the session is no longer available.";let n=Hf(e);if(t.planDecisionVersion!=null&&n!=null&&t.planDecisionVersion!==n)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 ll(t,...e){return e.find(n=>typeof n=="string"&&t(n))}function oo(...t){return ll(e=>e.trim().length>0,...t)}function al(...t){return ll(Uf,...t)}function zf(t){let e="callback"in t?al(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0;if(e)return e;let n="interaction"in t?t.interaction:void 0,r=al(n?.data,n?.callback_data,n?.callbackData);if(r)return r;let o="callback"in t?oo(t.callback?.payload):void 0;if(o)return o;let i=oo(n?.payload);return i||(("callback"in t?oo(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0)??oo(n?.data,n?.callback_data,n?.callbackData)??"")}function En(t,e=new Set){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean"||typeof t=="bigint")return String(t);if(t instanceof Error)return[t.name,t.message,En(t.cause,e)].filter(Boolean).join(" ");if(typeof t!="object")return String(t);if(e.has(t))return"";e.add(t);let n=t;return[n.message,n.description,n.error,n.error_description,En(n.cause,e),En(n.response,e),En(n.payload,e)].filter(Boolean).join(" ")}function gt(t){return/message is not modified/i.test(En(t))}function Qf(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function ft(t){if(typeof t.clearButtons=="function")try{await t.clearButtons()}catch(e){if(gt(e))return;throw e}}async function X(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:[]}),await ft(n),{textDelivered:!0}}catch(a){if(gt(a))return await ft(n),{textDelivered:!0};let d=a instanceof Error?a.message:String(a);`${d}`}if(o&&typeof n.editButtons=="function")try{return await n.editButtons({buttons:[]}),await ft(n),{textDelivered:!1}}catch(a){if(gt(a))return await ft(n),{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:[]}),await ft(n),{textDelivered:!1}}catch(a){if(gt(a))return await ft(n),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}return await ft(n),{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(gt(s))return{textDelivered:typeof i=="string"};if(Qf(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(gt(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 Jf(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 O(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}var us=["plan-approve","plan-request-changes","plan-reject"];function Yf(t){switch(t){case"plan-approve":return"Approve";case"plan-request-changes":return"Revise";case"plan-reject":return"Reject";default:return"Continue"}}function Zf(t){switch(t){case"plan-approve":return"primary";case"plan-reject":return"danger";default:return"secondary"}}function Xf(t,e){let n=t,o=(typeof n?.listActiveActionTokens=="function"?us.flatMap(a=>n.listActiveActionTokens?.(a)??[]):[e]).filter(a=>so(a.kind)&&a.sessionId===e.sessionId&&(e.planDecisionVersion==null||a.planDecisionVersion==null||a.planDecisionVersion===e.planDecisionVersion)).sort((a,d)=>us.indexOf(a.kind)-us.indexOf(d.kind)),i=new Set,s=o.filter(a=>i.has(a.kind)?!1:(i.add(a.kind),!0)).map(a=>({label:typeof a.label=="string"&&a.label.trim()?a.label:Yf(a.kind),callbackData:`${te}:${a.id}`,style:Zf(a.kind)}));return s.length>0?[s]:void 0}async function eg(t,e,n,r){if(t.channel!=="telegram"){await O(t,e);return}let o=Xf(n,r);await t.respond.reply({text:o?`${e}
128
+
129
+ Approval is still pending. Try again below.`:e,...o?{buttons:o}:{}})}function ul(t="telegram",e={}){let n=e.makeAgentMergeTool??Gr,r=e.makeAgentPrTool??_n;return B("callback_handler_registered",{channel:t,namespace:te}),{channel:t,namespace:te,handler:async o=>{let i=await Jf(o);if(!o.auth.isAuthorizedSender)return await O(o,"⛔ Unauthorized."),{handled:!0};let s=zf(o),a=Kf(s);if(B("callback_received",{channel:o.channel,namespace:te,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:Re(a),isAuthorizedSender:o.auth.isAuthorizedSender}),!a)return await O(o,"⚠️ Unrecognized callback payload."),{handled:!0};if(!v)return await O(o,"⚠️ Code agent service not running."),{handled:!0};let d=v.getActionToken(a);if(B("callback_token_lookup_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),tokenFound:!!d,actionKind:d?.kind,sessionId:d?.sessionId,planDecisionVersion:d?.planDecisionVersion}),!d)return await X(o,{alreadyAcknowledged:i}),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(d.kind==="question-answer"&&d.consumedAt!=null)return await X(o,{alreadyAcknowledged:i}),await O(o,"⚠️ That question button is no longer active. Use the latest question prompt."),{handled:!0};let l=d.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),c=u?.name??l,p=ls(d,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),actionKind:d.kind,sessionId:l,sessionName:c,planDecisionVersion:d.planDecisionVersion,valid:!p}),p)return so(d.kind)?await Ke(o,i):await X(o,{alreadyAcknowledged:i}),await O(o,`⚠️ ${p}`),{handled:!0};if(d.kind==="question-answer"){if(d.optionIndex==null)return await X(o,{alreadyAcknowledged:i}),await O(o,"⚠️ Invalid question-answer action."),{handled:!0};if(ds.has(a))return await O(o,"⚠️ That answer is already being submitted. If the question remains active, try again."),{handled:!0};ds.add(a);let y=!1;try{y=await v.resolvePendingInputOption(l,d.optionIndex,{requestId:d.pendingInputRequestId,questionId:d.pendingInputQuestionId})}catch(S){let b=S instanceof Error?S.message:String(S);return`${b}`,await O(o,ol),{handled:!0}}finally{ds.delete(a)}if(!y)return await O(o,ol),{handled:!0};let k=v.consumeActionToken(a);return B("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),consumed:!!k,actionKind:k?.kind,sessionId:k?.sessionId,planDecisionVersion:k?.planDecisionVersion}),k?(await X(o,{alreadyAcknowledged:i}),await O(o,"✅ Answer submitted."),{handled:!0}):(await X(o,{alreadyAcknowledged:i}),await O(o,"✅ Answer submitted."),{handled:!0})}let f=Vf(d);if(f)for(;;){let y=$n.get(f);if(!y)break;if(y.tokenId===a)return await Ke(o,i),await O(o,"⚠️ This plan decision is already being processed."),{handled:!0};await dl(y.operation);let k=v.getActionToken(a);if(!k)return await Ke(o,i),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(l=k.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),c=u?.name??l,p=ls(k,u),B("callback_plan_validation_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),actionKind:k.kind,sessionId:l,sessionName:c,planDecisionVersion:k.planDecisionVersion,valid:!p,afterPlanDecisionLock:!0}),p)return await Ke(o,i),await O(o,`⚠️ ${p}`),{handled:!0};d=k}if(d.kind==="plan-approve"){let y=d,k=!1,S=async(x=!1)=>{k||!x&&o.channel!=="telegram"||(await Ke(o,i),k=!0)},b=await il(f,a,async()=>(await S(),Pe(v,{session:y.sessionId,message:"Approved. Go ahead.",approve:!0,userInitiated:!0})));if(b.isError){let x=v.resolve?.(y.sessionId)??v.getPersistedSession?.(y.sessionId),R=Gf(x);if(R){let h=v.consumeActionToken(a);B("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),consumed:!!h,actionKind:h?.kind,sessionId:h?.sessionId??y.sessionId,planDecisionVersion:h?.planDecisionVersion,approvalAppliedAfterError:!0}),await S(!0)}return R?await O(o,`⚠️ ${b.text}`):await eg(o,`⚠️ ${b.text}`,v,y),{handled:!0}}let A=v.consumeActionToken(a);return B("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),consumed:!!A,actionKind:A?.kind,sessionId:A?.sessionId??y.sessionId,planDecisionVersion:A?.planDecisionVersion}),A?(await S(!0),{handled:!0}):(await S(!0),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0})}if(d.kind==="plan-reject"||d.kind==="plan-request-changes")return await il(f,a,async()=>{let y=v.getActionToken(a);if(!y)return await Ke(o,i),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};l=y.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),c=u?.name??l;let k=ls(y,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),actionKind:y.kind,sessionId:l,sessionName:c,planDecisionVersion:y.planDecisionVersion,valid:!k,afterPlanDecisionLock:!0}),k)return await Ke(o,i),await O(o,`⚠️ ${k}`),{handled:!0};let S=v.consumeActionToken(a);if(B("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),consumed:!!S,actionKind:S?.kind,sessionId:S?.sessionId,planDecisionVersion:S?.planDecisionVersion}),!S)return await Ke(o,i),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(await Ke(o,i),S.kind==="plan-reject"){let b=qi(v,l);await O(o,`❌ ${b.text}`)}else{let b=Ki(v,l);await O(o,`✏️ ${b.text}`)}return{handled:!0}});let m=v.consumeActionToken(a);if(B("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),consumed:!!m,actionKind:m?.kind,sessionId:m?.sessionId,planDecisionVersion:m?.planDecisionVersion}),!m)return await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:d.kind==="plan-offer-start"||d.kind==="plan-offer-dismiss"}),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};switch(m.kind){case"worktree-merge":{let y=await n().execute("callback",{session:l}),k=io(y);if(sl(y)){await ro(o,i);break}await O(o,k);break}case"worktree-decide-later":{let y=v.snoozeWorktreeDecision(l,{notifyUser:!1});if(cs(y)){let S=`⏭️ Snoozed 24h for [${c}]`;await ro(o,i),await O(o,S)}else await O(o,y);break}case"worktree-dismiss":{let y=await v.dismissWorktree(l),k=cs(y);k&&await ro(o,i),await O(o,k?"✅ Discarded":y);break}case"worktree-create-pr":case"worktree-update-pr":{let y=await r().execute("callback",{session:l}),k=io(y);if(sl(y)){await ro(o,i);break}await O(o,k);break}case"worktree-view-pr":{await X(o,{alreadyAcknowledged:i});let y=v.getPersistedSession?.(l),k=d.targetUrl??y?.worktreePrUrl;await O(o,k?`PR: ${k}`:"⚠️ PR URL is no longer available.");break}case"plan-offer-start":{if(!m.launchPrompt||!m.launchWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"⚠️ This action is missing the plan launch context.");break}let y;try{y=v.launchPlanOffer({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,worktreeStrategy:m.launchWorktreeStrategy})}catch(k){let S=k instanceof Error?k.message:String(k);await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ Failed to start planning session: ${S}`);break}await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`▶️ Planning session started: ${y.name} [${y.id}]`);break}case"plan-offer-dismiss":{await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!m.repoPolicy||!m.repoPolicyWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"⚠️ This action is missing the repo policy context.");break}if(!m.launchPrompt||!m.launchWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"⚠️ This action is missing the launch context.");break}if(typeof v.resolveRepoPolicy=="function"){let S=v.resolveRepoPolicy(m.repoPolicyWorkdir);if(S.identity){let b=qt(m.repoPolicy,S.prAvailable);if(b){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ ${b}`);break}}}let y=v.setRepoPolicy(m.repoPolicyWorkdir,m.repoPolicy);if(!y){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ Could not resolve a git repository for ${m.repoPolicyWorkdir}.`);break}v.clearRepoPolicyChoiceTokens(m.sessionId);let k;try{k=v.launchAfterRepoPolicyChoice({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,model:m.launchModel,reasoningEffort:m.launchReasoningEffort,fastMode:m.launchFastMode,systemPrompt:m.launchSystemPrompt,allowedTools:m.launchAllowedTools,resumeSessionId:m.launchResumeSessionId,resumeWorktreeFrom:m.launchResumeWorktreeFrom,sessionIdOverride:m.launchSessionIdOverride,clearedPersistedCodexResume:m.launchClearedPersistedCodexResume,forkSession:m.launchForkSession,forceNewSession:m.launchForceNewSession,permissionMode:m.launchPermissionMode,planApproval:m.launchPlanApproval,harness:m.launchHarness,worktreeStrategy:m.launchWorktreeStrategy,worktreeBaseBranch:m.launchWorktreeBaseBranch,worktreePrTargetRepo:m.launchWorktreePrTargetRepo,originAgentId:m.launchOriginAgentId}).text}catch(S){let b=S instanceof Error?S.message:String(S);await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ Repo policy saved, but launch failed: ${b}`);break}await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,[`✅ Repo policy saved: ${Ed(y.policy).title}.`,"",k].join(`
130
+ `));break}case"session-restart":case"session-resume":{await X(o,{alreadyAcknowledged:i});let y=await Pe(v,{session:l,message:"Continue where you left off.",userInitiated:!0});await O(o,y.isError?`⚠️ ${y.text}`:`▶️ ${y.text}`);break}case"view-output":{await X(o,{alreadyAcknowledged:i});let y=await Or().execute("callback",{session:l,lines:50});await O(o,io(y));break}default:{await X(o,{alreadyAcknowledged:i}),await O(o,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}K();ae();function Gt(t){return cl(t).map(e=>e.value)}function cl(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:tg(n),raw:n,start:r,end:r+n.length}})}function ht(t){let[e]=cl(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function tg(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function ng(t){return t instanceof Error?t.message:String(t)}function rg(t){let e=Gt(t),n,r=e;return e[0]==="--name"&&e[1]&&(n=e[1],r=e.slice(2)),{name:n,prompt:r.join(" ").trim()}}function pl(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}=rg(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=dr({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:mr(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=ng(i),a=s.includes("Max sessions")?"":`
131
+
132
+ Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${a}`}}}})}K();function ml(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:Er(v,"all",void 0,{full:n})}}})}K();function fl(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:Dr(v,n,"killed")}:{text:"Usage: /agent_kill <name-or-id>"}}})}K();function gl(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>
133
+ /agent_respond --interrupt <id-or-name> <message>`};let r=!1,o=n,i=ht(o);i?.value==="--interrupt"&&(r=!0,o=i.rest);let s=ht(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 Pe(v,{session:a,message:d,interrupt:r,userInitiated:!0})).text}:{text:"Error: Empty message. Usage: /agent_respond <id-or-name> <message>"}}})}K();function hl(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:ur(e,n)}}})}K();function og(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function yl(t){t.registerCommand({name:"agent_policy",description:"Inspect or set the current repo integration policy. Usage: /agent_policy [pr-required|pr-allowed|never-pr|manual|reset|list|cleanup]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let r=ht((e.args??"").trim())?.value;if(r==="list"){let a=v.listRepoPolicies();return{text:a.length===0?"No stored repo policies.":a.map(d=>`${d.policy} | ${d.provider} | ${d.repoRoot}`).join(`
134
+ `)}}if(r==="cleanup"){let a=v.cleanupRepoPolicies();return{text:a.length===0?"No stale repo policies found.":[`Removed ${a.length} stale repo ${a.length===1?"policy":"policies"}.`,...a.map(d=>`${d.policy} | ${d.provider} | ${d.repoRoot}`)].join(`
135
+ `)}}let o=e.workspaceDir;if(!o)return{text:"Error: workspaceDir is required."};if(r==="reset")return{text:v.resetRepoPolicy(o)?`Repo policy reset for ${o}.`:`No stored repo policy found for ${o}.`};if(r&&og(r)){if(typeof v.resolveRepoPolicy=="function"){let l=v.resolveRepoPolicy(o);if(l.identity){let u=qt(r,l.prAvailable);if(u)return{text:`Error: ${u}`}}}let a=v.setRepoPolicy(o,r);if(!a)return{text:`Error: ${o} is not a git repository.`};let d=`Repo policy set to ${a.policy} for ${a.repoRoot}.`;try{if(typeof v.continueLaunchAfterManualRepoPolicy!="function")return{text:d};let l=v.continueLaunchAfterManualRepoPolicy(a.repoRoot,r);if(l.kind==="launched")return{text:[d,"",l.text].join(`
136
+ `)};if(l.kind==="ambiguous")return{text:[d,"",`Repo policy saved, but ${l.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
137
+ `)}}catch(l){let u=l instanceof Error?l.message:String(l);return{text:[d,"",`Repo policy saved, but the deferred launch failed: ${u}`,"The pending launch context was kept so you can retry the same /agent_policy command or run the intended launch again."].join(`
138
+ `)}}return{text:d}}let i=v.resolveRepoPolicy(o);if(!i.identity)return{text:`No git repository found for ${o}.`};let s=bn(i.prAvailable).map(a=>a.policy).join(", ");return{text:[`Repo policy: ${i.policy??"unknown"}`,`Repo: ${i.identity.repoRoot}`,`Provider: ${i.provider}${i.prAvailable?"":" (PR automation unavailable)"}`,...i.identity.remoteUrl?[`Remote: ${i.identity.remoteUrl}`]:[],"",`Set with /agent_policy ${s}.`].join(`
139
+ `)}}})}K();var ig=50;function kl(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=Gt(n),o="",i=!1,s=ig;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:$r(v,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}K();var Sl="Usage: /goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function vl(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(!z)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:Sl};let r=Gt(n),o,i,s,a,d="bypassPermissions",l,u,c,p=[],f=[];for(let k=0;k<r.length;k++){let S=r[k];if(S==="--name"&&k+1<r.length)o=r[++k];else if(S==="--workdir"&&k+1<r.length)i=r[++k];else if(S==="--model"&&k+1<r.length)s=r[++k];else if(S==="--max-iterations"&&k+1<r.length){let b=parseInt(r[++k],10);!Number.isNaN(b)&&b>0&&(a=b)}else if(S==="--permission-mode"&&k+1<r.length){let b=r[++k];if(b==="default"||b==="plan"||b==="bypassPermissions")d=b;else return{text:`Error: Invalid permission mode "${b}".`}}else if(S==="--harness"&&k+1<r.length)l=r[++k];else if(S==="--mode"&&k+1<r.length){let b=r[++k];if(b==="ralph"||b==="verifier")u=b;else return{text:`Error: Invalid goal mode "${b}". Use ralph or verifier.`}}else if(S==="--completion-promise"&&k+1<r.length)c=r[++k];else if(S==="--verify"&&k+1<r.length){let b=r[++k].trim();if(!b)return{text:"Error: --verify commands must not be empty."};p.push(b)}else f.push(S)}let m=f.join(" ").trim();if(!m)return{text:Sl};let y=Yr({goal:m,verifierCommands:p,name:o,workdir:i,model:s,maxIterations:a,permissionMode:d,harness:l,goalMode:u,completionPromise:c},e);if(y.kind!=="resolved")return{text:y.text};try{let k=await z.launchTask({goal:y.goal,name:y.name,workdir:y.workdir,model:y.model,reasoningEffort:y.reasoningEffort,fastMode:y.fastMode,maxIterations:y.maxIterations,permissionMode:y.permissionMode,harness:y.harness,loopMode:y.loopMode,completionPromise:y.completionPromise,originChannel:y.originChannel,originThreadId:y.originThreadId,originAgentId:y.originAgentId,originSessionKey:y.originSessionKey,route:y.route,verifierCommands:y.verifierCommands});return{text:Zr(k,y)}}catch(k){return{text:`Error launching goal task: ${k instanceof Error?k.message:String(k)}`}}}})}K();function wl(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(!z)return{text:be};let n=(e.args??"").trim();return{text:eo(z,r=>v?.resolve(r),n)}}})}K();function Pl(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(!z)return{text:be};let n=(e.args??"").trim();if(!n)return{text:"Usage: /goal_stop <task-id-or-name>"};let r=z.stopTask(n);return{text:to(r,n)}}})}K();var bl="Usage: /goal_edit <task-id-or-name> <replacement-goal>";function Rl(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(!z)return{text:be};let n=(e.args??"").trim();if(!n)return{text:bl};let r=ht(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:bl};let s=z.editTask(o,i);return{text:no(s,o)}}})}import{execFile as Sg}from"child_process";import{createHash as Bl}from"crypto";import{existsSync as Dn,mkdirSync as sg,readFileSync as ag,renameSync as xl,writeFileSync as dg}from"fs";import{homedir as lg}from"os";import{dirname as ug,join as Tl}from"path";var cg=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function pg(t){let e=t.OPENCLAW_HOME?.trim();return e||Tl(lg(),".openclaw")}function mg(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||Tl(pg(t),"code-agent-goal-tasks.json")}function Cl(t){return t instanceof Error?t.message:String(t)}function Ml(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var fg=100;function Al(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function gg(t){if(!Dn(t))return;let e=Date.now(),n=Al(t,e);if(!Dn(n))return n;for(let r=1;r<=fg;r+=1){let o=Al(t,e,r);if(!Dn(o))return o}}function Il(t,e){try{let n=gg(t);return n?(xl(t,n),`${e}${n}`,!0):(Dn(t),!1)}catch(n){return`${Cl(n)}`,!1}}function hg(t){if(!Ml(t))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 yg(t){if(!Ml(t))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"||!cg.has(e.status))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:hg(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}}function kg(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=yg(n);if(!r)return;e.push(r)}return e}var ao=class{path;tasks=new Map;constructor(e=process.env){this.path=mg(e),this.load()}load(){try{if(!Dn(this.path))return;let e=ag(this.path,"utf8"),n=JSON.parse(e),r=kg(n);if(!r){Il(this.path,"invalid")&&this.save();return}this.tasks.clear();for(let o of r)this.tasks.set(o.id,o);this.save()}catch(e){if(e.code==="ENOENT")return;Il(this.path,"corrupt or unreadable")&&this.save()}}save(){try{sg(ug(this.path),{recursive:!0});let e=`${this.path}.tmp`;dg(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),xl(e,this.path)}catch(e){`${this.path}${Cl(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)}};xe();var vg=8,Fl=600*1e3,wg=4e3,ps=1200,Pg="DONE",bg=["BASH_ENV","ENV"];function Rg(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"goal-task"}function jt(t,e){return t.length<=e?t:`${t.slice(0,e-3)}...`}function tt(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(`
140
140
  `):n.slice(-e).join(`
141
- `)}function wg(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(`
142
- `):void 0}function Td(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Cd(t){let e=t?.trim();return e&&e.length>0?e:kg}function Pg(t){return t.route??Xt(t.originChannel,t.originThreadId,t.originSessionKey)}function cs(t){return t.map((e,n)=>({label:e.label.trim()||`check-${n+1}`,command:e.command.trim(),timeoutMs:e.timeoutMs??Nd})).filter(e=>e.command.length>0)}function bg(t){return t.loopMode==="verifier"}function Rg(t){return cs(t.verifierCommands).length>0}function Md(t){return bg(t)&&!Rg(t)}function so(){return"Verifier-mode goal tasks require at least one verifier command."}function _d(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${Ze(n.output,12)}`).join(`
143
- `);return Wd("sha1").update(e).digest("hex")}function Ag(t){return Wd("sha1").update(Ze(t,24)).digest("hex")}function $d(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 Ig(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(`
141
+ `)}function Ag(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(`
142
+ `):void 0}function _l(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function $l(t){let e=t?.trim();return e&&e.length>0?e:Pg}function Ig(t){return t.route??nn(t.originChannel,t.originThreadId,t.originSessionKey)}function ms(t){return t.map((e,n)=>({label:e.label.trim()||`check-${n+1}`,command:e.command.trim(),timeoutMs:e.timeoutMs??Fl})).filter(e=>e.command.length>0)}function xg(t){return t.loopMode==="verifier"}function Tg(t){return ms(t.verifierCommands).length>0}function El(t){return xg(t)&&!Tg(t)}function lo(){return"Verifier-mode goal tasks require at least one verifier command."}function Dl(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${tt(n.output,12)}`).join(`
143
+ `);return Bl("sha1").update(e).digest("hex")}function Cg(t){return Bl("sha1").update(tt(t,24)).digest("hex")}function Ol(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 Mg(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(`
144
144
  `);let e=t.verifierCommands.map(n=>`- ${n.label}: ${n.command}`).join(`
145
145
  `);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(`
146
- `)}function Ed(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(`
146
+ `)}function Wl(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(`
147
147
  `):["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(`
148
- `)}function xg(t,e){let n=e.steps.filter(o=>!o.ok).map(o=>[`- ${o.label} failed (exit ${o.exitCode})`,Ze(o.output,18)].join(`
148
+ `)}function _g(t,e){let n=e.steps.filter(o=>!o.ok).map(o=>[`- ${o.label} failed (exit ${o.exitCode})`,tt(o.output,18)].join(`
149
149
  `)).join(`
150
150
 
151
151
  `);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(`
152
- `)}function Tg(t,e){let n=Ze(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(`
153
- `)}function Cg(t,e){let n=e.steps.filter(r=>!r.ok).map(r=>[`- ${r.label} failed (exit ${r.exitCode})`,Ze(r.output,18)].join(`
152
+ `)}function $g(t,e){let n=tt(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(`
153
+ `)}function Eg(t,e){let n=e.steps.filter(r=>!r.ok).map(r=>[`- ${r.label} failed (exit ${r.exitCode})`,tt(r.output,18)].join(`
154
154
  `)).join(`
155
155
 
156
156
  `);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(`
157
- `)}function Mg(t,e){let n=e.trim();if(!n)return!1;let r=new RegExp(`(^|\\n)\\s*${Td(n)}\\s*(\\n|$)`,"i"),o=new RegExp(`<promise>\\s*${Td(n)}\\s*<\\/promise>`,"i");return r.test(t)||o.test(t)}function Dd(t){return t.steps.map(e=>`${e.ok?"PASS":"FAIL"} ${e.label} (exit ${e.exitCode}, ${Math.round(e.durationMs)}ms)`).join(`
158
- `)}function ft(t){return t instanceof Error?t.message:String(t)}function Od(t){return t==="succeeded"||t==="failed"||t==="stopped"}function _g(t){return Ut(t.error?.trim()||"Underlying session failed.",us)}function $g(t=process.env){let e={...t};for(let n of Sg)delete e[n];return e}function Eg(t,e){return new Promise(n=>{let r=Date.now();gg("bash",["-lc",e.command],{cwd:t,timeout:e.timeoutMs??Nd,maxBuffer:1024*1024,env:$g()},(o,i,s)=>{let a=Date.now()-r,l=typeof o?.code=="number"?o.code:o?1:0,d=`${i??""}${s?`
159
- ${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!o,exitCode:l,durationMs:a,output:Ut(d||"(no output)",yg)})})})}var ao=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 io}start(){this.started||(this.started=!0,!this.restorePromise&&(this.restorePromise=this.restoreRecoverableTasks().catch(e=>{`${ft(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=cs(e.verifierCommands);if(n==="verifier"&&r.length===0)throw new Error(so());let i={id:pr(8),name:vg(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??hg,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:Cd(e.completionPromise),verifierCommands:r,repeatedFailureCount:0},s=await this.spawnTaskSession(i,Ig(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
157
+ `)}function Dg(t,e){let n=e.trim();if(!n)return!1;let r=new RegExp(`(^|\\n)\\s*${_l(n)}\\s*(\\n|$)`,"i"),o=new RegExp(`<promise>\\s*${_l(n)}\\s*<\\/promise>`,"i");return r.test(t)||o.test(t)}function Nl(t){return t.steps.map(e=>`${e.ok?"PASS":"FAIL"} ${e.label} (exit ${e.exitCode}, ${Math.round(e.durationMs)}ms)`).join(`
158
+ `)}function yt(t){return t instanceof Error?t.message:String(t)}function Ll(t){return t==="succeeded"||t==="failed"||t==="stopped"}function Og(t){return jt(t.error?.trim()||"Underlying session failed.",ps)}function Wg(t=process.env){let e={...t};for(let n of bg)delete e[n];return e}function Ng(t,e){return new Promise(n=>{let r=Date.now();Sg("bash",["-lc",e.command],{cwd:t,timeout:e.timeoutMs??Fl,maxBuffer:1024*1024,env:Wg()},(o,i,s)=>{let a=Date.now()-r,d=typeof o?.code=="number"?o.code:o?1:0,l=`${i??""}${s?`
159
+ ${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!o,exitCode:d,durationMs:a,output:jt(l||"(no output)",wg)})})})}var uo=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 ao}start(){this.started||(this.started=!0,!this.restorePromise&&(this.restorePromise=this.restoreRecoverableTasks().catch(e=>{`${yt(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=ms(e.verifierCommands);if(n==="verifier"&&r.length===0)throw new Error(lo());let i={id:fr(8),name:Rg(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??vg,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:$l(e.completionPromise),verifierCommands:r,repeatedFailureCount:0},s=await this.spawnTaskSession(i,Mg(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
160
160
 
161
161
  Goal:
162
- ${Ut(i.goal,500)}`,"goal-task-started"),i}stopTask(e){let n=this.store.get(e);if(n)return Od(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(Od(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
162
+ ${jt(i.goal,500)}`,"goal-task-started"),i}stopTask(e){let n=this.store.get(e);if(n)return Ll(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(Ll(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
163
163
 
164
164
  Goal:
165
- ${Ut(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}=vt({requestedResumeSessionId:o,activeSession:i?{harnessSessionId:i.harnessSessionId}:void 0,persistedSession:s?{harness:s.harness,backendRef:s.backendRef}:void 0}),l={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:Pg(e),permissionMode:e.permissionMode,multiTurn:!0,goalTaskId:e.id,harness:e.harness,resumeSessionId:a,resumeWorktreeFrom:o,worktreeStrategy:"off"};return this.sessionManager.spawnAndAwaitRunning(l,{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(`
166
- `));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(Md(e)){this.markTaskFailed(e,so());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,Ed(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: ${ft(r)}`)}}}async runVerifiers(e){let n=cs(e.verifierCommands);if(n.length===0){let s={status:"fail",steps:[{label:"verifier-config",command:"(none configured)",ok:!1,exitCode:1,durationMs:0,output:so()}],summary:"",fingerprint:""};return s.fingerprint=_d(s),s.summary=Dd(s),s}let r=[];for(let s of n)r.push(await Eg(e.workdir,s));let i={status:r.every(s=>s.ok)?"pass":"fail",steps:r,summary:"",fingerprint:""};return i.fingerprint=_d(i),i.summary=Dd(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=wg(o),l=a?`${s}
165
+ ${jt(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}=bt({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:Ig(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(`
166
+ `));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(El(e)){this.markTaskFailed(e,lo());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,Wl(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: ${yt(r)}`)}}}async runVerifiers(e){let n=ms(e.verifierCommands);if(n.length===0){let s={status:"fail",steps:[{label:"verifier-config",command:"(none configured)",ok:!1,exitCode:1,durationMs:0,output:lo()}],summary:"",fingerprint:""};return s.fingerprint=Dl(s),s.summary=Nl(s),s}let r=[];for(let s of n)r.push(await Ng(e.workdir,s));let i={status:r.every(s=>s.ok)?"pass":"fail",steps:r,summary:"",fingerprint:""};return i.fingerprint=Dl(i),i.summary=Nl(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=Ag(o),d=a?`${s}
167
167
 
168
- ${a}`:s;this.notify(e,l,"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}${ft(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=Ut(n,us),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`❌ [${e.name}] Goal task failed
168
+ ${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}${yt(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=jt(n,ps),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`❌ [${e.name}] Goal task failed
169
169
 
170
170
  ${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
171
171
 
172
- ${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=Ut(n,us),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`⛔ [${e.name}] Goal task stopped
172
+ ${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=jt(n,ps),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`⛔ [${e.name}] Goal task stopped
173
173
 
174
- ${e.failureReason}`,"goal-task-stopped")}async handleRunningSession(e,n){if(n.pendingPlanApproval){let s=await we(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(`
175
- `),o=$d(r);if(!o){this.markTaskFailedWaitingForUser(e,Ze(r,24)||"The session is waiting for user input.");return}let i=await we(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: ${ft(o)}`)}}async handleTerminalSession(e,n){if(n.status==="failed"){this.markTaskFailed(e,_g(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(`
176
- `);if(n.pendingPlanApproval){let a=await we(this.sessionManager,{session:n.id,message:"Approved. Implement the plan.",approve:!0,userInitiated:!1});if(a.isError){this.markTaskFailed(e,a.text);return}let l=this.sessionManager.resolve(n.id);if(!l){this.markTaskFailed(e,"Failed to resolve the resumed goal task session after idle timeout plan approval.");return}this.attachSessionObservers(e,l),this.setTaskRunningWithSession(e,l),this.notifyIterationStatus(e,`🔄 [${e.name}] Goal task resumed after idle timeout`,l),this.scheduleTaskEvaluation(e.id,"idle-timeout-plan-resume",l.id);return}if(n.pendingInputState){let a=$d(s);if(!a){this.markTaskFailed(e,`Goal task was waiting for user input and cannot continue autonomously: ${Ze(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(`
174
+ ${e.failureReason}`,"goal-task-stopped")}async handleRunningSession(e,n){if(n.pendingPlanApproval){let s=await Pe(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(`
175
+ `),o=Ol(r);if(!o){this.markTaskFailedWaitingForUser(e,tt(r,24)||"The session is waiting for user input.");return}let i=await Pe(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: ${yt(o)}`)}}async handleTerminalSession(e,n){if(n.status==="failed"){this.markTaskFailed(e,Og(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(`
176
+ `);if(n.pendingPlanApproval){let a=await Pe(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=Ol(s);if(!a){this.markTaskFailed(e,`Goal task was waiting for user input and cannot continue autonomously: ${tt(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(`
177
177
 
178
- `));return}await this.resumeAfterIdleTimeout(e,n,Ed(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(`
179
- `),a=Cd(e.completionPromise);if(Mg(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(`
178
+ `));return}await this.resumeAfterIdleTimeout(e,n,Wl(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(`
179
+ `),a=$l(e.completionPromise);if(Dg(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(`
180
180
  `));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(`
181
- `));return}e.iteration+=1;let f=Cg(e,p),m=Yr({output:s,verifierSummary:p.summary,completionPromise:a,completionDetected:!0});try{let y=await this.resumeTaskSession(e,f,n);this.setTaskRunningWithSession(e,y),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,m),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",y.id)}catch(y){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${ft(y)}`)}return}let d=Ag(s);if(e.lastVerifierFingerprint===d?e.repeatedFailureCount+=1:e.repeatedFailureCount=1,e.lastVerifierFingerprint=d,e.iteration+1>=e.maxIterations){this.markTaskFailed(e,[`Completion promise "${a}" was not emitted before hitting the iteration budget (${e.maxIterations}).`,"Latest output:",Ze(s,20)||"(no output)"].join(`
182
- `));return}e.iteration+=1;let u=Tg(e,s),c=Yr({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: ${ft(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(`
183
- `));return}e.iteration+=1;let o=xg(e,r),i=Yr({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: ${ft(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(Md(e)){this.markTaskFailed(e,so());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)}}}}};import{createHash as Gu}from"crypto";ae();import{existsSync as Dg,realpathSync as Og}from"fs";import{resolve as Wg}from"path";function Ld(t){if(!t)return;let e=Wg(t);try{if(Dg(e))return Og.native(e)}catch{}return e}function lo(t,e){return!t||!e?!1:Ld(t)===Ld(e)}X();ae();import{existsSync as Ng}from"fs";X();ke();function Bd(t){return t instanceof Error?t.message:String(t)}function Lg(t){let e=t.worktreeStrategy??D.defaultWorktreeStrategy;return!!e&&e!=="off"&&Ri(cn({harnessName:t.harness??de(),backendRef:t.backendRef}))}function Bg(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(`
184
- `);return(t??"")+o}function Fg(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=wr(r.worktreePath);return r.workdir&&a&&lo(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&&or(cn({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=or(cn({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(Ng(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{br(i);let a=_i(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:i,worktreePath:a,worktreeBranchName:r.worktreeBranch}}catch(a){return`${Bd(a)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function Fd(t,e,n){let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:d,canCreateManagedWorktreeForResumeWithoutPersistedPath:u,failedResumeWorktreeRestore:c}=Fg(t,n);a&&(t.resumeSessionId=void 0),l&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,o??=t.workdir;let p=!!(t.resumeSessionId??t.resumeWorktreeFrom),f=t.worktreeStrategy??D.defaultWorktreeStrategy;f&&(t.worktreeStrategy=f);let m=Lg(t),k=(!p||!!u)&&!d&&!i&&f&&f!=="off"&&!m;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(m&&!Ci(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" requires a git worktree, but "${o}" is not a git repository.`);if(k&&Ci(o)){if(!Ya(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=_i(o,e),r=i,s=Et(i),!s)throw new Error(`created worktree at ${i} but failed to resolve branch name`);`${i}`}catch(S){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${Bd(S)}`)}}else if(k)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?Bg(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:d,failedResumeWorktreeRestore:c}}var uo=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return Fd(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)}};X();var co=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=E(e),o=E(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(U(o)===e||E(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])}};X();var qg=new Set(["starting","running"]),po=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=>E(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?E(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),qg.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};X();X();ke();import{existsSync as Kg}from"fs";var qd=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),mo=class{constructor(e){this.deps=e}deps;async plan(e){let n=U(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=qd.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&qd.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 l=ue(e);if(l&&!Kg(i))return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:l};let d=e.worktreeBaseBranch??_e(s),u=this.deps.getWorktreeCompletionState(s,i,a,d);if(u==="no-change")return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:l};if(u==="merged")return{kind:"merged",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:l};if(u==="released")return{kind:"released",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:l,reasons:["merge_noop_content_already_on_base"]};if(u==="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(u==="dirty-uncommitted")return{kind:"dirty-uncommitted",worktreePath:i,branchName:a,baseBranch:d};let c=Le(s,a,d);if(!c)return`${a}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let p=e.repoIntegrationPolicy?void 0:this.deps.resolveRepoPolicy?.(s),f=e.repoIntegrationPolicy??p?.policy,m=e.repoIntegrationPolicy?this.deps.isPrAvailable(s):p?.prAvailable??this.deps.isPrAvailable(s),y=El({requestedStrategy:o,policy:f,prAvailable:m,existingOpenPr:!1});return y.strategy?{kind:"decision",strategy:y.strategy,policy:f,policyReason:y.reason,policyBlocked:y.blocked,allowedActions:y.allowedActions,repoDir:s,worktreePath:i,branchName:a,baseBranch:d,diffSummary:c,sessionRef:n??void 0}:{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}}}};Rn();function Ug(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 Vg(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function Gg(){return/https?:\/\/\S+/gi}function fo(t){let e=Ug(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function ps(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 jg(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function Hg(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function zg(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function ms(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 Qg(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 fs(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=`$${(e.costUsd??0).toFixed(2)}`,s=xe(e.duration),a=jg(),l=d=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...fo(e),"","Output preview:",r,"",...Qg({contract:a,canonicalStatusDelivered:d}),"",...ms({sessionId:e.id,canonicalStatusDelivered:d,hasOriginRouteBlock:o})].join(`
185
- `);return{userMessage:`✅ [${e.name}] Completed | ${i} | ${s}${ar({harness:e.harnessName,model:e.model})}`,wakeMessageOnNotifySuccess:l(!0),wakeMessageOnNotifyFailed:l(!1),followupContract:a}}function Vt(t){let e=Hg(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>Kd(i).trim()).filter(i=>i.length>0),o=Kd(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(`
186
- `)}function gs(t){let e=zg(),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(`
187
- `)}function Kd(t){return t.replace(Vg(),"PR #$1").replace(Gg(),"[link omitted]")}function hs(t){let{session:e,originThreadLine:n,errorSummary:r,preview:o,worktreeAutoCleaned:i,failedButtons:s}=t,a=o.trim()?["","Output preview:",o]:[],l=i?["","Note: Worktree and branch were auto-removed (zero cost, startup failure)."]:[],d=`$${(e.costUsd??0).toFixed(2)}`,u=xe(e.duration);return{userMessage:[`❌ [${e.name}] Failed | ${d} | ${u}${ar({harness:e.harnessName,model:e.model})}`,` ⚠️ ${r}`].join(`
188
- `),wakeMessage:["Coding agent session failed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,n,...fo(e),...e.harnessSessionId?[`Backend conversation ID: ${e.harnessSessionId}`]:[],"","Failure summary:",r,...a,...l,"","[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(`
189
- `),buttons:s}}function ys(t){let{session:e,originThreadLine:n,preview:r}=t,o=`$${(e.costUsd??0).toFixed(2)}`;return{userMessage:`⏸️ [${e.name}] Turn completed | ${o}${ar({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(`
190
- `)}}function ks(t){let{sessionName:e,sessionId:n,branchName:r,baseBranch:o,promptSnippet:i,commitLines:s,moreNote:a,originThreadLine:l,diffSummary:d,allowedActions:u,policyReason:c}=t,p=!!l?.trim();return[`[DELEGATED WORKTREE DECISION] Session "${e}" completed with changes.`,"",`Session ID: ${n}`,`Branch: ${r} → ${o}`,`Commits: ${d.commits} | Files: ${d.filesChanged} | +${d.insertions} / -${d.deletions}`,...p?[l]:[],"",...s,...a?[a]:[],"","Original task prompt (first 500 chars):",i,"",...c?[`Policy constraint: ${c}`,""]:[],"You own the next step for this worktree.",...u?.merge===!1?["- Do not call agent_merge(); repo policy does not allow direct merge for this session."]:[`- Merge immediately with agent_merge(session="${e}", base_branch="${o}") if the changes are clearly in-scope and low-risk.`],...u?.pr===!1?["- Do not call agent_pr(); PR creation is unavailable or forbidden by repo policy."]:[`- 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.",...p?["- 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(`
191
- `)}function Ss(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(`
192
- `)}function vs(t){let{sessionName:e,sessionId:n,cleanupSummary:r,preview:o,originThreadLine:i,requestedPermissionMode:s,currentPermissionMode:a,approvalExecutionState:l,approvalState:d,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:p,approvalPromptDeliveredAt:f}=t,m=o.trim()?["","Output preview:",o]:[],y=!!i?.trim();return["Coding agent session completed with no worktree changes to merge.",`Name: ${e} | ID: ${n}`,`Worktree outcome: ${r}`,...y?[i]:[],...fo({requestedPermissionMode:s,currentPermissionMode:a,approvalExecutionState:l,approvalState:d,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:p,approvalPromptDeliveredAt:f}),...m,"",...ms({sessionId:n,canonicalStatusDetail:"The plugin already sent the canonical completion status to the user, including the no-worktree-changes outcome.",hasOriginRouteBlock:y})].join(`
193
- `)}var Gd=3200,ws=3e3,Jg=2400,Yg=120,Zg=5,Xg=280,Ud=1400,Vd="- Additional plan details omitted for brevity.";function jd(t){return t.replace(/^#{1,6}\s+/,"").replace(/^[-*+]\s+/,"").replace(/^\d+[.)]\s+/,"").replace(/^`([^`]+)`$/,"$1").trim()}function eh(t){return t.split(`
194
- `).map(e=>e.trim()).filter(Boolean).map(jd).map(e=>le(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 th(t){return t.split(`
195
- `).map(e=>e.trim()).filter(Boolean).map(jd).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 Ps(t){let e=eh(t);return e.length===0?`Review summary:
181
+ `));return}e.iteration+=1;let f=Eg(e,p),m=Xr({output:s,verifierSummary:p.summary,completionPromise:a,completionDetected:!0});try{let y=await this.resumeTaskSession(e,f,n);this.setTaskRunningWithSession(e,y),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,m),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",y.id)}catch(y){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${yt(y)}`)}return}let l=Cg(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:",tt(s,20)||"(no output)"].join(`
182
+ `));return}e.iteration+=1;let u=$g(e,s),c=Xr({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: ${yt(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(`
183
+ `));return}e.iteration+=1;let o=_g(e,r),i=Xr({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: ${yt(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(El(e)){this.markTaskFailed(e,lo());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)}}}}};import{createHash as Qu}from"crypto";ae();import{existsSync as Lg,realpathSync as Bg}from"fs";import{resolve as Fg}from"path";function ql(t){if(!t)return;let e=Fg(t);try{if(Lg(e))return Bg.native(e)}catch{}return e}function co(t,e){return!t||!e?!1:ql(t)===ql(e)}ee();ae();import{existsSync as qg}from"fs";ee();ke();function Kl(t){return t instanceof Error?t.message:String(t)}function Kg(t){let e=t.worktreeStrategy??E.defaultWorktreeStrategy;return!!e&&e!=="off"&&Ii(fn({harnessName:t.harness??le(),backendRef:t.backendRef}))}function Ug(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(`
184
+ `);return(t??"")+o}function Vg(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=br(r.worktreePath);return r.workdir&&a&&co(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&&sr(fn({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=sr(fn({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(qg(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{Ar(i);let a=Ei(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:i,worktreePath:a,worktreeBranchName:r.worktreeBranch}}catch(a){return`${Kl(a)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function Ul(t,e,n){let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,canCreateManagedWorktreeForResumeWithoutPersistedPath:u,failedResumeWorktreeRestore:c}=Vg(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 m=Kg(t),k=(!p||!!u)&&!l&&!i&&f&&f!=="off"&&!m;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(m&&!_i(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" requires a git worktree, but "${o}" is not a git repository.`);if(k&&_i(o)){if(!Xa(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=Ei(o,e),r=i,s=Ze(i),!s)throw new Error(`created worktree at ${i} but failed to resolve branch name`);`${i}`}catch(S){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${Kl(S)}`)}}else if(k)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?Ug(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,failedResumeWorktreeRestore:c}}var po=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return Ul(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)}};ee();var mo=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=$(e),o=$(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(V(o)===e||$(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])}};ee();var Gg=new Set(["starting","running"]),fo=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=>$(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?$(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),Gg.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};ee();ee();ke();import{existsSync as jg}from"fs";var Vl=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),go=class{constructor(e){this.deps=e}deps;async plan(e){let n=V(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=Vl.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&Vl.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=ue(e);if(d&&!jg(i))return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};let l=e.worktreeBaseBranch??$e(s),u=this.deps.getWorktreeCompletionState(s,i,a,l);if(u==="no-change")return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};if(u==="merged")return{kind:"merged",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};if(u==="released")return{kind:"released",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d,reasons:["merge_noop_content_already_on_base"]};if(u==="base-advanced")return{kind:"notify",label:"worktree-no-commits-ahead",message:`⚠️ [${e.name}] Auto-merge: branch '${a}' has no commits ahead of '${l}', but '${l}' has new commits — commits likely landed outside the worktree branch. Verify that commits were not made directly to '${l}' instead of the worktree branch. Worktree: ${i}`};if(u==="dirty-uncommitted")return{kind:"dirty-uncommitted",worktreePath:i,branchName:a,baseBranch:l};let c=Be(s,a,l);if(!c)return`${a}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let p=e.repoIntegrationPolicy?void 0:this.deps.resolveRepoPolicy?.(s),f=e.repoIntegrationPolicy??p?.policy,m=e.repoIntegrationPolicy?this.deps.isPrAvailable(s):p?.prAvailable??this.deps.isPrAvailable(s),y=Wd({requestedStrategy:o,policy:f,prAvailable:m,existingOpenPr:!1});return y.strategy?{kind:"decision",strategy:y.strategy,policy:f,policyReason:y.reason,policyBlocked:y.blocked,allowedActions:y.allowedActions,repoDir:s,worktreePath:i,branchName:a,baseBranch:l,diffSummary:c,sessionRef:n??void 0}:{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}}}};In();function Hg(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 zg(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function Qg(){return/https?:\/\/\S+/gi}function ho(t){let e=Hg(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function fs(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 Jg(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function Yg(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function Zg(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function gs(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 Xg(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 hs(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=`$${(e.costUsd??0).toFixed(2)}`,s=Te(e.duration),a=Jg(),d=l=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...ho(e),"","Output preview:",r,"",...Xg({contract:a,canonicalStatusDelivered:l}),"",...gs({sessionId:e.id,canonicalStatusDelivered:l,hasOriginRouteBlock:o})].join(`
185
+ `);return{userMessage:`✅ [${e.name}] Completed | ${i} | ${s}${lr({harness:e.harnessName,model:e.model})}`,wakeMessageOnNotifySuccess:d(!0),wakeMessageOnNotifyFailed:d(!1),followupContract:a}}function Ht(t){let e=Yg(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>Gl(i).trim()).filter(i=>i.length>0),o=Gl(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(`
186
+ `)}function ys(t){let e=Zg(),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(`
187
+ `)}function Gl(t){return t.replace(zg(),"PR #$1").replace(Qg(),"[link omitted]")}function ks(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=Te(e.duration);return{userMessage:[`❌ [${e.name}] Failed | ${l} | ${u}${lr({harness:e.harnessName,model:e.model})}`,` ⚠️ ${r}`].join(`
188
+ `),wakeMessage:["Coding agent session failed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,n,...ho(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(`
189
+ `),buttons:s}}function Ss(t){let{session:e,originThreadLine:n,preview:r}=t,o=`$${(e.costUsd??0).toFixed(2)}`;return{userMessage:`⏸️ [${e.name}] Turn completed | ${o}${lr({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(`
190
+ `)}}function vs(t){let{sessionName:e,sessionId:n,branchName:r,baseBranch:o,promptSnippet:i,commitLines:s,moreNote:a,originThreadLine:d,diffSummary:l,allowedActions:u,policyReason:c}=t,p=!!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}`,...p?[d]:[],"",...s,...a?[a]:[],"","Original task prompt (first 500 chars):",i,"",...c?[`Policy constraint: ${c}`,""]:[],"You own the next step for this worktree.",...u?.merge===!1?["- Do not call agent_merge(); repo policy does not allow direct merge for this session."]:[`- Merge immediately with agent_merge(session="${e}", base_branch="${o}") if the changes are clearly in-scope and low-risk.`],...u?.pr===!1?["- Do not call agent_pr(); PR creation is unavailable or forbidden by repo policy."]:[`- 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.",...p?["- 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(`
191
+ `)}function ws(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(`
192
+ `)}function Ps(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,m=o.trim()?["","Output preview:",o]:[],y=!!i?.trim();return["Coding agent session completed with no worktree changes to merge.",`Name: ${e} | ID: ${n}`,`Worktree outcome: ${r}`,...y?[i]:[],...ho({requestedPermissionMode:s,currentPermissionMode:a,approvalExecutionState:d,approvalState:l,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:p,approvalPromptDeliveredAt:f}),...m,"",...gs({sessionId:n,canonicalStatusDetail:"The plugin already sent the canonical completion status to the user, including the no-worktree-changes outcome.",hasOriginRouteBlock:y})].join(`
193
+ `)}var zl=3200,bs=3e3,eh=2400,th=120,nh=5,rh=280,jl=1400,Hl="- Additional plan details omitted for brevity.";function Ql(t){return t.replace(/^#{1,6}\s+/,"").replace(/^[-*+]\s+/,"").replace(/^\d+[.)]\s+/,"").replace(/^`([^`]+)`$/,"$1").trim()}function oh(t){return t.split(`
194
+ `).map(e=>e.trim()).filter(Boolean).map(Ql).map(e=>de(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 ih(t){return t.split(`
195
+ `).map(e=>e.trim()).filter(Boolean).map(Ql).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 Rs(t){let e=oh(t);return e.length===0?`Review summary:
196
196
  - Plan details are available in the full session output.`:["Review summary:",...e.slice(0,6).map(n=>`- ${n}`)].join(`
197
- `)}function nh(t){let e=[],n=!1;for(let o of t){let i=o.replace(/\s+/g," ").trim();if(!i)continue;let s=le(i,Xg);s.length<i.length&&(n=!0);let a=`- ${s}`;if(e.length>=Zg||[...e,a].join(`
198
- `).length>Ud){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,Vd].join(`
199
- `).length>Ud;)r.pop();return[...r,Vd]}function bs(t){return nh(th(t)).join(`
200
- `)}function rh(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 oh(t,e){let n=t.split(`
201
- `),r=[],o="",i=()=>{o.trim().length>0&&(r.push(o.trimEnd()),o="")};for(let s of n){if(s.length>e){i();for(let l of rh(s,e))r.push(l);continue}let a=o.length>0?`${o}
202
- ${s}`:s;if(a.length>e){i(),o=s;continue}o=a}return i(),r}function Hd(t){return le(t.trim(),Yg)}function zd(t,e){return e?t?`
197
+ `)}function sh(t){let e=[],n=!1;for(let o of t){let i=o.replace(/\s+/g," ").trim();if(!i)continue;let s=de(i,rh);s.length<i.length&&(n=!0);let a=`- ${s}`;if(e.length>=nh||[...e,a].join(`
198
+ `).length>jl){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,Hl].join(`
199
+ `).length>jl;)r.pop();return[...r,Hl]}function As(t){return sh(ih(t)).join(`
200
+ `)}function ah(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 dh(t,e){let n=t.split(`
201
+ `),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 ah(s,e))r.push(d);continue}let a=o.length>0?`${o}
202
+ ${s}`:s;if(a.length>e){i(),o=s;continue}o=a}return i(),r}function Jl(t){return de(t.trim(),th)}function Yl(t,e){return e?t?`
203
203
 
204
204
  Choose Approve, Revise, or Reject below.`:`
205
205
 
206
206
  Approval is still pending for this plan version.`:`
207
207
 
208
- Continued in next message.`}function ih(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=`📋 [${e}] Plan v${n??"?"} ready for approval:`,s=`
208
+ Continued in next message.`}function lh(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=`📋 [${e}] Plan v${n??"?"} ready for approval:`,s=`
209
209
 
210
210
  Full plan (truncated):
211
- `,a=zd(o,!0),l=Math.max(0,ws-i.length-s.length-a.length);return`${i}${s}${le(r,l)}${a}`}function sh(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=Hd(e),s=Jg;for(;s>0;){let a=oh(r,s),l=a.map((c,p)=>{let f=a.length,m=[`📋 [${i}] Plan v${n??"?"} ready for approval (${p+1}/${f}):`,"",p===0?"Full plan:":""].filter(Boolean).join(`
212
- `),y=zd(o,p===f-1);return`${m}
213
- ${c}${y}`}),d=l.reduce((c,p)=>Math.max(c,p.length),0);if(d<=ws)return l;let u=d-ws;s-=Math.max(u,50)}return[ih({sessionName:i,actionableVersion:n,fullPlanText:r,hasButtons:o})]}function Rs(t){let{preview:e,artifact:n}=t,r=n?.markdown?.trim();return r&&r.length<=Gd?`Full plan:
214
- ${r}`:Ps(r||e)}function Qd(t){let{sessionName:e,actionableVersion:n,preview:r,artifact:o,hasButtons:i}=t,s=o?.markdown?.trim(),a=Hd(e);if(s){let d=`📋 [${a}] Plan v${n??"?"} ready for approval:
211
+ `,a=Yl(o,!0),d=Math.max(0,bs-i.length-s.length-a.length);return`${i}${s}${de(r,d)}${a}`}function uh(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=Jl(e),s=eh;for(;s>0;){let a=dh(r,s),d=a.map((c,p)=>{let f=a.length,m=[`📋 [${i}] Plan v${n??"?"} ready for approval (${p+1}/${f}):`,"",p===0?"Full plan:":""].filter(Boolean).join(`
212
+ `),y=Yl(o,p===f-1);return`${m}
213
+ ${c}${y}`}),l=d.reduce((c,p)=>Math.max(c,p.length),0);if(l<=bs)return d;let u=l-bs;s-=Math.max(u,50)}return[lh({sessionName:i,actionableVersion:n,fullPlanText:r,hasButtons:o})]}function Is(t){let{preview:e,artifact:n}=t,r=n?.markdown?.trim();return r&&r.length<=zl?`Full plan:
214
+ ${r}`:Rs(r||e)}function Zl(t){let{sessionName:e,actionableVersion:n,preview:r,artifact:o,hasButtons:i}=t,s=o?.markdown?.trim(),a=Jl(e);if(s){let l=`📋 [${a}] Plan v${n??"?"} ready for approval:
215
215
 
216
216
  Full plan:
217
217
  ${s}
218
218
 
219
- ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`;return d.length<=Gd?{displayMode:"single-full-plan",userMessages:[d],reviewSummary:`Full plan:
220
- ${s}`}:{displayMode:"chunked-full-plan",userMessages:sh({sessionName:e,actionableVersion:n,fullPlanText:s,hasButtons:i}),reviewSummary:Ps(s)}}let l=Ps(r);return{displayMode:"summary",userMessages:[`📋 [${a}] Plan v${n??"?"} ready for approval:
219
+ ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`;return l.length<=zl?{displayMode:"single-full-plan",userMessages:[l],reviewSummary:`Full plan:
220
+ ${s}`}:{displayMode:"chunked-full-plan",userMessages:uh({sessionName:e,actionableVersion:n,fullPlanText:s,hasButtons:i}),reviewSummary:Rs(s)}}let d=Rs(r);return{displayMode:"summary",userMessages:[`📋 [${a}] Plan v${n??"?"} ready for approval:
221
221
 
222
- ${l}
222
+ ${d}
223
223
 
224
- ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`],reviewSummary:l}}function Jd(t){let e=t?.trim();return e||void 0}function ah(t){let e=Jd(t.questionText)??"The session is waiting for your reply.",n=Jd(t.contextSummary);return n?[`❓ [${t.sessionName}] Question waiting for reply:`,"",e,"",`Why: ${n}`].join(`
224
+ ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`],reviewSummary:d}}function Xl(t){let e=t?.trim();return e||void 0}function ch(t){let e=Xl(t.questionText)??"The session is waiting for your reply.",n=Xl(t.contextSummary);return n?[`❓ [${t.sessionName}] Question waiting for reply:`,"",e,"",`Why: ${n}`].join(`
225
225
  `):`❓ [${t.sessionName}] Question waiting for reply:
226
226
 
227
- ${e}`}function lh(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function En(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(`
228
- `)}function As(t){let{session:e,preview:n,questionText:r,questionContextSummary:o,planArtifact:i,originThreadLine:s,planApprovalMode:a,planApprovalButtons:l,questionButtons:d}=t,u=e.pendingPlanApproval,c=e.actionablePlanDecisionVersion??e.planDecisionVersion,p=lh(e,c),f=a??"delegate",m=u&&f==="ask"&&!p?Qd({sessionName:e.name,actionableVersion:c,preview:n,artifact:i,hasButtons:!!l}):void 0,y=u?m?.reviewSummary??Rs({preview:n,artifact:i}):void 0,k=u?m&&m.userMessages.length===1?m.userMessages[0]:void 0:ah({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!d}),S=u&&m&&m.userMessages.length>1?m.userMessages.map((A,x,R)=>({text:A,buttons:x===R.length-1?l:void 0})):void 0;if(u){let A=f,x="Permission mode: plan → will switch to bypassPermissions on approval";return A==="delegate"?{label:"plan-approval",userMessage:k,userMessages:S,planReviewSummary:y,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,x,"","⚠️ 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(`
227
+ ${e}`}function ph(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function On(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(`
228
+ `)}function xs(t){let{session:e,preview:n,questionText:r,questionContextSummary:o,planArtifact:i,originThreadLine:s,planApprovalMode:a,planApprovalButtons:d,questionButtons:l}=t,u=e.pendingPlanApproval,c=e.actionablePlanDecisionVersion??e.planDecisionVersion,p=ph(e,c),f=a??"delegate",m=u&&f==="ask"&&!p?Zl({sessionName:e.name,actionableVersion:c,preview:n,artifact:i,hasButtons:!!d}):void 0,y=u?m?.reviewSummary??Is({preview:n,artifact:i}):void 0,k=u?m&&m.userMessages.length===1?m.userMessages[0]:void 0:ch({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!l}),S=u&&m&&m.userMessages.length>1?m.userMessages.map((A,x,R)=>({text:A,buttons:x===R.length-1?d:void 0})):void 0;if(u){let A=f,x="Permission mode: plan → will switch to bypassPermissions on approval";return A==="delegate"?{label:"plan-approval",userMessage:k,userMessages:S,planReviewSummary:y,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,x,"","⚠️ 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(`
229
229
  `)}:A==="ask"?{label:"plan-approval",userMessage:k,userMessages:S,planReviewSummary:y,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,x,"","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(`
230
- `),buttons:S?void 0:l}:{label:"plan-approval",userMessage:k,planReviewSummary:y,wakeMessage:["[AUTO-APPROVE] Session has a plan ready. Approve it now:",`agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true)`].join(`
230
+ `),buttons:S?void 0:d}:{label:"plan-approval",userMessage:k,planReviewSummary:y,wakeMessage:["[AUTO-APPROVE] Session has a plan ready. Approve it now:",`agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true)`].join(`
231
231
  `)}}let b=e.multiTurn?"Multi-turn session":"Session";return{label:"waiting",userMessage:k,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.]`,"",`${b} 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(`
232
- `),buttons:d}}var go=3,Is=180,dh=4e3,Yd=32;function Zd(){let t=_t(),e=yh(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=kh(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 uh(t,e){let n=Sh(e);if(n.length>0)return n;let r=ch(t);if(r.length>0)return r;let o=[],i=t.changedFiles.slice(0,3).map(a=>`\`${a}\``);if(i.length>0){let a=t.changedFiles.length-i.length;o.push(a>0?`Touches ${i.join(", ")} and ${a} more file${a===1?"":"s"}`:`Touches ${i.join(", ")}`)}let s=[...new Set(t.commitMessages.map(a=>a.message.trim()).filter(Boolean))].slice(0,2);return s.length>0&&o.push(`Recent work: ${s.join("; ")}`),o}function ch(t){let e=new Set,n=t.commitMessages.length===1?t.changedFiles:[];return t.commitMessages.map(r=>ph(r.message,n)).filter(r=>!!r).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,go)}function ph(t,e){let n=mh(t);if(!n)return;let r=e.length===1?` in \`${e[0]}\``:e.length>1&&e.length<=3?` across ${e.map(o=>`\`${o}\``).join(", ")}`:"";return xs(`${n}${r}.`,Is)}function mh(t){let e=ho(yo(t)).replace(/^(?:feat|fix|docs|style|refactor|perf|test|tests|build|ci|chore|revert)(?:\([^)]+\))?!?:\s*/i,"").replace(/\.$/,"").trim();if(!e||Ts(e))return;let n=e.match(/^([a-z]+)\b(.*)$/i);if(!n)return e;let r=n[1].toLowerCase(),o=n[2]??"",s=new Map([["add","Adds"],["address","Addresses"],["block","Blocks"],["change","Changes"],["clarify","Clarifies"],["clean","Cleans"],["cover","Covers"],["create","Creates"],["deduplicate","Deduplicates"],["delete","Deletes"],["disable","Disables"],["document","Documents"],["enable","Enables"],["extract","Extracts"],["fix","Fixes"],["guard","Guards"],["harden","Hardens"],["implement","Implements"],["improve","Improves"],["init","Initializes"],["initialize","Initializes"],["migrate","Migrates"],["move","Moves"],["normalize","Normalizes"],["preserve","Preserves"],["prevent","Prevents"],["refactor","Refactors"],["remove","Removes"],["rename","Renames"],["restore","Restores"],["simplify","Simplifies"],["tighten","Tightens"],["update","Updates"],["use","Uses"],["wire","Wires"],["wrap","Wraps"]]).get(r);return s?`${s}${o}`:`${r[0].toUpperCase()}${r.slice(1)}${o}`}async function Xd(t){let e=fh(t),n=uh(t.diffSummary??{changedFiles:e.changedFiles,commitMessages:e.commitSubjects.map(r=>({message:r}))},t.outputPreview);if(!t.provider)return{source:"fallback",lines:n,evidence:e,error:"LLM summary provider unavailable."};try{let r=await t.provider.generateWorktreeDecisionSummary(e),o=gh(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 fh(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:Ph(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=>ho(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:xs(yo(t.outputPreview??""),dh)}}function gh(t){let e=hh(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>go)return[];let r=n.map(o=>typeof o=="string"?ho(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>Is)?[]:r.some(Ts)?[]:r}function hh(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
233
- `).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,go)}}}function yh(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 kh(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(`
234
- `)}function Sh(t){let e=new Set;return yo(t??"").replace(/\r\n/g,`
232
+ `),buttons:l}}var yo=3,Ts=180,mh=4e3,eu=32;function tu(){let t=Dt(),e=wh(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=Ph(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 fh(t,e){let n=bh(e);if(n.length>0)return n;let r=gh(t);if(r.length>0)return r;let o=[],i=t.changedFiles.slice(0,3).map(a=>`\`${a}\``);if(i.length>0){let a=t.changedFiles.length-i.length;o.push(a>0?`Touches ${i.join(", ")} and ${a} more file${a===1?"":"s"}`:`Touches ${i.join(", ")}`)}let s=[...new Set(t.commitMessages.map(a=>a.message.trim()).filter(Boolean))].slice(0,2);return s.length>0&&o.push(`Recent work: ${s.join("; ")}`),o}function gh(t){let e=new Set,n=t.commitMessages.length===1?t.changedFiles:[];return t.commitMessages.map(r=>hh(r.message,n)).filter(r=>!!r).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,yo)}function hh(t,e){let n=yh(t);if(!n)return;let r=e.length===1?` in \`${e[0]}\``:e.length>1&&e.length<=3?` across ${e.map(o=>`\`${o}\``).join(", ")}`:"";return Cs(`${n}${r}.`,Ts)}function yh(t){let e=ko(So(t)).replace(/^(?:feat|fix|docs|style|refactor|perf|test|tests|build|ci|chore|revert)(?:\([^)]+\))?!?:\s*/i,"").replace(/\.$/,"").trim();if(!e||Ms(e))return;let n=e.match(/^([a-z]+)\b(.*)$/i);if(!n)return e;let r=n[1].toLowerCase(),o=n[2]??"",s=new Map([["add","Adds"],["address","Addresses"],["block","Blocks"],["change","Changes"],["clarify","Clarifies"],["clean","Cleans"],["cover","Covers"],["create","Creates"],["deduplicate","Deduplicates"],["delete","Deletes"],["disable","Disables"],["document","Documents"],["enable","Enables"],["extract","Extracts"],["fix","Fixes"],["guard","Guards"],["harden","Hardens"],["implement","Implements"],["improve","Improves"],["init","Initializes"],["initialize","Initializes"],["migrate","Migrates"],["move","Moves"],["normalize","Normalizes"],["preserve","Preserves"],["prevent","Prevents"],["refactor","Refactors"],["remove","Removes"],["rename","Renames"],["restore","Restores"],["simplify","Simplifies"],["tighten","Tightens"],["update","Updates"],["use","Uses"],["wire","Wires"],["wrap","Wraps"]]).get(r);return s?`${s}${o}`:`${r[0].toUpperCase()}${r.slice(1)}${o}`}async function nu(t){let e=kh(t),n=fh(t.diffSummary??{changedFiles:e.changedFiles,commitMessages:e.commitSubjects.map(r=>({message:r}))},t.outputPreview);if(!t.provider)return{source:"fallback",lines:n,evidence:e,error:"LLM summary provider unavailable."};try{let r=await t.provider.generateWorktreeDecisionSummary(e),o=Sh(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 kh(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:Ih(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=>ko(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:Cs(So(t.outputPreview??""),mh)}}function Sh(t){let e=vh(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>yo)return[];let r=n.map(o=>typeof o=="string"?ko(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>Ts)?[]:r.some(Ms)?[]:r}function vh(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
233
+ `).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,yo)}}}function wh(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 Ph(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(`
234
+ `)}function bh(t){let e=new Set;return So(t??"").replace(/\r\n/g,`
235
235
  `).split(`
236
- `).map(r=>ho(r)).map(r=>vh(r)).filter(wh).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,go)}function vh(t){return t.replace(/^(?:summary|done|completed|changes|validation|verified)\s*:\s*/i,"").trim()}function wh(t){return t.length<12||t.length>Is||Ts(t)||/^(```|>|command\b|exit code\b|\$|[a-z0-9_-]+@[a-z0-9_-]+:)/i.test(t)||/^(?:running|ran|pnpm|npm|node|git|tsc|vitest|jest)\b/i.test(t)||/^(?:pass|fail|ok|error)\b[:\s]/i.test(t)||/^(?:changed files?|files changed|recent commits?|commits?)\b/i.test(t)?!1:/^(?:implemented|updated|added|fixed|changed|removed|verified|covered|refactored|improved|created|documented|hardened|restored|simplified|renamed|moved|wired|handled|blocked|reduced|deduplicated|normalized|addressed|prevented)\b/i.test(t)||/\b(?:so that|coverage|validation|regression|cleanup|summary|notification|callback|button|merge|worktree|policy)\b/i.test(t)&&/\b(?:preserv(?:e|es|ed|ing)|clear(?:s|ed|ing)?|reuse(?:s|d|ing)?|cover(?:s|ed|ing)?|pass(?:es|ed|ing)?|fail(?:s|ed|ing)?|complete(?:s|d)?|fall(?:s|ing)? back)\b/i.test(t)}function Ph(t){let e=t?.replace(/\r\n/g,`
236
+ `).map(r=>ko(r)).map(r=>Rh(r)).filter(Ah).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,yo)}function Rh(t){return t.replace(/^(?:summary|done|completed|changes|validation|verified)\s*:\s*/i,"").trim()}function Ah(t){return t.length<12||t.length>Ts||Ms(t)||/^(```|>|command\b|exit code\b|\$|[a-z0-9_-]+@[a-z0-9_-]+:)/i.test(t)||/^(?:running|ran|pnpm|npm|node|git|tsc|vitest|jest)\b/i.test(t)||/^(?:pass|fail|ok|error)\b[:\s]/i.test(t)||/^(?:changed files?|files changed|recent commits?|commits?)\b/i.test(t)?!1:/^(?:implemented|updated|added|fixed|changed|removed|verified|covered|refactored|improved|created|documented|hardened|restored|simplified|renamed|moved|wired|handled|blocked|reduced|deduplicated|normalized|addressed|prevented)\b/i.test(t)||/\b(?:so that|coverage|validation|regression|cleanup|summary|notification|callback|button|merge|worktree|policy)\b/i.test(t)&&/\b(?:preserv(?:e|es|ed|ing)|clear(?:s|ed|ing)?|reuse(?:s|d|ing)?|cover(?:s|ed|ing)?|pass(?:es|ed|ing)?|fail(?:s|ed|ing)?|complete(?:s|d)?|fall(?:s|ing)? back)\b/i.test(t)}function Ih(t){let e=t?.replace(/\r\n/g,`
237
237
  `).split(`
238
- `).map(o=>o.trim()).filter(Boolean).join(" ");if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=yo(n).replace(/\s+/g," ").trim();return r?xs(r,180):void 0}function ho(t){return t.replace(/^[-*•]\s+/,"").replace(/\s+/g," ").trim()}function xs(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function yo(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_-]{${Yd},}\\b`,"g"),"[redacted token]")}function Ts(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_-]{${Yd},}\\b`).test(t)}ke();var ko=class{constructor(e){this.deps=e;this.actions=new mo({shouldRunWorktreeStrategy:e.shouldRunWorktreeStrategy,isAlreadyMerged:e.isAlreadyMerged,resolveWorktreeRepoDir:e.resolveWorktreeRepoDir,getWorktreeCompletionState:e.getWorktreeCompletionState,isPrAvailable:e.isPrAvailable??(()=>!0),resolveRepoPolicy:e.resolveRepoPolicy})}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(`
239
- `)}notifyAutoMergeConflictEscalation(e,n,r,o,i=[]){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,...i.map(s=>`⚠️ ${s}`)].join(`
240
- `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,o,{},[[this.deps.makeOpenPrButton(e.id)]])})}updatePersistedSessionFor(e,n){for(let r of fe(e))this.deps.updatePersistedSession(r,n)}markPendingDecision(e,n={}){this.updatePersistedSessionFor(e,Nr(e,n))}markAutoMergeConflictResolving(e,n,r){this.updatePersistedSessionFor(e,Ol(e,n,r,{notes:[`resolver_session:${n}`]}))}markMerged(e){this.updatePersistedSessionFor(e,Bt(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.branchName,n.nativeBackendWorktree);if(n.kind==="merged"){let r=n.nativeBackendWorktree?!0:pe(n.repoDir,n.worktreePath);return ye(n.repoDir,n.branchName),this.markMerged(e),{notificationSent:!1,worktreeRemoved:r}}if(n.kind==="released"){let r=n.nativeBackendWorktree?!0:pe(n.repoDir,n.worktreePath);return ye(n.repoDir,n.branchName),this.markReleased(e,n.reasons),{notificationSent:!1,worktreeRemoved:r}}return n.policyBlocked?(this.markPendingDecision(e,{notes:n.policyReason?[n.policyReason]:void 0}),this.deps.dispatchSessionNotification(e,{label:"worktree-policy-blocked",idempotencyKey:`worktree-policy-blocked:${e.id}:${n.branchName}:${n.baseBranch}`,userMessage:`⚠️ [${e.name}] ${n.policyReason??"Repo policy blocked automatic follow-through."}`,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,n.allowedActions,{allowDelegate:!0})}),{notificationSent:!0,worktreeRemoved:!1}):n.strategy==="ask"?this.shouldUpdateExistingOpenPr(e,n.repoDir,n.branchName,n.policy,n.allowedActions)?this.handleAutoPrStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.allowedActions):await this.handleAskStrategy(e,n.branchName,n.baseBranch,n.diffSummary,n.allowedActions,n.policyReason):n.strategy==="delegate"?this.handleDelegateStrategy(e,n.branchName,n.baseBranch,n.diffSummary,n.allowedActions,n.policyReason):n.strategy==="auto-merge"?(await this.handleAutoMergeStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.diffSummary,n.sessionRef,n.allowedActions),{notificationSent:!0,worktreeRemoved:!1}):n.strategy==="auto-pr"?this.handleAutoPrStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.allowedActions):{notificationSent:!1,worktreeRemoved:!1}}async handleNoChange(e,n,r,o,i=ue(e)){if(this.hasCurrentlyOpenPrForBranch(e,n,o)){let a=new Date().toISOString();return this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_open",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{state:"pr_open",updatedAt:a,resolutionSource:e.worktreeLifecycle?.resolutionSource??"agent_pr",baseBranch:e.worktreeBaseBranch,targetRepo:e.worktreePrTargetRepo,pushRemote:e.worktreePushRemote,notes:["no_new_worktree_commits_preserved_open_pr"]}}),this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:i,cleanupSucceeded:!0,worktreePath:r,worktreeBranch:o,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e),preservedSummary:"existing PR worktree preserved until merge"})),{notificationSent:!0,worktreeRemoved:!1}}let s=i?!0:pe(n,r);return s?(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:i,cleanupSucceeded:!0,worktreePath:r,worktreeBranch:o,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)}))):this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:i,cleanupSucceeded:!1,worktreePath:r,worktreeBranch:o,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)})),{notificationSent:!0,worktreeRemoved:s}}hasCurrentlyOpenPrForBranch(e,n,r){return this.deps.hasOpenPrForBranch?.(n,r,e.worktreePrTargetRepo)===!0}shouldUpdateExistingOpenPr(e,n,r,o,i){return e.worktreeStrategy==="auto-pr"&&o==="never-pr"&&i.pr===!1&&this.hasCurrentlyOpenPrForBranch(e,n,r)}async handleAskStrategy(e,n,r,o,i,s){let a=await Xd({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:a.lines,policyReason:s,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i)})),this.markPendingDecision(e),{notificationSent:!0,worktreeRemoved:!1}}handleDelegateStrategy(e,n,r,o,i,s){return this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildDelegateNotification({session:e,branchName:n,baseBranch:r,diffSummary:o,policyReason:s,allowedActions:i,originThreadLine:this.deps.originThreadLine(e)})),this.markPendingDecision(e),{notificationSent:!0,worktreeRemoved:!1}}getPolicyAwareWorktreeDecisionButtons(e,n,r={},o){if(this.deps.getPolicyAwareWorktreeDecisionButtons)return this.deps.getPolicyAwareWorktreeDecisionButtons(e,r,n);if(o&&n.pr)return o;if(!(o&&!n.pr&&!n.merge))return this.deps.getWorktreeDecisionButtons(e)}handleDirtyUncommittedCompletion(e,n,r,o){this.markPendingDecision(e,{notes:["dirty_uncommitted_completion"]});let i=st(n),s=i.slice(0,20).map(l=>`- ${l}`),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(`
241
- `)}),{notificationSent:!0,worktreeRemoved:!1}}handleAutoMergeSuccess(e,n,r,o,i,s){ye(n,r),this.markMerged(e);let a=lt({kind:"merge",branch:r,base:o,filesChanged:i.filesChanged,insertions:i.insertions,deletions:i.deletions}),l=a;s.stashPopConflict?l+=`
242
- ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${s.stashRef??"stash@{0}"}\` in ${n} to review stashed changes.`:s.stashed&&(l+=`
243
- (Pre-existing changes on ${o} were auto-stashed and restored.)`),l=$e(l,s);let d=Nt(s),u=[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.`]:[],...d];this.deps.dispatchSessionNotification(e,{label:"worktree-merge-success",idempotencyKey:`worktree-merge-success:${e.id}:${r}:${o}`,userMessage:l,notifyUser:"always",completionSummary:{required:!0,producer:"worktree",outcomeKey:`terminal:${e.id}`},completionWakeSummaryRequired:!0,completionWakeOutcomeKey:`terminal:${e.id}`,deferConditionalWakeUntilNextTick:!0,wakeMessageOnNotifySuccess:Vt({sessionId:e.id,sessionName:e.name,outcomeLine:a,originThreadLine:this.deps.originThreadLine(e),detailLines:u,canonicalStatusDelivered:!0}),wakeMessageOnNotifyFailed:Vt({sessionId:e.id,sessionName:e.name,outcomeLine:a,originThreadLine:this.deps.originThreadLine(e),detailLines:u,canonicalStatusDelivered:!1})})}async handleInitialAutoMergeConflict(e,n,r,o,i,s,a,l){let d=l?Nt(l):[],u=e.autoMergeConflictResolutionAttemptCount??0;if(u>=1){this.markPendingDecision(e,{notes:["auto_merge_conflict_retry_exhausted"],clearResolverSessionId:!0}),this.notifyAutoMergeConflictEscalation(e,o,s.pr?`The rebased branch still conflicts with \`${i}\`. Open a PR or resolve manually in ${r}.`:`The rebased branch still conflicts with \`${i}\`. Resolve manually in ${r}.`,s,d);return}let c=this.buildConflictResolverPrompt({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,mergeError:a});try{let p=await this.deps.spawnConflictResolver({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,prompt:c});this.markAutoMergeConflictResolving(e,p.id,u+1),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-resolving",idempotencyKey:`worktree-merge-conflict-resolving:${e.id}:${o}:${p.id}`,userMessage:[`⚠️ [${e.name}] Auto-merge hit a rebase conflict. Started resolver session ${p.name} and will retry automatically if it succeeds.`,...d.map(f=>`⚠️ ${f}`)].join(`
244
- `)})}catch(p){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: ${p instanceof Error?p.message:String(p)}`,...d.map(f=>`⚠️ ${f}`)].join(`
245
- `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,s,{},[[this.deps.makeOpenPrButton(e.id)]])})}}handleAutoMergeRetryFailure(e,n,r,o,i){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(`
246
- `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i,{},[[this.deps.makeOpenPrButton(e.id)]])})}async handleAutoMergeStrategy(e,n,r,o,i,s,a=U(e)??e.harnessSessionId,l={merge:!0,pr:!0}){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,l,d.error,d);return}let u=$e(d.dirtyError?`❌ [${e.name}] Merge blocked: ${d.error}`:`❌ [${e.name}] Merge failed: ${d.error??"unknown error"}`,d);if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,o,r,u,l);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${o}`,userMessage:u})},()=>{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,s={merge:!0,pr:!0}){if(this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_in_progress"}),!(await this.deps.runAutoPr(e,i)).success){let l=Et(n);if(!!(l&&l!==o&&Dt(n,o,l)&&st(r).length===0)){let u=ue(e)?!0:pe(n,r);return u&&(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0})),ye(n,o),this.markReleased(e,[`released_by_branch:${l}`]),{notificationSent:!1,worktreeRemoved:u}}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.getPolicyAwareWorktreeDecisionButtons(e.id,s)})}return{notificationSent:!0,worktreeRemoved:!1}}};import{existsSync as sy,statSync as ay,writeFileSync as ly}from"fs";Ie();import{randomUUID as bh}from"crypto";function Rh(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var So=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:bh(),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}}listActiveActionTokens(e){let n=[];for(let r of[...this.tokens.keys()]){let o=this.getActionToken(r);!o||o.consumedAt!=null||e&&o.kind!==e||n.push(o)}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()}deleteActionTokensForSessionByKind(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId===e&&i.kind===n&&(this.tokens.delete(o),r=!0);r&&this.notifyChanged()}deletePlanDecisionTokensForSession(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId!==e||!Rh(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)}return n&&this.notifyChanged(),n}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?.()}};X();X();var vo=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 l=a.createdAt??Number.NEGATIVE_INFINITY,d=a.completedAt??Number.NEGATIVE_INFINITY;(l>r||l===r&&d>o||l===r&&d===o&&s>i)&&(n=a,r=l,o=d,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?E(s):void 0)??r}let o=this.getLatestPersistedByName(e);if(o)return E(o)??o.harnessSessionId;let i=this.indexes.backendIdIndex.get(e);if(i){let s=this.indexes.persisted.get(i);return(s?E(s):void 0)??i}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?E(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 cu,mkdirSync as Jh,readFileSync as Yh,readdirSync as Zh,renameSync as pu,statSync as mu,unlinkSync as fu,writeFileSync as gu}from"fs";import{tmpdir as Xh}from"os";import{dirname as ey,join as hu}from"path";import{homedir as Ah}from"node:os";import{join as Ih}from"node:path";function eu(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||Ah();return Ih(n,".openclaw")}Ie();var wo=7,xh=new Set(["running","completed","failed","killed"]);function Ke(t){return!!t&&typeof t=="object"}function Gt(t,e=""){return typeof t=="string"&&t.trim().length>0?t:e}function P(t){return typeof t=="string"&&t.trim().length>0?t:void 0}function me(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function tu(t){return typeof t=="string"&&xl.has(t)?t:void 0}function Cs(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function Th(t){return t==="never"||t==="on-request"?"never":void 0}function nu(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function Ch(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function ru(t){return typeof t=="string"&&Or.has(t)?t:void 0}function Ms(t){return typeof t=="string"&&Il.has(t)?t:void 0}function ou(t){return t==="github"||t==="unsupported"?t:void 0}function Mh(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function _h(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function iu(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 $h(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function Eh(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 Dh(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 su(t){return t==="live"||t==="stopped"?t:void 0}function Oh(t){if(!Ke(t)||t.reason!=="persisted-running-without-runtime")return;let e=P(t.recoveredAt);if(!e||!Number.isFinite(Date.parse(e)))return;let n=t.normalizedStatus==="killed"?"killed":void 0;if(n)return{reason:"persisted-running-without-runtime",recoveredAt:e,rawStatus:P(t.rawStatus),rawLifecycle:P(t.rawLifecycle),rawRuntimeState:P(t.rawRuntimeState),rawResumable:typeof t.rawResumable=="boolean"?t.rawResumable:void 0,rawCompletedAt:me(t.rawCompletedAt),rawOutputPath:P(t.rawOutputPath),normalizedStatus:n,normalizedLifecycle:iu(t.normalizedLifecycle),normalizedRuntimeState:su(t.normalizedRuntimeState)}}function Wh(t){return{reason:"persisted-running-without-runtime",recoveredAt:new Date().toISOString(),rawStatus:P(t.status),rawLifecycle:P(t.lifecycle),rawRuntimeState:P(t.runtimeState),rawResumable:typeof t.resumable=="boolean"?t.resumable:void 0,rawCompletedAt:me(t.completedAt),rawOutputPath:P(t.outputPath),normalizedStatus:"killed",normalizedLifecycle:"suspended",normalizedRuntimeState:"stopped"}}function Nh(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function Lh(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function Bh(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function Fh(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function qh(t){return t==="in_flight"||t==="delivered"?t:void 0}function Kh(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ke(n))return;let r=P(n.key),o=qh(n.status),i=P(n.recordedAt);if(!(!r||!o||!i||!Number.isFinite(Date.parse(i))))return{key:r,status:o,recordedAt:i,label:P(n.label)}}).filter(n=>!!n);return e.length>0?e.slice(-64):void 0}function Uh(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ke(n))return;let r=P(n.key),o=P(n.recordedAt);if(!r||!o||!Number.isFinite(Date.parse(o)))return;let i=Array.isArray(n.linkedKeys)?[...new Set(n.linkedKeys.map(P).filter(s=>!!(s&&s!==r)))]:void 0;return{key:r,linkedKeys:i&&i.length>0?i:void 0,recordedAt:o,label:P(n.label),skipReason:P(n.skipReason)}}).filter(n=>!!n);return e.length>0?e.slice(-1024):void 0}function Vh(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 Gh(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"||t==="plan-offer-start"||t==="plan-offer-dismiss"||t==="repo-policy-set"||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 au(t){if(!Ke(t))return;let e=P(t.provider),n=P(t.accountId),r=P(t.target),o=P(t.threadId),i=P(t.sessionKey);if(!(!e||!r))return{provider:e,accountId:n,target:r,threadId:o,sessionKey:i}}function jh(t,e,n){if(Ke(t)){let r=P(t.kind),o=P(t.conversationId);if(o&&(r==="claude-code"||r==="codex-app-server"||r==="opencode-server"))return{kind:r,conversationId:o,runId:P(t.runId),worktreeId:P(t.worktreeId),worktreePath:P(t.worktreePath)}}if(e==="claude-code")return{kind:"claude-code",conversationId:n}}function Hh(t){if(!Ke(t))return;let e=Dh(t.state),n=P(t.updatedAt);if(!e||!n)return;let r=P(t.resolutionSource);return{state:e,updatedAt:n,resolvedAt:P(t.resolvedAt),resolutionSource:r==="agent_merge"||r==="agent_pr"||r==="strategy_no_change"||r==="lifecycle_resolver"||r==="dismiss"||r==="maintenance"?r:void 0,baseBranch:P(t.baseBranch),targetRepo:P(t.targetRepo),pushRemote:P(t.pushRemote),notes:Array.isArray(t.notes)?t.notes.filter(o=>typeof o=="string"&&o.length>0):void 0}}function zh(t){let e=new Date(0).toISOString(),n=P(t.worktreeMergedAt)??P(t.worktreeDismissedAt)??P(t.pendingWorktreeDecisionSince)??e;if(t.worktreeMerged===!0||t.worktreeDisposition==="merged")return{state:"merged",updatedAt:n,resolvedAt:P(t.worktreeMergedAt)??n,resolutionSource:"agent_merge",baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.worktreeDisposition==="dismissed")return{state:"dismissed",updatedAt:n,resolvedAt:P(t.worktreeDismissedAt)??n,resolutionSource:"dismiss",baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.worktreeDisposition==="no-change-cleaned")return{state:"no_change",updatedAt:n,resolvedAt:n,resolutionSource:"strategy_no_change",baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.worktreeDisposition==="pr-opened"||t.worktreeState==="pr_open")return{state:"pr_open",updatedAt:n,baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.pendingWorktreeDecisionSince||t.worktreeState==="pending_decision")return{state:"pending_decision",updatedAt:n,baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.worktreeState==="merge_conflict_resolving")return{state:"merge_conflict_resolving",updatedAt:n,baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(P(t.worktreePath)||P(t.worktreeBranch))return{state:"provisioned",updatedAt:n,baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)}}function Qh(t){if(typeof t=="string"&&xh.has(t))return t==="running"?"killed":t}function lu(t){if(!Ke(t))return;let e=Gt(t.harnessSessionId);if(!e)return;let n=Qh(t.status);if(!n)return;let r=t.status==="running",o=P(t.worktreePath),i=P(t.worktreeBranch),s=P(t.originChannel),a=typeof t.originThreadId=="string"||typeof t.originThreadId=="number"?t.originThreadId:void 0,l=P(t.originSessionKey),d=au(t.route);if(!d)return;let u=et({route:d,originChannel:s,originThreadId:a,originSessionKey:l});if(!u||o&&!i)return;let c=P(t.harness),p=jh(t.backendRef,c,e),f=Hh(t.worktreeLifecycle)??zh(t),m=P(t.completionWakeSucceededAt),y=P(t.completionWakeSkippedAt),k=t.completionWakeSummaryRequired===!0&&!y?!0:void 0;return{sessionId:P(t.sessionId),harnessSessionId:e,backendRef:p,name:Gt(t.name,e),prompt:Gt(t.prompt),workdir:Gt(t.workdir,"(unknown)"),model:P(t.model),reasoningEffort:tu(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:me(t.createdAt),completedAt:me(t.completedAt),status:n,lifecycle:r?"suspended":iu(t.lifecycle),approvalState:$h(t.approvalState),worktreeState:Eh(t.worktreeState),runtimeState:r?"stopped":su(t.runtimeState),runtimeRecovery:r?Wh(t):Oh(t.runtimeRecovery),deliveryState:Fh(t.deliveryState),notificationDedupe:Kh(t.notificationDedupe),completionSummaryDedupe:Uh(t.completionSummaryDedupe),completionWakeIssuedAt:P(t.completionWakeIssuedAt),completionWakeSucceededAt:m,completionWakeFailedAt:P(t.completionWakeFailedAt),completionWakeSkippedAt:y,completionWakeSkipReason:P(t.completionWakeSkipReason),completionWakeSummaryRequired:k,killReason:_h(t.killReason),costUsd:typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)?t.costUsd:0,originAgentId:P(t.originAgentId),originChannel:s,originThreadId:a,originSessionKey:l,route:u,outputPath:P(t.outputPath),harness:c,goalTaskId:P(t.goalTaskId),requestedPermissionMode:Cs(t.requestedPermissionMode),currentPermissionMode:Cs(t.currentPermissionMode),approvalExecutionState:Vh(t.approvalExecutionState),approvalRationale:P(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:Ch(t.planApprovalContext),planDecisionVersion:me(t.planDecisionVersion),actionablePlanDecisionVersion:me(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:me(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:me(t.approvalPromptRequiredVersion),approvalPromptVersion:me(t.approvalPromptVersion),approvalPromptStatus:Nh(t.approvalPromptStatus),approvalPromptTransport:Lh(t.approvalPromptTransport),approvalPromptMessageKind:Bh(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:P(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:P(t.approvalPromptDeliveredAt),approvalPromptFailedAt:P(t.approvalPromptFailedAt),planApproval:nu(t.planApproval),codexApprovalPolicy:Th(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:ru(t.worktreeStrategy),repoIntegrationPolicy:Ms(t.repoIntegrationPolicy),repoIntegrationPolicySource:Mh(t.repoIntegrationPolicySource),repoProvider:ou(t.repoProvider),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:P(t.worktreeMergedAt),worktreePrUrl:P(t.worktreePrUrl),worktreePrNumber:me(t.worktreePrNumber),pendingWorktreeDecisionSince:P(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:P(t.lastWorktreeReminderAt),worktreeBaseBranch:P(t.worktreeBaseBranch),worktreePrTargetRepo:P(t.worktreePrTargetRepo),autoMergeParentSessionId:P(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:me(t.autoMergeConflictResolutionAttemptCount),autoMergeResolverSessionId:P(t.autoMergeResolverSessionId),worktreePushRemote:P(t.worktreePushRemote),worktreeDecisionSnoozedUntil:P(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:P(t.worktreeDismissedAt),worktreeLifecycle:f,resumable:r?!0:t.resumable===!0}}function du(t){if(!Ke(t))return;let e=P(t.key),n=P(t.repoRoot),r=Ms(t.policy),o=ou(t.provider)??"unsupported",i=P(t.createdAt),s=P(t.updatedAt),a=t.source==="seeded"?"seeded":"stored";if(!(!e||!n||!r||!i||!s)&&!(!Number.isFinite(Date.parse(i))||!Number.isFinite(Date.parse(s))))return{key:e,policy:r,repoRoot:n,remoteUrl:P(t.remoteUrl),provider:o,createdAt:i,updatedAt:s,source:a}}function uu(t){if(!Ke(t))return;let e=Gh(t.kind),n=Gt(t.id),r=Gt(t.sessionId),o=me(t.createdAt);if(!(!n||!r||!e||o==null))return{id:n,sessionId:r,kind:e,createdAt:o,planDecisionVersion:me(t.planDecisionVersion),expiresAt:me(t.expiresAt),consumedAt:me(t.consumedAt),optionIndex:me(t.optionIndex),pendingInputRequestId:P(t.pendingInputRequestId),pendingInputQuestionId:P(t.pendingInputQuestionId),label:P(t.label),targetUrl:P(t.targetUrl),route:au(t.route),launchName:P(t.launchName),launchPrompt:P(t.launchPrompt),launchWorkdir:P(t.launchWorkdir),launchModel:P(t.launchModel),launchReasoningEffort:tu(t.launchReasoningEffort),launchFastMode:t.launchFastMode===!0?!0:void 0,launchSystemPrompt:P(t.launchSystemPrompt),launchAllowedTools:Array.isArray(t.launchAllowedTools)?t.launchAllowedTools.filter(i=>typeof i=="string"):void 0,launchResumeSessionId:P(t.launchResumeSessionId),launchResumeWorktreeFrom:P(t.launchResumeWorktreeFrom),launchSessionIdOverride:P(t.launchSessionIdOverride),launchClearedPersistedCodexResume:t.launchClearedPersistedCodexResume===!0?!0:void 0,launchForkSession:typeof t.launchForkSession=="boolean"?t.launchForkSession:void 0,launchForceNewSession:typeof t.launchForceNewSession=="boolean"?t.launchForceNewSession:void 0,launchPermissionMode:Cs(t.launchPermissionMode),launchPlanApproval:nu(t.launchPlanApproval),launchHarness:P(t.launchHarness),launchWorktreeStrategy:ru(t.launchWorktreeStrategy),launchWorktreeBaseBranch:P(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:P(t.launchWorktreePrTargetRepo),launchOriginAgentId:P(t.launchOriginAgentId),repoPolicy:Ms(t.repoPolicy),repoPolicyWorkdir:P(t.repoPolicyWorkdir)}}function Po(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 Dn(t){return!!t&&typeof t=="object"}function _s(t){return t instanceof Error?t.message:String(t)}function ty(t,e){JSON.stringify({component:"SessionStore",event:t,at:new Date().toISOString(),...e})}function ny(t){return Dn(t)?{backendRefKind:typeof t.kind=="string"?t.kind:void 0,hasBackendConversationId:typeof t.conversationId=="string"&&t.conversationId.length>0,hasBackendRunId:typeof t.runId=="string"&&t.runId.length>0,hasBackendWorktreeId:typeof t.worktreeId=="string"&&t.worktreeId.length>0,hasBackendWorktreePath:typeof t.worktreePath=="string"&&t.worktreePath.length>0}:{}}function yu(t,e,n=Date.now()){let r=`${t}.${e}-${n}`;for(let o=0;o<100;o+=1){let i=o===0?"":`-${o}`,s=`${r}${i}.json`;if(!cu(s))return s}}function $s(){let t=Xh();return Zh(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>hu(t,e))}function ku(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||hu(eu(t),"code-agent-sessions.json")}function Su(t,e,n,r=[]){try{Jh(ey(t),{recursive:!0});let o=t+".tmp";gu(o,JSON.stringify({schemaVersion:wo,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),pu(o,t)}catch(o){`${_s(o)}`}}function ry(t,e){try{if(!cu(t))return!1;let n=yu(t,"legacy");return n?(pu(t,n),`${e}${n}`,!0):!1}catch(n){return`${_s(n)}`,!1}}var oy={archiveLegacySessionIndex:ry};function iy(t,e){try{if(e.length===0)return;let n=yu(t,"codex-sdk-legacy");if(!n)return;gu(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${_s(n)}`}}function vu(t,e,n=[]){try{let r=new Set(n);for(let o of $s())if(!r.has(o))try{let i=mu(o).mtimeMs;t-i>e&&fu(o)}catch{}}catch{}}function wu(t,e,n=[]){try{let r=new Set(n),o;for(let i of $s())if(!r.has(i))try{let s=mu(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function Pu(t){try{let e=new Set(t);for(let n of $s())if(!e.has(n))try{fu(n)}catch{}}catch{}}function bu(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:a}=t,l=d=>oy.archiveLegacySessionIndex(e,d)?(n(),!0):!1;try{let d=Yh(e,"utf-8"),u=JSON.parse(d);if(Array.isArray(u)){if(!l("legacy array store"))return;a();return}if(!Dn(u)||u.schemaVersion!==wo&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!l(`schema mismatch (expected v${wo})`))return;a();return}let c=(R,h)=>{if(!Object.prototype.hasOwnProperty.call(u,R))return[];let w=u[R];if(Array.isArray(w))return w;l(h)&&a()},p=c("sessions","invalid sessions collection");if(p===void 0)return;let f=[],m=[],y=!1;for(let R of p){if(Dn(R)&&R.harness==="codex"){let w=Dn(R.backendRef)?R.backendRef:void 0;if((typeof w?.kind=="string"?w.kind:void 0)!=="codex-app-server"){f.push(R);continue}}let h=lu(R);if(!h){if(!l("invalid v4 session entry"))return;a();return}Dn(R)&&R.status==="running"&&(y=!0,ty("session.recovered_from_running_persisted_row",{sessionId:typeof R.sessionId=="string"?R.sessionId:void 0,hasHarnessSessionId:typeof R.harnessSessionId=="string"&&R.harnessSessionId.length>0,...ny(R.backendRef),rawStatus:R.status,rawLifecycle:R.lifecycle,rawRuntimeState:R.runtimeState,normalizedStatus:h.status,normalizedLifecycle:h.lifecycle,normalizedRuntimeState:h.runtimeState,reason:h.runtimeRecovery?.reason})),m.push(h)}f.length>0&&iy(e,f);let k=c("actionTokens","invalid action token collection");if(k===void 0)return;let S=[];for(let R of k){let h=uu(R);if(!h){if(!l("invalid v4 action token"))return;a();return}S.push(h)}let b=c("repoPolicies","invalid repo policy collection");if(b===void 0)return;let A=[],x=!1;for(let R of b){let h=du(R);if(!h){x=!0;continue}A.push(h)}for(let R of m)r(R);for(let R of S)o(R);for(let R of A)i(R);(f.length>0||y)&&a(),x&&a(),s()}catch(d){if(d.code==="ENOENT"||!l("corrupt or unreadable"))return;a()}}var dy=new Set(["completed","failed","killed"]),Es=1440*60*1e3;function uy(t){return t instanceof Error?t.message:String(t)}var cy={statSync:ay};function py(t){try{return cy.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var bo=class{persisted=new Map;repoPolicies=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??ku(n),this.actionTokenStore=new So(()=>this.saveIndex(),Es),this.actionTokens=this.actionTokenStore.tokens,this.queries=new vo({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){bu({indexPath:this.indexPath,clearAll:()=>{this.persisted.clear(),this.repoPolicies.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)},setRepoPolicy:e=>{this.repoPolicies.set(e.key,e)},purgeExpiredActionTokens:()=>this.actionTokenStore.purgeExpiredActionTokens(),saveIndex:()=>this.saveIndex()})}saveIndex(){Su(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){Po(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=bi(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,repoIntegrationPolicy:e.repoIntegrationPolicy,repoIntegrationPolicySource:e.repoIntegrationPolicySource,repoProvider:e.repoProvider,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=E(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=et({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:it(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,repoIntegrationPolicy:o.repoIntegrationPolicy,repoIntegrationPolicySource:o.repoIntegrationPolicySource,repoProvider:o.repoProvider,worktreeBaseBranch:o.worktreeBaseBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Po(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=et({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let l=it(e.id);if(sy(l))s=l;else{let d=e.getOutput().join(`
247
- `);d.length>0&&(ly(l,d,"utf-8"),s=l)}}catch(l){`${e.id}${uy(l)}`}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};Po(a),this.indexPersistedEntry(a),this.saveIndex()}getExistingNotificationDedupe(e){return this.getPersistedSession(e.id)?.notificationDedupe??(e.harnessSessionId?this.getPersistedSession(e.harnessSessionId)?.notificationDedupe:void 0)??(E(e)?this.getPersistedSession(E(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()}getRepoPolicy(e){return this.repoPolicies.get(e)}listRepoPolicies(){return[...this.repoPolicies.values()].sort((e,n)=>e.repoRoot.localeCompare(n.repoRoot)||e.key.localeCompare(n.key))}setRepoPolicy(e){let n=this.repoPolicies.get(e.key),r={...e,createdAt:n?.createdAt??e.createdAt,updatedAt:new Date().toISOString(),source:"stored"};return this.repoPolicies.set(r.key,r),this.saveIndex(),r}updateRepoPolicy(e,n){let r=this.repoPolicies.get(e);if(r)return this.setRepoPolicy({...r,policy:n})}resetRepoPolicy(e){let n=this.repoPolicies.delete(e);return n&&this.saveIndex(),n}removeRepoPolicies(e){let n=[];for(let r of e){let o=this.repoPolicies.get(r);o&&(this.repoPolicies.delete(r),n.push(o))}return n.length>0&&this.saveIndex(),n.sort((r,o)=>r.repoRoot.localeCompare(o.repoRoot)||r.key.localeCompare(o.key))}cleanupRepoPolicies(){let e=[];for(let[n,r]of this.repoPolicies)py(r.repoRoot)||(this.repoPolicies.delete(n),e.push(r));return e.length>0&&this.saveIndex(),e.sort((n,r)=>n.repoRoot.localeCompare(r.repoRoot)||n.key.localeCompare(r.key))}cleanupTmpOutputFiles(e){this.actionTokenStore.purgeExpiredActionTokens(e),vu(e,Es,this.getReferencedOutputPaths())}getNextTmpOutputCleanupAt(e){return wu(e,Es,this.getReferencedOutputPaths())}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||!dy.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()){return 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(){Pu(this.getReferencedOutputPaths())}};var my=new Set(["completed","failed","killed"]),Ro=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),my.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:le(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 Iu from"child_process";var Ru=5e3,xu=64,fy={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},gy={execFile:Iu.execFile},Xe=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},Io=class{constructor(e=gy.execFile){this.execFile=e}execFile;async send(e,n,r){B("direct_send_started",{...Re(e),messageTextLength:n.length,...J(r)});try{await this.sendViaRuntime(e,n,r),B("direct_send_succeeded",{...Re(e),deliveryPath:"runtime",...J(r)});return}catch(o){if(!(o instanceof Xe))throw B("direct_send_failed",{...Re(e),deliveryPath:"runtime",...J(r),error:Ds(o)}),o;B("direct_send_runtime_capability_missing",{...Re(e),deliveryPath:"runtime",...J(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),B("direct_send_succeeded",{...Re(e),deliveryPath:"cli-fallback",...J(r)})}}async sendViaRuntime(e,n,r){let o=_t(),i=La(),s=o?.channel?.outbound?.loadAdapter;if(!o)throw new Xe("OpenClaw plugin runtime is unavailable for direct notification delivery");if(i==null)throw new Xe("OpenClaw runtime config snapshot is unavailable for direct notification delivery");if(!o.channel)throw new Xe(`OpenClaw plugin runtime channel surface is unavailable for direct notification delivery (runtimeVersion=${Os(o)})`);if(!o.channel.outbound)throw new Xe(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${Os(o)})`);if(!s)throw new Xe(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${Os(o)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let l=To(r);if(B("runtime_adapter_loaded",{...Re(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...J(r),...l?os(l):{}}),l){await this.sendPresentation(a,i,e,n,l);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=yy(i),a={text:o,presentation:i,interactive:s};B("presentation_render_started",{...Re(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...os(i)});let l={cfg:n,to:r.target,text:o,payload:a,accountId:r.accountId,threadId:r.threadId},d=e.renderPresentation?await e.renderPresentation({payload:a,presentation:i,ctx:l}):a,u=Sy(d,s,r.channel);if(B("presentation_render_completed",{...Re(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...is(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({...l,payload:u});B("presentation_send_payload_completed",{...Re(r),...is(u),...ed(c)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let a=hy(e,n,r);B("direct_send_cli_fallback_started",{...Re(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...J(r)}),this.execFile("openclaw",a,{timeout:Ru,killSignal:"SIGKILL"},(l,d,u)=>{if(!l){B("direct_send_cli_fallback_completed",{...Re(e),deliveryPath:"cli-fallback",...J(r)}),i();return}let c=u?.trim()?` | stderr: ${u.trim()}`:"";B("direct_send_cli_fallback_failed",{...Re(e),deliveryPath:"cli-fallback",...J(r),error:Ds(l),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${Ru}ms timeout: ${Ds(l)}${c}`))})})}};function Re(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function hy(t,e,n){let r=To(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 Ds(t){return t instanceof Error?t.message:String(t)}function Os(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function To(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:Ay(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function yy(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 ky(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 Sy(t,e,n){if(!e)return t;let r=ky(t)?t:vy(t,e);return n!=="telegram"?r:wy(r,e)}function vy(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function wy(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=jt(n.channelData),o=jt(r?.telegram),i=by(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=Py(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function Py(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")<=xu).map(r=>({text:r.label,callback_data:r.value,...Tu(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function by(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)&&!(i.callback_data!==void 0&&(typeof i.callback_data!="string"||i.callback_data.trim().length===0||Buffer.byteLength(i.callback_data,"utf8")>xu))&&Ry(i))return{...i,...Tu(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function Ry(t){return xo(t.callback_data)||xo(t.url)||Ao(t.web_app)||Ao(t.webApp)||Ao(t.login_url)||Ao(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||jt(t.switch_inline_query_chosen_chat)!==void 0||jt(t.callback_game)!==void 0||t.pay===!0||Au(t.copy_text)||Au(t.copyText)}function xo(t){return typeof t=="string"&&t.trim().length>0}function Ao(t){let e=jt(t);return xo(e?.url)}function Au(t){let e=jt(t);return xo(e?.text)}function Tu(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=fy[e];return n?{style:n}:{}}function jt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Ay(t){return t.startsWith(`${ee}:`)?t:`${ee}:${t}`}import*as Cu from"child_process";var Ht=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 Ws=3e4,Iy=2e3,xy=2e4,ge=4;function On(t){return t instanceof Error?t.message:String(t)}function Ty(){return new Error(`Dispatch timed out after ${Ws}ms`)}function Cy(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var My={execFile:Cu.execFile},Co=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,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:ge}),My.execFile("openclaw",e,{timeout:Ws,killSignal:"SIGKILL"},(s,a,l)=>{if(this.disposed){r?.();return}let d=Date.now()-i;if(!s){let m=n.successValidator?.(a??"");if(m?.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:ge,elapsedMs:d,error:m.reason,terminal:!0}),n.onFinalFailure?.(),r?.();return}if(m?.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:ge,elapsedMs:d,reason:m.reason}),n.shouldContinue?.()!==!1&&n.onSkipped?.(m.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:ge,elapsedMs:d}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.();return}let u=l?.trim()?` | stderr: ${l.trim()}`:"";if(n.shouldContinue?.()===!1){r?.();return}if(n.target==="message.send"&&Cy(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:ge,elapsedMs:d,error:`${On(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(o>=ge||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:ge,elapsedMs:d,error:`${On(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:ge,elapsedMs:d,retryDelayMs:p,error:`${On(s)}${u}`});let f={timer:setTimeout(()=>{let m=this.pendingRetryTimers.get(n.sessionId);if(m&&(m.delete(f),m.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:ge}),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:ge,elapsedMs:s}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.()}).catch(s=>{if(this.disposed){r?.();return}let a=Date.now()-i;if(n.shouldContinue?.()===!1){r?.();return}if(o>=ge||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:ge,elapsedMs:a,error:On(s),terminal:!0,...n.terminalOnFailure===!0&&o<ge?{terminalReason:"non_retryable"}:{}}),n.onFinalFailure?.(),r?.();return}let l=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:ge,elapsedMs:a,retryDelayMs:l,error:On(s)});let d={timer:setTimeout(()=>{let u=this.pendingRetryTimers.get(n.sessionId);if(u&&(u.delete(d),u.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executePromiseNow(e,n,r,o+1)},l),onCleared:r};d.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(d)})}executePromiseWithTimeout(e){return new Promise((n,r)=>{let o=!1,i=setTimeout(()=>{o||(o=!0,r(Ty()))},Ws);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=Iy*2**n;return Math.min(r,xy)}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}}};Ie();var Mo=class{resolve(e){let n=Ee(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 _y}from"crypto";var _o=class{constructor(e={}){}buildChatSendArgs(e,n,r,o=_y()){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=To(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 $y(t){let e=Ey(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 Ey(t){let e=t.trim();if(!e)return"";try{return Ns(JSON.parse(e)).trim()}catch{return e}}function Ns(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>Ns(r)).filter(Boolean).join(`
248
- `);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=Ns(e[r]);if(o.trim())return o}return""}var $o=class{routes=new Mo;transport;directNotifications;executor=new Co;constructor(e={}){this.transport=e.transport??new _o(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new Io: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,l,d,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:d,onFinalFailure:i,successValidator:l,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:d,successValidator:l,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:d,onFinalFailure:i,successValidator:l,shouldContinue:p})}})}sendUserNotification(e,n,r,o,i,s,a=!1,l){if(l?.()===!1)return;let d=!!o?.some(m=>Array.isArray(m)&&m.length>0),u=this.routes.resolve(e);B("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,...J(o)});let c=u?`notify:${u.channel}|${u.accountId??""}|${u.target}|${u.threadId??""}`:`notify:system:${e.id}`;if(!u){if(B("wake_notify_no_direct_route",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:d,...J(o)}),a){`${r}${e.id}`,i?.();return}if(d){`${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:l});return}let p=()=>{if(B("wake_notify_direct_failed",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:d,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...J(o)}),a){`${r}${e.id}`,i?.();return}if(d){`${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:l})},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:l};if(this.directNotifications){B("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,...J(o)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,o),f);return}B("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,...J(o)}),this.executor.execute(this.transport.buildDirectNotificationArgs(u,n,o),f)}sendUserNotificationSequence(e,n,r,o,i,s=!1,a){let l=n.map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0);if(l.length===0){o?.();return}B("wake_notify_sequence_started",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:l.length,buttonChunkIndexes:l.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 d=u=>{if(a?.()===!1)return;let c=l[u];if(!c){B("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:l.length}),i?.();return}let p=u===0?o:i;B("wake_notify_sequence_chunk_selected",{sessionId:e.id,sessionName:e.name,label:r,chunkIndex:u+1,chunkCount:l.length,messageTextLength:c.text.length,failureHandler:u===0?"all-failed":"sequence-success",...J(c.buttons)}),this.sendUserNotification(e,c.text,`${r}-part-${u+1}`,c.buttons,p,()=>d(u+1),s,a)};d(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(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0),a=n.wakeMessage?.trim(),l=n.shouldDispatch,d=n.completionWakeSummaryRequired===!0?$y:void 0;if(o){let u=n.wakeMessageOnNotifySuccess?.trim(),c=n.wakeMessageOnNotifyFailed?.trim(),p=k=>{k&&l?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,k,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,l,d,r?.onWakeSkipped,n.idempotencyKey))},f=k=>{if(k){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let S=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>p(k),S).unref?.();return}p(k)}},m=()=>{l?.()!==!1&&(r?.onNotifySucceeded?.(),u&&f(u))},y=c?()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),f(c))}:()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(l?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,y,m,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(a&&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,a,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,l,d,r?.onWakeSkipped,n.idempotencyKey)}}};var Mu=36,_u=2,$u="...";function Dy(t){let e=Array.from(t);return e.length<=Mu?t:`${e.slice(0,Mu-$u.length).join("")}${$u}`}var Eo=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)}listActiveActionTokens(e){return this.actionTokens.listActiveActionTokens(e)}clearRepoPolicyChoiceTokens(e){this.actionTokens.deleteActionTokensForSessionByKind(e,"repo-policy-set")}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":case"repo-policy-set":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,r={merge:!0,pr:!0}){if(!n)return[];let o=[],i=[];if(r.merge&&i.push(this.makeActionButton(e,"worktree-merge","Merge")),r.pr&&this.isGitHubCliAvailable())n.worktreePrUrl?(i.push(this.makeActionButton(e,"worktree-view-pr","View PR",{targetUrl:n.worktreePrUrl})),i.length>0&&o.push(i),o.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")),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-decide-later","Later"),this.makeActionButton(e,"worktree-dismiss","Discard")]));else return o.push([...i,this.makeActionButton(e,"worktree-decide-later","Later")]),o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o;return n.worktreePrUrl&&o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o}getPlanApprovalButtons(e,n){let r=n?.actionablePlanDecisionVersion??n?.planDecisionVersion;this.clearPlanDecisionTokens(e,r);let o=[[this.makeActionButton(e,"plan-approve","Approve",{planDecisionVersion:r}),this.makeActionButton(e,"plan-request-changes","Revise",{planDecisionVersion:r}),this.makeActionButton(e,"plan-reject","Reject",{planDecisionVersion:r})]];return B("plan_approval_buttons_created",{sessionId:e,planDecisionVersion:r,...J(o)}),o}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,r={}){if(n.length===0)return;let o=n.map((s,a)=>{let l=this.createActionToken(e,"question-answer",{label:s.label,optionIndex:a,pendingInputRequestId:r.requestId,pendingInputQuestionId:r.questionId});return{label:Dy(s.label),callbackData:l.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=_u)i.push(o.slice(s,s+_u));return i}getPlanOfferButtons(e){let{offerId:n,route:r,planName:o,planPrompt:i,planWorkdir:s,planWorktreeStrategy:a}=e,l=[[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 B("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,...J(l)}),l}getRepoPolicyChoiceButtons(e){let n=wn(e.prAvailable??!0),r=Array.from({length:Math.ceil(n.length/2)},(o,i)=>n.slice(i*2,i*2+2)).map(o=>o.map(i=>this.makeActionButton(e.choiceId,"repo-policy-set",i.label,{route:e.route,repoPolicy:i.policy,repoPolicyWorkdir:e.repoRoot,launchName:e.launchName,launchPrompt:e.launchPrompt,launchWorkdir:e.launchWorkdir,launchModel:e.launchModel,launchReasoningEffort:e.launchReasoningEffort,launchFastMode:e.launchFastMode,launchSystemPrompt:e.launchSystemPrompt,launchAllowedTools:e.launchAllowedTools,launchResumeSessionId:e.launchResumeSessionId,launchResumeWorktreeFrom:e.launchResumeWorktreeFrom,launchSessionIdOverride:e.launchSessionIdOverride,launchClearedPersistedCodexResume:e.launchClearedPersistedCodexResume,launchForkSession:e.launchForkSession,launchForceNewSession:e.launchForceNewSession,launchPermissionMode:e.launchPermissionMode,launchPlanApproval:e.launchPlanApproval,launchHarness:e.launchHarness,launchWorktreeStrategy:e.launchWorktreeStrategy,launchWorktreeBaseBranch:e.launchWorktreeBaseBranch,launchWorktreePrTargetRepo:e.launchWorktreePrTargetRepo,launchOriginAgentId:e.launchOriginAgentId})));return B("repo_policy_choice_buttons_created",{choiceId:e.choiceId,repoRoot:e.repoRoot,channel:e.route.provider,target:e.route.target,accountId:e.route.accountId,threadId:e.route.threadId,sessionKey:e.route.sessionKey,labels:n.map(o=>o.label),...J(r)}),r}};X();Ie();import{createHash as Ly}from"crypto";var Oy="duplicate notification already delivered or in flight",Do=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:Oy}:(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))}};Ie();X();Ie();import{createHash as Wy}from"crypto";var Ny=1024,Wn="duplicate completion follow-up wake already handled",Oo="prior human-visible summary already delivered",Wo=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??Ny))}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=this.buildPersistedKeyMap(i),a=o.decisionKeys.find(u=>this.inFlight.has(u)||!!this.getCompletedRecord(u)||s.has(u)),l=a?this.getCompletedRecord(a):void 0,d=a?s.get(a):void 0;return a?{required:!0,allowed:!1,explicit:o.explicit,dedupeKey:o.primary,skipReason:l?.skipReason??d?.skipReason??Wn}:(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=this.buildPersistedKeyMap(s),l=i.decisionKeys.find(p=>!!this.getCompletedRecord(p)||a.has(p)),d=l?this.getCompletedRecord(l):void 0,u=l?a.get(l):void 0;if(d||u)return{required:!0,allowed:!1,explicit:i.explicit,dedupeKey:i.primary,skipReason:d?.skipReason??u?.skipReason};this.finishKeys(i.primary,i.claimKeys,!0,Oo);let c=this.deliveredRecords(i.claimKeys,s,o,Oo);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:c}}finish(e,n,r=Wn){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=Wn){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=Wn){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===Oo&&o!==Oo||(this.completed.delete(i),this.completed.set(i,{skipReason:o,linkedKeys:n.filter(a=>a!==i)}));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)}`,l=this.isGoalLike(e,n,o),d=this.buildSessionAliasKeys(r,e,"visible-summary"),u=this.buildSessionAliasKeys(r,e,"goal-summary"),c=this.isTerminalLike(n,o),p=o.startsWith("worktree-pr:")?this.normalizeWorktreePrOutcome(n.outcomeKey?.trim()):void 0,f=p?.aliases.map(m=>`${this.buildVisibleScope(r,e)}:outcome:${this.digest(m)}`)??[];return{primary:a,explicit:!0,claimKeys:[...d,...l?u:[],...f,a],decisionKeys:[a,...p?.blocksAliases?f:[],...l||c?d:[],...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.normalizeWorktreePrOutcome(n);return o?o.primary:n}normalizeWorktreePrOutcome(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;let l=["worktree-pr",o.toLowerCase(),s,a].join(":"),d=`${l}:created`;if(r.endsWith("updated")){let u=n.slice(5).join(":").trim();return{primary:u?`${l}:updated:${u}`:`${l}:updated`,aliases:[d,l],blocksAliases:!1}}return{primary:d,aliases:[l],blocksAliases:!0}}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=Ee(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,E(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 U(e)??E(e)??""}digest(e){return Wy("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):[]}buildPersistedKeyMap(e){let n=new Map;for(let r of e){n.set(r.key,r);for(let o of r.linkedKeys??[])o.trim()&&n.set(o,r)}return n}getCompletedRecord(e){let n=this.completed.get(e);if(n)return n;for(let r of this.completed.values())if(r.linkedKeys?.includes(e))return r}deliveredRecords(e,n,r,o=Wn){let i=new Date().toISOString(),s=this.normalizeRecords(n),a=new Set(e),d=[...s.filter(u=>!a.has(u.key)&&!(u.linkedKeys??[]).some(c=>a.has(c))),...e.map(u=>{let c=e.filter(p=>p!==u);return{key:u,linkedKeys:c.length>0?c:void 0,recordedAt:i,label:r,skipReason:o}})];return d.slice(Math.max(0,d.length-this.maxCompletedKeys))}};var By=2e3,Fy=new Set(["1","true","yes","on"]);function qy(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&Fy.has(t))||rs()}function Ky(t){qy()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
249
- `)}var No=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new Wo({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new Do({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),l=n.completionSummaryOwner==="foreground"&&a?.required===!0,d=l?this.completionSummaries.recordVisibleDelivery(e,a,o?.completionSummaryDedupe,n.label):this.completionSummaries.decide(e,a,o?.completionSummaryDedupe);d.records&&this.applyCompletionSummaryDedupePatch(r,d.records);let u=l?this.withoutCompletionWake(n):n;if(d.required&&!d.allowed)if(this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:d.dedupeKey??d.key,outcomeKey:a?.outcomeKey,decision:l?"skip":d.explicit?"send_without_followup":"skip",reason:d.skipReason??"completion follow-up wake suppressed",deliveryPath:l?"foreground-summary":"wake",followupKind:a?.producer}),n.hooks?.onWakeSkipped?.(d.skipReason??"completion follow-up wake suppressed"),l){this.releaseNotificationDedupe(r,i);return}else if(d.explicit)u=this.withoutCompletionWake(n);else{this.releaseNotificationDedupe(r,i);return}a?.required===!0&&this.logNotificationDecision({session:e,request:u,deliveryRef:r,dedupeKey:d.dedupeKey??d.key,outcomeKey:a.outcomeKey,decision:l?"record_visible":u.completionWakeSummaryRequired===!0?"send_with_followup":"send_without_followup",reason:l?"foreground summary owns completion follow-up":void 0,deliveryPath:l?"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()),m=!1,y=!1,k=()=>{y||(y=!0,m||(this.releaseNotificationDedupe(r,i),m=!0),this.completionSummaries.finish(d.key,!1))},S=u.shouldDispatch?()=>{let A=u.shouldDispatch?.()!==!1;return A||k(),A}:void 0,b={onNotifyStarted:()=>{this.applyDeliveryState(r,"notifying"),u.hooks?.onNotifyStarted?.()},onNotifySucceeded:()=>{m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.applyNotifyDeliveryState(r,p?"wake_pending":"idle",p?c:void 0),p||this.completionSummaries.finish(d.key,!1),u.hooks?.onNotifySucceeded?.()},onNotifyFailed:()=>{this.applyNotifyDeliveryState(r,f?"wake_pending":"failed",f?c:void 0),f||(this.completionSummaries.finish(d.key,!1),this.releaseNotificationDedupe(r,i),m=!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:()=>{m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,d.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(d.key,!0),u.hooks?.onWakeSucceeded?.()},onWakeSkipped:A=>{if(y){u.hooks?.onWakeSkipped?.(A);return}m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,d.key,u.label,A),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(c),{completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:new Date().toISOString(),completionWakeSkipReason:A}),this.completionSummaries.finish(d.key,!0),u.hooks?.onWakeSkipped?.(A)},onWakeFailed:()=>{this.applyPersistedPatchWithCompletionWake(r,"failed",c,{completionWakeFailedAt:new Date().toISOString()}),this.completionSummaries.finish(d.key,!1),this.releaseNotificationDedupe(r,i),m=!0,u.hooks?.onWakeFailed?.()}};this.wakeDispatcher.dispatchSessionNotification(e,{...u,idempotencyKey:i??u.idempotencyKey,shouldDispatch:S,hooks:b})}notifyWorktreeOutcome(e,n,r={}){let o=this.getDeliveryRef(e),i=d=>Vt({sessionId:o,sessionName:e.name,outcomeLine:n,originThreadLine:en(e),detailLines:r.detailLines,canonicalStatusDelivered:d}),s=r.summaryWakeRequired??!0,a={required:s,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},l=r.completionSummaryOwner!=="foreground";if(s&&!l){let d=this.getDeliveryRef(e),u=this.completionSummaries.recordVisibleDelivery(e,a,d?this.getPersistedSession?.(d)?.completionSummaryDedupe:void 0,"worktree-outcome");u.records&&this.applyCompletionSummaryDedupePatch(d,u.records)}this.dispatch(e,{label:"worktree-outcome",userMessage:n,notifyUser:"always",requireDirectUserNotification:!0,completionSummary:{...a,required:s&&l},completionWakeSummaryRequired:s&&l,completionWakeOutcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`,idempotencyKey:`worktree-outcome:${r.completionWakeOutcomeKey??n}`,deferConditionalWakeUntilNextTick:!0,deferConditionalWakeMs:By,wakeMessageOnNotifySuccess:s&&l?i(!0):void 0,wakeMessageOnNotifyFailed:s&&l?i(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return U(e)??E(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}
238
+ `).map(o=>o.trim()).filter(Boolean).join(" ");if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=So(n).replace(/\s+/g," ").trim();return r?Cs(r,180):void 0}function ko(t){return t.replace(/^[-*•]\s+/,"").replace(/\s+/g," ").trim()}function Cs(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function So(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_-]{${eu},}\\b`,"g"),"[redacted token]")}function Ms(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_-]{${eu},}\\b`).test(t)}ke();function Ce(t){return[t.startedAt,t.worktreeBranch??"unknown-branch",t.worktreePath??"unknown-worktree"].join(":")}var vo=class{constructor(e){this.deps=e;this.actions=new go({shouldRunWorktreeStrategy:e.shouldRunWorktreeStrategy,isAlreadyMerged:e.isAlreadyMerged,resolveWorktreeRepoDir:e.resolveWorktreeRepoDir,getWorktreeCompletionState:e.getWorktreeCompletionState,isPrAvailable:e.isPrAvailable??(()=>!0),resolveRepoPolicy:e.resolveRepoPolicy})}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(`
239
+ `)}notifyAutoMergeConflictEscalation(e,n,r,o,i=[]){this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-escalated",idempotencyKey:`worktree-merge-conflict-escalated:${e.id}:${n}:${Ce(e)}`,userMessage:[`⚠️ [${e.name}] Auto-merge could not finish after one conflict-resolution attempt.`,`Branch \`${n}\` was preserved for manual follow-up.`,"",r,...i.map(s=>`⚠️ ${s}`)].join(`
240
+ `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,o,{},[[this.deps.makeOpenPrButton(e.id)]])})}updatePersistedSessionFor(e,n){for(let r of fe(e))this.deps.updatePersistedSession(r,n)}markPendingDecision(e,n={}){this.updatePersistedSessionFor(e,Br(e,n))}markAutoMergeConflictResolving(e,n,r){this.updatePersistedSessionFor(e,Ld(e,n,r,{notes:[`resolver_session:${n}`]}))}markMerged(e){this.updatePersistedSessionFor(e,Kt(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.startedAt,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.branchName,n.nativeBackendWorktree);if(n.kind==="merged"){let r=n.nativeBackendWorktree?!0:pe(n.repoDir,n.worktreePath);return ye(n.repoDir,n.branchName),this.markMerged(e),{notificationSent:!1,worktreeRemoved:r}}if(n.kind==="released"){let r=n.nativeBackendWorktree?!0:pe(n.repoDir,n.worktreePath);return ye(n.repoDir,n.branchName),this.markReleased(e,n.reasons),{notificationSent:!1,worktreeRemoved:r}}return n.policyBlocked?(this.markPendingDecision(e,{notes:n.policyReason?[n.policyReason]:void 0}),this.deps.dispatchSessionNotification(e,{label:"worktree-policy-blocked",idempotencyKey:`worktree-policy-blocked:${e.id}:${n.branchName}:${n.baseBranch}:${Ce(e)}`,userMessage:`⚠️ [${e.name}] ${n.policyReason??"Repo policy blocked automatic follow-through."}`,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,n.allowedActions,{allowDelegate:!0})}),{notificationSent:!0,worktreeRemoved:!1}):n.strategy==="ask"?this.shouldUpdateExistingOpenPr(e,n.repoDir,n.branchName,n.policy,n.allowedActions)?this.handleAutoPrStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.allowedActions):await this.handleAskStrategy(e,n.branchName,n.baseBranch,n.diffSummary,n.allowedActions,n.policyReason):n.strategy==="delegate"?this.handleDelegateStrategy(e,n.branchName,n.baseBranch,n.diffSummary,n.allowedActions,n.policyReason):n.strategy==="auto-merge"?(await this.handleAutoMergeStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.diffSummary,n.sessionRef,n.allowedActions),{notificationSent:!0,worktreeRemoved:!1}):n.strategy==="auto-pr"?this.handleAutoPrStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.allowedActions):{notificationSent:!1,worktreeRemoved:!1}}async handleNoChange(e,n,r,o,i=ue(e)){if(this.hasCurrentlyOpenPrForBranch(e,n,o)){let a=new Date().toISOString();return this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_open",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{state:"pr_open",updatedAt:a,resolutionSource:e.worktreeLifecycle?.resolutionSource??"agent_pr",baseBranch:e.worktreeBaseBranch,targetRepo:e.worktreePrTargetRepo,pushRemote:e.worktreePushRemote,notes:["no_new_worktree_commits_preserved_open_pr"]}}),this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:i,cleanupSucceeded:!0,worktreePath:r,worktreeBranch:o,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e),preservedSummary:"existing PR worktree preserved until merge"})),{notificationSent:!0,worktreeRemoved:!1}}let s=i?!0:pe(n,r);return s?(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:i,cleanupSucceeded:!0,worktreePath:r,worktreeBranch:o,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)}))):this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:i,cleanupSucceeded:!1,worktreePath:r,worktreeBranch:o,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)})),{notificationSent:!0,worktreeRemoved:s}}hasCurrentlyOpenPrForBranch(e,n,r){return this.deps.hasOpenPrForBranch?.(n,r,e.worktreePrTargetRepo)===!0}shouldUpdateExistingOpenPr(e,n,r,o,i){return e.worktreeStrategy==="auto-pr"&&o==="never-pr"&&i.pr===!1&&this.hasCurrentlyOpenPrForBranch(e,n,r)}async handleAskStrategy(e,n,r,o,i,s){let a=await nu({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:a.lines,policyReason:s,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i)})),this.markPendingDecision(e),{notificationSent:!0,worktreeRemoved:!1}}handleDelegateStrategy(e,n,r,o,i,s){return this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildDelegateNotification({session:e,branchName:n,baseBranch:r,diffSummary:o,policyReason:s,allowedActions:i,originThreadLine:this.deps.originThreadLine(e)})),this.markPendingDecision(e),{notificationSent:!0,worktreeRemoved:!1}}getPolicyAwareWorktreeDecisionButtons(e,n,r={},o){if(this.deps.getPolicyAwareWorktreeDecisionButtons)return this.deps.getPolicyAwareWorktreeDecisionButtons(e,r,n);if(o&&n.pr)return o;if(!(o&&!n.pr&&!n.merge))return this.deps.getWorktreeDecisionButtons(e)}handleDirtyUncommittedCompletion(e,n,r,o){this.markPendingDecision(e,{notes:["dirty_uncommitted_completion"]});let i=lt(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}:${Ce(e)}`,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(`
241
+ `)}),{notificationSent:!0,worktreeRemoved:!1}}handleAutoMergeSuccess(e,n,r,o,i,s){ye(n,r),this.markMerged(e);let a=ct({kind:"merge",branch:r,base:o,filesChanged:i.filesChanged,insertions:i.insertions,deletions:i.deletions}),d=a;s.stashPopConflict?d+=`
242
+ ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${s.stashRef??"stash@{0}"}\` in ${n} to review stashed changes.`:s.stashed&&(d+=`
243
+ (Pre-existing changes on ${o} were auto-stashed and restored.)`),d=Ee(d,s);let l=Lt(s),u=[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.`]:[],...l];this.deps.dispatchSessionNotification(e,{label:"worktree-merge-success",idempotencyKey:`worktree-merge-success:${e.id}:${r}:${o}:${Ce(e)}`,userMessage:d,notifyUser:"always",completionSummary:{required:!0,producer:"worktree",outcomeKey:`worktree-merge:${e.id}:${r}:${o}:${Ce(e)}`},completionWakeSummaryRequired:!0,completionWakeOutcomeKey:`worktree-merge:${e.id}:${r}:${o}:${Ce(e)}`,deferConditionalWakeUntilNextTick:!0,wakeMessageOnNotifySuccess:Ht({sessionId:e.id,sessionName:e.name,outcomeLine:a,originThreadLine:this.deps.originThreadLine(e),detailLines:u,canonicalStatusDelivered:!0}),wakeMessageOnNotifyFailed:Ht({sessionId:e.id,sessionName:e.name,outcomeLine:a,originThreadLine:this.deps.originThreadLine(e),detailLines:u,canonicalStatusDelivered:!1})})}async handleInitialAutoMergeConflict(e,n,r,o,i,s,a,d){let l=d?Lt(d):[],u=e.autoMergeConflictResolutionAttemptCount??0;if(u>=1){this.markPendingDecision(e,{notes:["auto_merge_conflict_retry_exhausted"],clearResolverSessionId:!0}),this.notifyAutoMergeConflictEscalation(e,o,s.pr?`The rebased branch still conflicts with \`${i}\`. Open a PR or resolve manually in ${r}.`:`The rebased branch still conflicts with \`${i}\`. Resolve manually in ${r}.`,s,l);return}let c=this.buildConflictResolverPrompt({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,mergeError:a});try{let p=await this.deps.spawnConflictResolver({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,prompt:c});this.markAutoMergeConflictResolving(e,p.id,u+1),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-resolving",idempotencyKey:`worktree-merge-conflict-resolving:${e.id}:${o}:${p.id}`,userMessage:[`⚠️ [${e.name}] Auto-merge hit a rebase conflict. Started resolver session ${p.name} and will retry automatically if it succeeds.`,...l.map(f=>`⚠️ ${f}`)].join(`
244
+ `)})}catch(p){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}:${Ce(e)}`,userMessage:[`❌ [${e.name}] Auto-merge hit a rebase conflict and failed to start the resolver: ${p instanceof Error?p.message:String(p)}`,...l.map(f=>`⚠️ ${f}`)].join(`
245
+ `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,s,{},[[this.deps.makeOpenPrButton(e.id)]])})}}handleAutoMergeRetryFailure(e,n,r,o,i){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}:${Ce(e)}`,userMessage:[o,"","Auto-merge retry did not complete after conflict resolution.",`Branch \`${n}\` was preserved for manual follow-up in ${r}.`].join(`
246
+ `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i,{},[[this.deps.makeOpenPrButton(e.id)]])})}async handleAutoMergeStrategy(e,n,r,o,i,s,a=V(e)??e.harnessSessionId,d={merge:!0,pr:!0}){this.deps.isAlreadyMerged(a)||e.autoMergeResolverSessionId||await this.deps.enqueueMerge(n,async()=>{if(this.deps.isAlreadyMerged(a))return;let l=this.deps.mergeBranch(n,o,i,"merge",r);if(l.success){this.handleAutoMergeSuccess(e,n,o,i,s,l);return}if(l.rebaseConflict){await this.handleInitialAutoMergeConflict(e,n,r,o,i,d,l.error,l);return}let u=Ee(l.dirtyError?`❌ [${e.name}] Merge blocked: ${l.error}`:`❌ [${e.name}] Merge failed: ${l.error??"unknown error"}`,l);if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,o,r,u,d);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${o}:${Ce(e)}`,userMessage:u})},()=>{this.deps.dispatchSessionNotification(e,{label:"worktree-merge-queued",idempotencyKey:`worktree-merge-queued:${e.id}:${o}:${Ce(e)}`,userMessage:`🕐 [${e.name}] Merge queued — another merge for this repo is in progress. Will notify when complete.`})})}async handleAutoPrStrategy(e,n,r,o,i,s={merge:!0,pr:!0}){let a=this.releaseIfRepresentedByTargetPrBranch(e,n,r,o,i);if(a)return a;if(this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_in_progress"}),!(await this.deps.runAutoPr(e,i)).success){let l=this.releaseIfRepresentedByTargetPrBranch(e,n,r,o,i);if(l)return l;this.markPendingDecision(e),this.deps.dispatchSessionNotification(e,{label:"worktree-auto-pr-failed",idempotencyKey:`worktree-auto-pr-failed:${e.id}:${i}:${Ce(e)}`,userMessage:`⚠️ [${e.name}] Auto-PR did not complete. The worktree is preserved for an explicit merge or PR decision.`,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,s)})}return{notificationSent:!0,worktreeRemoved:!1}}getPrStatusForUrl(e,n,r){return this.deps.getPrStatusForUrl?.(e,n,r)??Ft(e,n,r)}releaseIfRepresentedByTargetPrBranch(e,n,r,o,i){if(lt(r).length>0)return;let s=Ze(n),a=e.worktreePrUrl;if(!s||!a||s===o||s===i)return;let d=this.getPrStatusForUrl(n,a,e.worktreePrTargetRepo);if(!!!((d?.state==="open"||d?.state==="merged")&&d?.headRefName===s&&d?.baseRefName===i&&dt(n,o,s)))return;let u=ue(e)?!0:pe(n,r);return u?(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0}),ye(n,o),this.markReleased(e,[`released_by_branch:${s}`]),{notificationSent:!1,worktreeRemoved:u}):(this.markPendingDecision(e,{notes:[`represented_by_branch:${s}`,"represented_worktree_cleanup_failed"]}),{notificationSent:!1,worktreeRemoved:!1})}};import{existsSync as uy,statSync as cy,writeFileSync as py}from"fs";xe();import{randomUUID as xh}from"crypto";function Th(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var wo=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:xh(),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}}listActiveActionTokens(e){let n=[];for(let r of[...this.tokens.keys()]){let o=this.getActionToken(r);!o||o.consumedAt!=null||e&&o.kind!==e||n.push(o)}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()}deleteActionTokensForSessionByKind(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId===e&&i.kind===n&&(this.tokens.delete(o),r=!0);r&&this.notifyChanged()}deletePlanDecisionTokensForSession(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId!==e||!Th(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)}return n&&this.notifyChanged(),n}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?.()}};ee();ee();var Po=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?$(s):void 0)??r}let o=this.getLatestPersistedByName(e);if(o)return $(o)??o.harnessSessionId;let i=this.indexes.backendIdIndex.get(e);if(i){let s=this.indexes.persisted.get(i);return(s?$(s):void 0)??i}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?$(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 fu,mkdirSync as ey,readFileSync as ty,readdirSync as ny,renameSync as gu,statSync as hu,unlinkSync as yu,writeFileSync as ku}from"fs";import{tmpdir as ry}from"os";import{dirname as oy,join as Su}from"path";import{homedir as Ch}from"node:os";import{join as Mh}from"node:path";function ru(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||Ch();return Mh(n,".openclaw")}xe();var bo=7,_h=new Set(["running","completed","failed","killed"]);function Ue(t){return!!t&&typeof t=="object"}function zt(t,e=""){return typeof t=="string"&&t.trim().length>0?t:e}function P(t){return typeof t=="string"&&t.trim().length>0?t:void 0}function me(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function ou(t){return typeof t=="string"&&Md.has(t)?t:void 0}function _s(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function $h(t){return t==="never"||t==="on-request"?"never":void 0}function iu(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function Eh(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function su(t){return typeof t=="string"&&Nr.has(t)?t:void 0}function $s(t){return typeof t=="string"&&Cd.has(t)?t:void 0}function au(t){return t==="github"||t==="unsupported"?t:void 0}function Dh(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function Oh(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function du(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 Wh(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function Nh(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 Lh(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 lu(t){return t==="live"||t==="stopped"?t:void 0}function Bh(t){if(!Ue(t)||t.reason!=="persisted-running-without-runtime")return;let e=P(t.recoveredAt);if(!e||!Number.isFinite(Date.parse(e)))return;let n=t.normalizedStatus==="killed"?"killed":void 0;if(n)return{reason:"persisted-running-without-runtime",recoveredAt:e,rawStatus:P(t.rawStatus),rawLifecycle:P(t.rawLifecycle),rawRuntimeState:P(t.rawRuntimeState),rawResumable:typeof t.rawResumable=="boolean"?t.rawResumable:void 0,rawCompletedAt:me(t.rawCompletedAt),rawOutputPath:P(t.rawOutputPath),normalizedStatus:n,normalizedLifecycle:du(t.normalizedLifecycle),normalizedRuntimeState:lu(t.normalizedRuntimeState)}}function Fh(t){return{reason:"persisted-running-without-runtime",recoveredAt:new Date().toISOString(),rawStatus:P(t.status),rawLifecycle:P(t.lifecycle),rawRuntimeState:P(t.runtimeState),rawResumable:typeof t.resumable=="boolean"?t.resumable:void 0,rawCompletedAt:me(t.completedAt),rawOutputPath:P(t.outputPath),normalizedStatus:"killed",normalizedLifecycle:"suspended",normalizedRuntimeState:"stopped"}}function qh(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function Kh(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function Uh(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function Vh(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function Gh(t){return t==="in_flight"||t==="delivered"?t:void 0}function jh(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ue(n))return;let r=P(n.key),o=Gh(n.status),i=P(n.recordedAt);if(!(!r||!o||!i||!Number.isFinite(Date.parse(i))))return{key:r,status:o,recordedAt:i,label:P(n.label)}}).filter(n=>!!n);return e.length>0?e.slice(-64):void 0}function Hh(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ue(n))return;let r=P(n.key),o=P(n.recordedAt);if(!r||!o||!Number.isFinite(Date.parse(o)))return;let i=Array.isArray(n.linkedKeys)?[...new Set(n.linkedKeys.map(P).filter(s=>!!(s&&s!==r)))]:void 0;return{key:r,linkedKeys:i&&i.length>0?i:void 0,recordedAt:o,label:P(n.label),skipReason:P(n.skipReason)}}).filter(n=>!!n);return e.length>0?e.slice(-1024):void 0}function zh(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 Qh(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"||t==="plan-offer-start"||t==="plan-offer-dismiss"||t==="repo-policy-set"||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 uu(t){if(!Ue(t))return;let e=P(t.provider),n=P(t.accountId),r=P(t.target),o=P(t.threadId),i=P(t.sessionKey);if(!(!e||!r))return{provider:e,accountId:n,target:r,threadId:o,sessionKey:i}}function Jh(t,e,n){if(Ue(t)){let r=P(t.kind),o=P(t.conversationId);if(o&&(r==="claude-code"||r==="codex-app-server"||r==="opencode-server"))return{kind:r,conversationId:o,runId:P(t.runId),worktreeId:P(t.worktreeId),worktreePath:P(t.worktreePath)}}if(e==="claude-code")return{kind:"claude-code",conversationId:n}}function Yh(t){if(!Ue(t))return;let e=Lh(t.state),n=P(t.updatedAt);if(!e||!n)return;let r=P(t.resolutionSource);return{state:e,updatedAt:n,resolvedAt:P(t.resolvedAt),resolutionSource:r==="agent_merge"||r==="agent_pr"||r==="strategy_no_change"||r==="lifecycle_resolver"||r==="dismiss"||r==="maintenance"?r:void 0,baseBranch:P(t.baseBranch),targetRepo:P(t.targetRepo),pushRemote:P(t.pushRemote),notes:Array.isArray(t.notes)?t.notes.filter(o=>typeof o=="string"&&o.length>0):void 0}}function Zh(t){let e=new Date(0).toISOString(),n=P(t.worktreeMergedAt)??P(t.worktreeDismissedAt)??P(t.pendingWorktreeDecisionSince)??e;if(t.worktreeMerged===!0||t.worktreeDisposition==="merged")return{state:"merged",updatedAt:n,resolvedAt:P(t.worktreeMergedAt)??n,resolutionSource:"agent_merge",baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.worktreeDisposition==="dismissed")return{state:"dismissed",updatedAt:n,resolvedAt:P(t.worktreeDismissedAt)??n,resolutionSource:"dismiss",baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.worktreeDisposition==="no-change-cleaned")return{state:"no_change",updatedAt:n,resolvedAt:n,resolutionSource:"strategy_no_change",baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.worktreeDisposition==="pr-opened"||t.worktreeState==="pr_open")return{state:"pr_open",updatedAt:n,baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.pendingWorktreeDecisionSince||t.worktreeState==="pending_decision")return{state:"pending_decision",updatedAt:n,baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(t.worktreeState==="merge_conflict_resolving")return{state:"merge_conflict_resolving",updatedAt:n,baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)};if(P(t.worktreePath)||P(t.worktreeBranch))return{state:"provisioned",updatedAt:n,baseBranch:P(t.worktreeBaseBranch),targetRepo:P(t.worktreePrTargetRepo),pushRemote:P(t.worktreePushRemote)}}function Xh(t){if(typeof t=="string"&&_h.has(t))return t==="running"?"killed":t}function cu(t){if(!Ue(t))return;let e=zt(t.harnessSessionId);if(!e)return;let n=Xh(t.status);if(!n)return;let r=t.status==="running",o=P(t.worktreePath),i=P(t.worktreeBranch),s=P(t.originChannel),a=typeof t.originThreadId=="string"||typeof t.originThreadId=="number"?t.originThreadId:void 0,d=P(t.originSessionKey),l=uu(t.route);if(!l)return;let u=rt({route:l,originChannel:s,originThreadId:a,originSessionKey:d});if(!u||o&&!i)return;let c=P(t.harness),p=Jh(t.backendRef,c,e),f=Yh(t.worktreeLifecycle)??Zh(t),m=P(t.completionWakeSucceededAt),y=P(t.completionWakeSkippedAt),k=t.completionWakeSummaryRequired===!0&&!y?!0:void 0;return{sessionId:P(t.sessionId),harnessSessionId:e,backendRef:p,name:zt(t.name,e),prompt:zt(t.prompt),workdir:zt(t.workdir,"(unknown)"),model:P(t.model),reasoningEffort:ou(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:me(t.createdAt),completedAt:me(t.completedAt),status:n,lifecycle:r?"suspended":du(t.lifecycle),approvalState:Wh(t.approvalState),worktreeState:Nh(t.worktreeState),runtimeState:r?"stopped":lu(t.runtimeState),runtimeRecovery:r?Fh(t):Bh(t.runtimeRecovery),deliveryState:Vh(t.deliveryState),notificationDedupe:jh(t.notificationDedupe),completionSummaryDedupe:Hh(t.completionSummaryDedupe),completionWakeIssuedAt:P(t.completionWakeIssuedAt),completionWakeSucceededAt:m,completionWakeFailedAt:P(t.completionWakeFailedAt),completionWakeSkippedAt:y,completionWakeSkipReason:P(t.completionWakeSkipReason),completionWakeSummaryRequired:k,killReason:Oh(t.killReason),costUsd:typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)?t.costUsd:0,originAgentId:P(t.originAgentId),originChannel:s,originThreadId:a,originSessionKey:d,route:u,outputPath:P(t.outputPath),harness:c,goalTaskId:P(t.goalTaskId),requestedPermissionMode:_s(t.requestedPermissionMode),currentPermissionMode:_s(t.currentPermissionMode),approvalExecutionState:zh(t.approvalExecutionState),approvalRationale:P(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:Eh(t.planApprovalContext),planDecisionVersion:me(t.planDecisionVersion),actionablePlanDecisionVersion:me(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:me(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:me(t.approvalPromptRequiredVersion),approvalPromptVersion:me(t.approvalPromptVersion),approvalPromptStatus:qh(t.approvalPromptStatus),approvalPromptTransport:Kh(t.approvalPromptTransport),approvalPromptMessageKind:Uh(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:P(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:P(t.approvalPromptDeliveredAt),approvalPromptFailedAt:P(t.approvalPromptFailedAt),planApproval:iu(t.planApproval),codexApprovalPolicy:$h(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:su(t.worktreeStrategy),repoIntegrationPolicy:$s(t.repoIntegrationPolicy),repoIntegrationPolicySource:Dh(t.repoIntegrationPolicySource),repoProvider:au(t.repoProvider),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:P(t.worktreeMergedAt),worktreePrUrl:P(t.worktreePrUrl),worktreePrNumber:me(t.worktreePrNumber),pendingWorktreeDecisionSince:P(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:P(t.lastWorktreeReminderAt),worktreeBaseBranch:P(t.worktreeBaseBranch),worktreePrTargetRepo:P(t.worktreePrTargetRepo),autoMergeParentSessionId:P(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:me(t.autoMergeConflictResolutionAttemptCount),autoMergeResolverSessionId:P(t.autoMergeResolverSessionId),worktreePushRemote:P(t.worktreePushRemote),worktreeDecisionSnoozedUntil:P(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:P(t.worktreeDismissedAt),worktreeLifecycle:f,resumable:r?!0:t.resumable===!0}}function pu(t){if(!Ue(t))return;let e=P(t.key),n=P(t.repoRoot),r=$s(t.policy),o=au(t.provider)??"unsupported",i=P(t.createdAt),s=P(t.updatedAt),a=t.source==="seeded"?"seeded":"stored";if(!(!e||!n||!r||!i||!s)&&!(!Number.isFinite(Date.parse(i))||!Number.isFinite(Date.parse(s))))return{key:e,policy:r,repoRoot:n,remoteUrl:P(t.remoteUrl),provider:o,createdAt:i,updatedAt:s,source:a}}function mu(t){if(!Ue(t))return;let e=Qh(t.kind),n=zt(t.id),r=zt(t.sessionId),o=me(t.createdAt);if(!(!n||!r||!e||o==null))return{id:n,sessionId:r,kind:e,createdAt:o,planDecisionVersion:me(t.planDecisionVersion),expiresAt:me(t.expiresAt),consumedAt:me(t.consumedAt),optionIndex:me(t.optionIndex),pendingInputRequestId:P(t.pendingInputRequestId),pendingInputQuestionId:P(t.pendingInputQuestionId),label:P(t.label),targetUrl:P(t.targetUrl),route:uu(t.route),launchName:P(t.launchName),launchPrompt:P(t.launchPrompt),launchWorkdir:P(t.launchWorkdir),launchModel:P(t.launchModel),launchReasoningEffort:ou(t.launchReasoningEffort),launchFastMode:t.launchFastMode===!0?!0:void 0,launchSystemPrompt:P(t.launchSystemPrompt),launchAllowedTools:Array.isArray(t.launchAllowedTools)?t.launchAllowedTools.filter(i=>typeof i=="string"):void 0,launchResumeSessionId:P(t.launchResumeSessionId),launchResumeWorktreeFrom:P(t.launchResumeWorktreeFrom),launchSessionIdOverride:P(t.launchSessionIdOverride),launchClearedPersistedCodexResume:t.launchClearedPersistedCodexResume===!0?!0:void 0,launchForkSession:typeof t.launchForkSession=="boolean"?t.launchForkSession:void 0,launchForceNewSession:typeof t.launchForceNewSession=="boolean"?t.launchForceNewSession:void 0,launchPermissionMode:_s(t.launchPermissionMode),launchPlanApproval:iu(t.launchPlanApproval),launchHarness:P(t.launchHarness),launchWorktreeStrategy:su(t.launchWorktreeStrategy),launchWorktreeBaseBranch:P(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:P(t.launchWorktreePrTargetRepo),launchOriginAgentId:P(t.launchOriginAgentId),repoPolicy:$s(t.repoPolicy),repoPolicyWorkdir:P(t.repoPolicyWorkdir)}}function Ro(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 Wn(t){return!!t&&typeof t=="object"}function Es(t){return t instanceof Error?t.message:String(t)}function iy(t,e){JSON.stringify({component:"SessionStore",event:t,at:new Date().toISOString(),...e})}function sy(t){return Wn(t)?{backendRefKind:typeof t.kind=="string"?t.kind:void 0,hasBackendConversationId:typeof t.conversationId=="string"&&t.conversationId.length>0,hasBackendRunId:typeof t.runId=="string"&&t.runId.length>0,hasBackendWorktreeId:typeof t.worktreeId=="string"&&t.worktreeId.length>0,hasBackendWorktreePath:typeof t.worktreePath=="string"&&t.worktreePath.length>0}:{}}function vu(t,e,n=Date.now()){let r=`${t}.${e}-${n}`;for(let o=0;o<100;o+=1){let i=o===0?"":`-${o}`,s=`${r}${i}.json`;if(!fu(s))return s}}function Ds(){let t=ry();return ny(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>Su(t,e))}function wu(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||Su(ru(t),"code-agent-sessions.json")}function Pu(t,e,n,r=[]){try{ey(oy(t),{recursive:!0});let o=t+".tmp";ku(o,JSON.stringify({schemaVersion:bo,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),gu(o,t)}catch(o){`${Es(o)}`}}function ay(t,e){try{if(!fu(t))return!1;let n=vu(t,"legacy");return n?(gu(t,n),`${e}${n}`,!0):!1}catch(n){return`${Es(n)}`,!1}}var dy={archiveLegacySessionIndex:ay};function ly(t,e){try{if(e.length===0)return;let n=vu(t,"codex-sdk-legacy");if(!n)return;ku(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${Es(n)}`}}function bu(t,e,n=[]){try{let r=new Set(n);for(let o of Ds())if(!r.has(o))try{let i=hu(o).mtimeMs;t-i>e&&yu(o)}catch{}}catch{}}function Ru(t,e,n=[]){try{let r=new Set(n),o;for(let i of Ds())if(!r.has(i))try{let s=hu(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function Au(t){try{let e=new Set(t);for(let n of Ds())if(!e.has(n))try{yu(n)}catch{}}catch{}}function Iu(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:a}=t,d=l=>dy.archiveLegacySessionIndex(e,l)?(n(),!0):!1;try{let l=ty(e,"utf-8"),u=JSON.parse(l);if(Array.isArray(u)){if(!d("legacy array store"))return;a();return}if(!Wn(u)||u.schemaVersion!==bo&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!d(`schema mismatch (expected v${bo})`))return;a();return}let c=(R,h)=>{if(!Object.prototype.hasOwnProperty.call(u,R))return[];let w=u[R];if(Array.isArray(w))return w;d(h)&&a()},p=c("sessions","invalid sessions collection");if(p===void 0)return;let f=[],m=[],y=!1;for(let R of p){if(Wn(R)&&R.harness==="codex"){let w=Wn(R.backendRef)?R.backendRef:void 0;if((typeof w?.kind=="string"?w.kind:void 0)!=="codex-app-server"){f.push(R);continue}}let h=cu(R);if(!h){if(!d("invalid v4 session entry"))return;a();return}Wn(R)&&R.status==="running"&&(y=!0,iy("session.recovered_from_running_persisted_row",{sessionId:typeof R.sessionId=="string"?R.sessionId:void 0,hasHarnessSessionId:typeof R.harnessSessionId=="string"&&R.harnessSessionId.length>0,...sy(R.backendRef),rawStatus:R.status,rawLifecycle:R.lifecycle,rawRuntimeState:R.runtimeState,normalizedStatus:h.status,normalizedLifecycle:h.lifecycle,normalizedRuntimeState:h.runtimeState,reason:h.runtimeRecovery?.reason})),m.push(h)}f.length>0&&ly(e,f);let k=c("actionTokens","invalid action token collection");if(k===void 0)return;let S=[];for(let R of k){let h=mu(R);if(!h){if(!d("invalid v4 action token"))return;a();return}S.push(h)}let b=c("repoPolicies","invalid repo policy collection");if(b===void 0)return;let A=[],x=!1;for(let R of b){let h=pu(R);if(!h){x=!0;continue}A.push(h)}for(let R of m)r(R);for(let R of S)o(R);for(let R of A)i(R);(f.length>0||y)&&a(),x&&a(),s()}catch(l){if(l.code==="ENOENT"||!d("corrupt or unreadable"))return;a()}}var my=new Set(["completed","failed","killed"]),Os=1440*60*1e3;function fy(t){return t instanceof Error?t.message:String(t)}var gy={statSync:cy};function hy(t){try{return gy.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var Ao=class{persisted=new Map;repoPolicies=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??wu(n),this.actionTokenStore=new wo(()=>this.saveIndex(),Os),this.actionTokens=this.actionTokenStore.tokens,this.queries=new Po({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Iu({indexPath:this.indexPath,clearAll:()=>{this.persisted.clear(),this.repoPolicies.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)},setRepoPolicy:e=>{this.repoPolicies.set(e.key,e)},purgeExpiredActionTokens:()=>this.actionTokenStore.purgeExpiredActionTokens(),saveIndex:()=>this.saveIndex()})}saveIndex(){Pu(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){Ro(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=Ai(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,repoIntegrationPolicy:e.repoIntegrationPolicy,repoIntegrationPolicySource:e.repoIntegrationPolicySource,repoProvider:e.repoProvider,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=$(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=rt({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:at(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,repoIntegrationPolicy:o.repoIntegrationPolicy,repoIntegrationPolicySource:o.repoIntegrationPolicySource,repoProvider:o.repoProvider,worktreeBaseBranch:o.worktreeBaseBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Ro(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=rt({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let d=at(e.id);if(uy(d))s=d;else{let l=e.getOutput().join(`
247
+ `);l.length>0&&(py(d,l,"utf-8"),s=d)}}catch(d){`${e.id}${fy(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};Ro(a),this.indexPersistedEntry(a),this.saveIndex()}getExistingNotificationDedupe(e){return this.getPersistedSession(e.id)?.notificationDedupe??(e.harnessSessionId?this.getPersistedSession(e.harnessSessionId)?.notificationDedupe:void 0)??($(e)?this.getPersistedSession($(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()}getRepoPolicy(e){return this.repoPolicies.get(e)}listRepoPolicies(){return[...this.repoPolicies.values()].sort((e,n)=>e.repoRoot.localeCompare(n.repoRoot)||e.key.localeCompare(n.key))}setRepoPolicy(e){let n=this.repoPolicies.get(e.key),r={...e,createdAt:n?.createdAt??e.createdAt,updatedAt:new Date().toISOString(),source:"stored"};return this.repoPolicies.set(r.key,r),this.saveIndex(),r}updateRepoPolicy(e,n){let r=this.repoPolicies.get(e);if(r)return this.setRepoPolicy({...r,policy:n})}resetRepoPolicy(e){let n=this.repoPolicies.delete(e);return n&&this.saveIndex(),n}removeRepoPolicies(e){let n=[];for(let r of e){let o=this.repoPolicies.get(r);o&&(this.repoPolicies.delete(r),n.push(o))}return n.length>0&&this.saveIndex(),n.sort((r,o)=>r.repoRoot.localeCompare(o.repoRoot)||r.key.localeCompare(o.key))}cleanupRepoPolicies(){let e=[];for(let[n,r]of this.repoPolicies)hy(r.repoRoot)||(this.repoPolicies.delete(n),e.push(r));return e.length>0&&this.saveIndex(),e.sort((n,r)=>n.repoRoot.localeCompare(r.repoRoot)||n.key.localeCompare(r.key))}cleanupTmpOutputFiles(e){this.actionTokenStore.purgeExpiredActionTokens(e),bu(e,Os,this.getReferencedOutputPaths())}getNextTmpOutputCleanupAt(e){return Ru(e,Os,this.getReferencedOutputPaths())}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||!my.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()){return 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(){Au(this.getReferencedOutputPaths())}};var yy=new Set(["completed","failed","killed"]),Io=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),yy.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:de(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 Cu from"child_process";var xu=5e3,Mu=64,ky={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},Sy={execFile:Cu.execFile},nt=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},To=class{constructor(e=Sy.execFile){this.execFile=e}execFile;async send(e,n,r){B("direct_send_started",{...Ae(e),messageTextLength:n.length,...Y(r)});try{await this.sendViaRuntime(e,n,r),B("direct_send_succeeded",{...Ae(e),deliveryPath:"runtime",...Y(r)});return}catch(o){if(!(o instanceof nt))throw B("direct_send_failed",{...Ae(e),deliveryPath:"runtime",...Y(r),error:Ws(o)}),o;B("direct_send_runtime_capability_missing",{...Ae(e),deliveryPath:"runtime",...Y(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),B("direct_send_succeeded",{...Ae(e),deliveryPath:"cli-fallback",...Y(r)})}}async sendViaRuntime(e,n,r){let o=Dt(),i=Fa(),s=o?.channel?.outbound?.loadAdapter;if(!o)throw new nt("OpenClaw plugin runtime is unavailable for direct notification delivery");if(i==null)throw new nt("OpenClaw runtime config snapshot is unavailable for direct notification delivery");if(!o.channel)throw new nt(`OpenClaw plugin runtime channel surface is unavailable for direct notification delivery (runtimeVersion=${Ns(o)})`);if(!o.channel.outbound)throw new nt(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${Ns(o)})`);if(!s)throw new nt(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${Ns(o)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let d=Mo(r);if(B("runtime_adapter_loaded",{...Ae(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...Y(r),...d?ss(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=wy(i),a={text:o,presentation:i,interactive:s};B("presentation_render_started",{...Ae(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...ss(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=by(l,s,r.channel);if(B("presentation_render_completed",{...Ae(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...as(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});B("presentation_send_payload_completed",{...Ae(r),...as(u),...rl(c)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let a=vy(e,n,r);B("direct_send_cli_fallback_started",{...Ae(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...Y(r)}),this.execFile("openclaw",a,{timeout:xu,killSignal:"SIGKILL"},(d,l,u)=>{if(!d){B("direct_send_cli_fallback_completed",{...Ae(e),deliveryPath:"cli-fallback",...Y(r)}),i();return}let c=u?.trim()?` | stderr: ${u.trim()}`:"";B("direct_send_cli_fallback_failed",{...Ae(e),deliveryPath:"cli-fallback",...Y(r),error:Ws(d),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${xu}ms timeout: ${Ws(d)}${c}`))})})}};function Ae(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function vy(t,e,n){let r=Mo(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 Ws(t){return t instanceof Error?t.message:String(t)}function Ns(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function Mo(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:Cy(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function wy(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 Py(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 by(t,e,n){if(!e)return t;let r=Py(t)?t:Ry(t,e);return n!=="telegram"?r:Ay(r,e)}function Ry(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function Ay(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Qt(n.channelData),o=Qt(r?.telegram),i=xy(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=Iy(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function Iy(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")<=Mu).map(r=>({text:r.label,callback_data:r.value,..._u(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function xy(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)&&!(i.callback_data!==void 0&&(typeof i.callback_data!="string"||i.callback_data.trim().length===0||Buffer.byteLength(i.callback_data,"utf8")>Mu))&&Ty(i))return{...i,..._u(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function Ty(t){return Co(t.callback_data)||Co(t.url)||xo(t.web_app)||xo(t.webApp)||xo(t.login_url)||xo(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||Qt(t.switch_inline_query_chosen_chat)!==void 0||Qt(t.callback_game)!==void 0||t.pay===!0||Tu(t.copy_text)||Tu(t.copyText)}function Co(t){return typeof t=="string"&&t.trim().length>0}function xo(t){let e=Qt(t);return Co(e?.url)}function Tu(t){let e=Qt(t);return Co(e?.text)}function _u(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=ky[e];return n?{style:n}:{}}function Qt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Cy(t){return t.startsWith(`${te}:`)?t:`${te}:${t}`}import*as $u from"child_process";var Jt=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 Ls=3e4,My=2e3,_y=2e4,ge=4;function Nn(t){return t instanceof Error?t.message:String(t)}function $y(){return new Error(`Dispatch timed out after ${Ls}ms`)}function Ey(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var Dy={execFile:$u.execFile},_o=class{pendingRetryTimers=new Map;orderedDispatches=new Jt;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:ge}),Dy.execFile("openclaw",e,{timeout:Ls,killSignal:"SIGKILL"},(s,a,d)=>{if(this.disposed){r?.();return}let l=Date.now()-i;if(!s){let m=n.successValidator?.(a??"");if(m?.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:ge,elapsedMs:l,error:m.reason,terminal:!0}),n.onFinalFailure?.(),r?.();return}if(m?.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:ge,elapsedMs:l,reason:m.reason}),n.shouldContinue?.()!==!1&&n.onSkipped?.(m.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:ge,elapsedMs:l}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.();return}let u=d?.trim()?` | stderr: ${d.trim()}`:"";if(n.shouldContinue?.()===!1){r?.();return}if(n.target==="message.send"&&Ey(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:ge,elapsedMs:l,error:`${Nn(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(o>=ge||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:ge,elapsedMs:l,error:`${Nn(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:ge,elapsedMs:l,retryDelayMs:p,error:`${Nn(s)}${u}`});let f={timer:setTimeout(()=>{let m=this.pendingRetryTimers.get(n.sessionId);if(m&&(m.delete(f),m.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:ge}),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:ge,elapsedMs:s}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.()}).catch(s=>{if(this.disposed){r?.();return}let a=Date.now()-i;if(n.shouldContinue?.()===!1){r?.();return}if(o>=ge||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:ge,elapsedMs:a,error:Nn(s),terminal:!0,...n.terminalOnFailure===!0&&o<ge?{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:ge,elapsedMs:a,retryDelayMs:d,error:Nn(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($y()))},Ls);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=My*2**n;return Math.min(r,_y)}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}}};xe();var $o=class{resolve(e){let n=De(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 Oy}from"crypto";var Eo=class{constructor(e={}){}buildChatSendArgs(e,n,r,o=Oy()){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=Mo(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 Wy(t){let e=Ny(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 Ny(t){let e=t.trim();if(!e)return"";try{return Bs(JSON.parse(e)).trim()}catch{return e}}function Bs(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>Bs(r)).filter(Boolean).join(`
248
+ `);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=Bs(e[r]);if(o.trim())return o}return""}var Do=class{routes=new $o;transport;directNotifications;executor=new _o;constructor(e={}){this.transport=e.transport??new Eo(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new To: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(m=>Array.isArray(m)&&m.length>0),u=this.routes.resolve(e);B("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,...Y(o)});let c=u?`notify:${u.channel}|${u.accountId??""}|${u.target}|${u.threadId??""}`:`notify:system:${e.id}`;if(!u){if(B("wake_notify_no_direct_route",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:l,...Y(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(B("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,...Y(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){B("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,...Y(o)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,o),f);return}B("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,...Y(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}B("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){B("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length}),i?.();return}let p=u===0?o:i;B("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",...Y(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(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0),a=n.wakeMessage?.trim(),d=n.shouldDispatch,l=n.completionWakeSummaryRequired===!0?Wy:void 0;if(o){let u=n.wakeMessageOnNotifySuccess?.trim(),c=n.wakeMessageOnNotifyFailed?.trim(),p=k=>{k&&d?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,k,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,d,l,r?.onWakeSkipped,n.idempotencyKey))},f=k=>{if(k){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let S=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>p(k),S).unref?.();return}p(k)}},m=()=>{d?.()!==!1&&(r?.onNotifySucceeded?.(),u&&f(u))},y=c?()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),f(c))}:()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,y,m,n.requireDirectUserNotification===!0,d)}else y();return}if(i==="always"&&s.length>0){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{d?.()!==!1&&r?.onNotifySucceeded?.()},n.requireDirectUserNotification===!0,d)}if(a&&d?.()!==!1){if(r?.onWakeStarted?.(),i==="on-wake-fallback"&&s.length>0&&!this.routes.resolve(e)?.sessionKey){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{d?.()!==!1&&r?.onNotifySucceeded?.()},!1,d)}this.sendWake(e,a,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,d,l,r?.onWakeSkipped,n.idempotencyKey)}}};var Eu=36,Du=2,Ou="...";function Ly(t){let e=Array.from(t);return e.length<=Eu?t:`${e.slice(0,Eu-Ou.length).join("")}${Ou}`}var Oo=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)}listActiveActionTokens(e){return this.actionTokens.listActiveActionTokens(e)}clearRepoPolicyChoiceTokens(e){this.actionTokens.deleteActionTokensForSessionByKind(e,"repo-policy-set")}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":case"repo-policy-set":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,r={merge:!0,pr:!0}){if(!n)return[];let o=[],i=[];if(r.merge&&i.push(this.makeActionButton(e,"worktree-merge","Merge")),r.pr&&this.isGitHubCliAvailable())n.worktreePrUrl?(i.push(this.makeActionButton(e,"worktree-view-pr","View PR",{targetUrl:n.worktreePrUrl})),i.length>0&&o.push(i),o.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")),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-decide-later","Later"),this.makeActionButton(e,"worktree-dismiss","Discard")]));else return o.push([...i,this.makeActionButton(e,"worktree-decide-later","Later")]),o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o;return n.worktreePrUrl&&o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o}getPlanApprovalButtons(e,n){let r=n?.actionablePlanDecisionVersion??n?.planDecisionVersion;this.clearPlanDecisionTokens(e,r);let o=[[this.makeActionButton(e,"plan-approve","Approve",{planDecisionVersion:r}),this.makeActionButton(e,"plan-request-changes","Revise",{planDecisionVersion:r}),this.makeActionButton(e,"plan-reject","Reject",{planDecisionVersion:r})]];return B("plan_approval_buttons_created",{sessionId:e,planDecisionVersion:r,...Y(o)}),o}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,r={}){if(n.length===0)return;let o=n.map((s,a)=>{let d=this.createActionToken(e,"question-answer",{label:s.label,optionIndex:a,pendingInputRequestId:r.requestId,pendingInputQuestionId:r.questionId});return{label:Ly(s.label),callbackData:d.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=Du)i.push(o.slice(s,s+Du));return i}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 B("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,...Y(d)}),d}getRepoPolicyChoiceButtons(e){let n=bn(e.prAvailable??!0),r=Array.from({length:Math.ceil(n.length/2)},(o,i)=>n.slice(i*2,i*2+2)).map(o=>o.map(i=>this.makeActionButton(e.choiceId,"repo-policy-set",i.label,{route:e.route,repoPolicy:i.policy,repoPolicyWorkdir:e.repoRoot,launchName:e.launchName,launchPrompt:e.launchPrompt,launchWorkdir:e.launchWorkdir,launchModel:e.launchModel,launchReasoningEffort:e.launchReasoningEffort,launchFastMode:e.launchFastMode,launchSystemPrompt:e.launchSystemPrompt,launchAllowedTools:e.launchAllowedTools,launchResumeSessionId:e.launchResumeSessionId,launchResumeWorktreeFrom:e.launchResumeWorktreeFrom,launchSessionIdOverride:e.launchSessionIdOverride,launchClearedPersistedCodexResume:e.launchClearedPersistedCodexResume,launchForkSession:e.launchForkSession,launchForceNewSession:e.launchForceNewSession,launchPermissionMode:e.launchPermissionMode,launchPlanApproval:e.launchPlanApproval,launchHarness:e.launchHarness,launchWorktreeStrategy:e.launchWorktreeStrategy,launchWorktreeBaseBranch:e.launchWorktreeBaseBranch,launchWorktreePrTargetRepo:e.launchWorktreePrTargetRepo,launchOriginAgentId:e.launchOriginAgentId})));return B("repo_policy_choice_buttons_created",{choiceId:e.choiceId,repoRoot:e.repoRoot,channel:e.route.provider,target:e.route.target,accountId:e.route.accountId,threadId:e.route.threadId,sessionKey:e.route.sessionKey,labels:n.map(o=>o.label),...Y(r)}),r}};ee();xe();import{createHash as Ky}from"crypto";var By="duplicate notification already delivered or in flight",Wo=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:By}:(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))}};xe();ee();xe();import{createHash as Fy}from"crypto";var qy=1024,Ln="duplicate completion follow-up wake already handled",No="prior human-visible summary already delivered",Lo=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??qy))}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=this.buildPersistedKeyMap(i),a=o.decisionKeys.find(u=>this.inFlight.has(u)||!!this.getCompletedRecord(u)||s.has(u)),d=a?this.getCompletedRecord(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??Ln}:(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=this.buildPersistedKeyMap(s),d=i.decisionKeys.find(p=>!!this.getCompletedRecord(p)||a.has(p)),l=d?this.getCompletedRecord(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,No);let c=this.deliveredRecords(i.claimKeys,s,o,No);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:c}}finish(e,n,r=Ln){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=Ln){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=Ln){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===No&&o!==No||(this.completed.delete(i),this.completed.set(i,{skipReason:o,linkedKeys:n.filter(a=>a!==i)}));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),p=o.startsWith("worktree-pr:")?this.normalizeWorktreePrOutcome(n.outcomeKey?.trim()):void 0,f=p?.aliases.map(m=>`${this.buildVisibleScope(r,e)}:outcome:${this.digest(m)}`)??[];return{primary:a,explicit:!0,claimKeys:[...l,...d?u:[],...f,a],decisionKeys:[a,...p?.blocksAliases?f:[],...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.normalizeWorktreePrOutcome(n);return o?o.primary:n}normalizeWorktreePrOutcome(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;let d=["worktree-pr",o.toLowerCase(),s,a].join(":"),l=`${d}:created`;if(r.endsWith("updated")){let u=n.slice(5).join(":").trim();return{primary:u?`${d}:updated:${u}`:`${d}:updated`,aliases:[l,d],blocksAliases:!1}}return{primary:l,aliases:[d],blocksAliases:!0}}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=De(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,$(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 V(e)??$(e)??""}digest(e){return Fy("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):[]}buildPersistedKeyMap(e){let n=new Map;for(let r of e){n.set(r.key,r);for(let o of r.linkedKeys??[])o.trim()&&n.set(o,r)}return n}getCompletedRecord(e){let n=this.completed.get(e);if(n)return n;for(let r of this.completed.values())if(r.linkedKeys?.includes(e))return r}deliveredRecords(e,n,r,o=Ln){let i=new Date().toISOString(),s=this.normalizeRecords(n),a=new Set(e),l=[...s.filter(u=>!a.has(u.key)&&!(u.linkedKeys??[]).some(c=>a.has(c))),...e.map(u=>{let c=e.filter(p=>p!==u);return{key:u,linkedKeys:c.length>0?c:void 0,recordedAt:i,label:r,skipReason:o}})];return l.slice(Math.max(0,l.length-this.maxCompletedKeys))}};var Uy=2e3,Vy=new Set(["1","true","yes","on"]);function Gy(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&Vy.has(t))||is()}function jy(t){Gy()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
249
+ `)}var Bo=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new Lo({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new Wo({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()),m=!1,y=!1,k=()=>{y||(y=!0,m||(this.releaseNotificationDedupe(r,i),m=!0),this.completionSummaries.finish(l.key,!1))},S=u.shouldDispatch?()=>{let A=u.shouldDispatch?.()!==!1;return A||k(),A}:void 0,b={onNotifyStarted:()=>{this.applyDeliveryState(r,"notifying"),u.hooks?.onNotifyStarted?.()},onNotifySucceeded:()=>{m=!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),m=!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:()=>{m=!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:A=>{if(y){u.hooks?.onWakeSkipped?.(A);return}m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label,A),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(c),{completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:new Date().toISOString(),completionWakeSkipReason:A}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSkipped?.(A)},onWakeFailed:()=>{this.applyPersistedPatchWithCompletionWake(r,"failed",c,{completionWakeFailedAt:new Date().toISOString()}),this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),m=!0,u.hooks?.onWakeFailed?.()}};this.wakeDispatcher.dispatchSessionNotification(e,{...u,idempotencyKey:i??u.idempotencyKey,shouldDispatch:S,hooks:b})}notifyWorktreeOutcome(e,n,r={}){let o=this.getDeliveryRef(e),i=l=>Ht({sessionId:o,sessionName:e.name,outcomeLine:n,originThreadLine:rn(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:Uy,wakeMessageOnNotifySuccess:s&&d?i(!0):void 0,wakeMessageOnNotifyFailed:s&&d?i(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return V(e)??$(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}
250
250
  ${n.join(`
251
251
  ---completion-wake---
252
- `)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=Ee(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=Ee(e.session);Ky({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 Ly("sha256").update(e).digest("hex").slice(0,16)}};ke();import{existsSync as Uy}from"fs";var Lo=class{getCompletionState(e,n,r,o){let i=yn(e,r,o);if(i===void 0)return"has-commits";if(i===0){let s=yn(e,o,r);return s===void 0?"has-commits":s>0?Dt(e,r,o)?"merged":"base-advanced":at(n)?"dirty-uncommitted":"no-change"}return at(n)?"dirty-uncommitted":Pr(e,r,o)?"released":"has-commits"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!Uy(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}};import{randomUUID as Vy}from"node:crypto";function Gy(t){let e=t.pendingInputState,n=e?.activeQuestionIndex??0;return e?.questions?.[n]?.id??(e?.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:void 0)}var Bo=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??[],l=`❓ [${e.name}] ${s.question}`,d=Gy(e),u=e.pendingInputState?.requestId??`legacy:${Vy()}`,c=this.getQuestionButtons(e.id,a,{requestId:u,questionId:d}),p=[`[ASK USER QUESTION] Session "${e.name}" has a question requiring user input.`,"",`Question: ${s.question}`,...a.length>0?["Options:",...a.map((f,m)=>` ${m+1}. ${f.label}`)]:[],"",`Send the question to the user and call agent_respond(session="${e.id}", message="<answer>") with their answer.`].join(`
253
- `);return new Promise((f,m)=>{let y=this.pendingQuestions.get(e.id);y&&(clearTimeout(y.timeoutHandle),y.reject(new Error(`AskUserQuestion superseded by a newer question for session "${e.name}".`)));let k=setTimeout(()=>{this.pendingQuestions.delete(e.id),m(new Error(`AskUserQuestion timed out after ${6e5/1e3}s for session "${e.name}"`))},6e5);k.unref?.(),this.pendingQuestions.set(e.id,{resolve:f,reject:m,questions:i,timeoutHandle:k,requestId:u,questionId:d}),this.dispatchSessionNotification(e,{label:"ask-user-question",idempotencyKey:`ask-user-question:${e.id}:${u}`,userMessage:l,notifyUser:"always",buttons:c,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(`
254
- `),wakeMessageOnNotifyFailed:p})})}resolveAskUserQuestion(e,n,r={}){let o=this.pendingQuestions.get(e);if(!o)return`${e}`,!1;if(r.requestId&&r.requestId!==o.requestId)return`${e}${o.requestId}${r.requestId}`,!1;if(r.questionId&&r.questionId!==o.questionId)return`${e}${o.questionId??""}${r.questionId}`,!1;let i=o.questions[0],s=i.options??[],a=s[n];return a?(clearTimeout(o.timeoutHandle),this.pendingQuestions.delete(e),this.clearWaitingTimestamp(e),o.resolve({behavior:"allow",updatedInput:{questions:o.questions,answers:{[i.question]:a.label}}}),!0):(`${n}${e}${s.length}`,!1)}dispose(){for(let e of this.pendingQuestions.values())clearTimeout(e.timeoutHandle),e.reject(new Error("SessionManager disposed before AskUserQuestion resolved."));this.pendingQuestions.clear()}};X();Sn();var jy=new Set(["merged","released","dismissed","none","cleanup_failed"]),Hy=new Set(["merged","released","dismissed","no_change","none","cleanup_failed"]),Fo=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 fe(e))this.updatePersistedSession(s,{lastWorktreeReminderAt:new Date(n).toISOString()});return!0}sendReminderNotification(e,n){let r=this.buildRoutingProxy({id:e.sessionId??e.name??E(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:Ss(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(`
255
- `);this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,userMessage:o,notifyUser:"always",buttons:this.getWorktreeDecisionButtons(U(e)??e.harnessSessionId,e)})}clearResolvedReminderState(e){if(!e.pendingWorktreeDecisionSince&&!e.lastWorktreeReminderAt&&!e.worktreeDecisionSnoozedUntil||!this.isResolvedWorktreeDecision(e))return!1;let n=!1;for(let r of fe(e))n=this.updatePersistedSession(r,{pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0})||n;return n}getWorktreeDecisionReminderStatus(e,n){if(this.hasResolvedWorktreeDecisionMarker(e))return"resolved";if(!e.pendingWorktreeDecisionSince)return"inactive";let r=n??new Date(e.pendingWorktreeDecisionSince).getTime();if(!Number.isFinite(r))return"inactive";let o=e.worktreeState==="pending_decision"||e.lifecycle==="awaiting_worktree_decision"||e.worktreeLifecycle?.state==="pending_decision",i=e.worktreeState==null&&e.lifecycle==null&&e.worktreeLifecycle?.state==null&&!e.worktreeMerged&&!e.worktreePrUrl;if(!o&&!i)return"inactive";let s=Je(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(s.derivedState)?"resolved":"pending"}isResolvedWorktreeDecision(e){if(this.hasResolvedWorktreeDecisionMarker(e))return!0;let n=Je(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(n.derivedState)}hasResolvedWorktreeDecisionMarker(e){return!!(e.worktreeMerged||e.worktreePrUrl||e.lifecycle==="terminal"||e.worktreeState&&jy.has(e.worktreeState)||e.worktreeLifecycle?.state&&Hy.has(e.worktreeLifecycle.state))}isResolvedDerivedWorktreeState(e){return e==="merged"||e==="released"||e==="no_change"||e==="cleanup_failed"}};ke();X();Ie();function Nn(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&zy(t.approvalPromptStatus)}function zy(t){return t==="delivered"||t==="fallback_delivered"}function Ln(t,e){return!t||e==null?!1:!!(t.pendingPlanApproval&&t.approvalState==="pending"&&t.lifecycle==="awaiting_plan_decision"&&(t.actionablePlanDecisionVersion??t.planDecisionVersion)===e)}function zt(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(`
256
- `)}function qo(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(`
257
- `)}import{existsSync as ok,readFileSync as ik}from"fs";var Qy=4e3,Eu=180,Jy=300;function Du(){let t=_t(),e=Xy(t);if(e)return{async generateQuestionContextSummary(n){if(typeof e.generateQuestionContextSummary=="function")return await e.generateQuestionContextSummary(n);if(typeof e.summarizeQuestionContext=="function")return await e.summarizeQuestionContext(n);let r=ek(n);if(typeof e.generateObject=="function")return await e.generateObject({task:"openclaw-code-agent.question-context-summary",prompt:r,input:n});if(typeof e.generateText=="function")return await e.generateText({task:"openclaw-code-agent.question-context-summary",prompt:r});if(typeof e.complete=="function")return await e.complete({prompt:r})}}}async function Ou(t){let e=Ko(t.question??""),n=Ko(tk(e,t.context??""));if(!t.provider||!e||!n)return;let r={sessionName:t.sessionName,question:e,context:nk(n,Qy)};try{let o=await rk(t.provider.generateQuestionContextSummary(r),t.timeoutMs??Jy);return Yy(o)}catch(o){let i=o instanceof Error?o.message:String(o);i!=="question-context-summary timed out"&&`${i}`;return}}function Yy(t){let e=Zy(t),n=typeof e=="string"?e:e&&typeof e=="object"&&typeof e.summary=="string"?e.summary:void 0,r=Ko(n??"").replace(/^[-*•]\s+/,"").trim();if(!(!r||r.length>Eu)&&!(r.split(/[.!?]+/).filter(o=>o.trim()).length>1))return r}function Zy(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return e}}function Xy(t){return[t?.questionContextSummary,t?.llm,t?.ai,t?.model,t?.models].find(n=>!!(n&&typeof n=="object"&&(typeof n.generateQuestionContextSummary=="function"||typeof n.summarizeQuestionContext=="function"||typeof n.generateObject=="function"||typeof n.generateText=="function"||typeof n.complete=="function")))}function ek(t){return["Summarize why an OpenClaw Code Agent question is being asked.",'Return only JSON with shape {"summary":"..."}.',`Write one concise user-facing sentence under ${Eu} characters.`,"Do not answer the question. Do not invent choices. Do not alter option labels or semantics.","","Evidence:",JSON.stringify(t,null,2)].join(`
258
- `)}function tk(t,e){return t?e.split(/\r?\n/).filter(n=>Ko(n)!==t).join(`
259
- `):e}function Ko(t){return t.replace(/\s+/g," ").trim()}function nk(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function rk(t,e){return new Promise((n,r)=>{let o=setTimeout(()=>r(new Error("question-context-summary timed out")),e);o.unref?.(),t.then(i=>{clearTimeout(o),n(i)},i=>{clearTimeout(o),r(i)})})}var sk=280;function ak(t,e){if(t.latestPlanArtifactVersion===e&&t.latestPlanArtifact)return t.latestPlanArtifact;let n=t.planFilePath?.trim();if(!(!n||!ok(n)))try{let r=ik(n,"utf-8").trim();return r?{markdown:r,steps:[]}:void 0}catch{return}}function lk(t){let e=[t.total>1?`Question ${t.index+1}`:void 0,t.question.header].filter(Boolean).join(" - "),n=[...e?[e]:[],t.question.question];return t.optionDescriptions.length>0&&n.push("","Options:",...t.optionDescriptions.map(r=>`${r.label} - ${r.description}`)),n.join(`
260
- `)}function dk(t){return t.options.map(e=>({label:e.label,description:e.description?.trim()??""})).filter(e=>e.description&&e.description.length<=sk)}function Wu(t){let e=t?.activeQuestionIndex??0;return t?.questions?.[e]?.id??(t?.activeQuestionIndex!=null?`q${t.activeQuestionIndex}`:void 0)}function uk(t,e,n){let r=t.pendingInputState;return!!(r&&r.requestId===e&&Wu(r)===n)}var Uo=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:En({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>Ln(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:zt(e,n,!0),wakeMessageOnNotifyFailed:qo({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:!!Ee(e)}async handleTurnEnd(e,n){if(e.status!=="running"){`${e.id}${e.status}`;return}if(!e.goalTaskId){if(n||e.pendingPlanApproval){await 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),l=e.worktreeBranch,d=ue(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(a&&!d&&(u=pe(a,e.worktreePath)),a&&l&&!d&&u&&ye(a,l),u){for(let c of fe(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),l=ue(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:a&&!l&&pe(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,le(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 l=e.actionablePlanDecisionVersion??e.planDecisionVersion,d=Nn(e,l);if(a==="delegate"){this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${l??"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(`
261
- `),notifyUser:"never"}),this.deps.clearRetryTimersForSession(e.id);return}if(a==="ask"&&d){this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${l??"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${l??"?"}`,this.deps.originThreadLine(e),"Do NOT post another approval summary unless canonical delivery is known to be missing."].join(`
262
- `)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${l??"unknown"}:user-prompt`,userMessage:[`📋 [${e.name}] Plan v${l??"?"} still awaiting approval after idle timeout | ${i} | ${xe(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(`
263
- `),notifyUser:"always",buttons:a==="ask"&&!d?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:l}):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} | ${xe(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${ps(e.killReason)} | ${i} | ${xe(s)}`),this.deps.clearRetryTimersForSession(e.id)}async emitWaitingForInput(e){let n=e.pendingInputState?.questions,r=n?.[e.pendingInputState?.activeQuestionIndex??0],o=e.pendingInputState?.requestId,i=Wu(e.pendingInputState),s=o?[o,i].filter(Boolean).join(":"):void 0,a=s?`pending-input:${s}`:void 0;if(!this.deps.debounceWaitingEvent(e.id,a))return;let l=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0,d=e.actionablePlanDecisionVersion??e.planDecisionVersion,u=e.pendingPlanApproval&&l==="ask"&&Nn(e,d),c=e.pendingInputState?.promptText?.trim()||void 0,p=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),f=!e.pendingPlanApproval&&c?c:!e.pendingPlanApproval&&p!==void 0?p:this.deps.getOutputPreview(e,e.pendingPlanApproval&&l!=="delegate"?Number.POSITIVE_INFINITY:void 0),m=e.pendingInputState?.options.map(w=>({label:w}))??[],y=!n||n.length===0?m:r&&r.options.length>0&&r.options.length<=6&&!r.options.some(w=>w.isOther)&&!r.multiSelect?r.options:n.length===1&&r&&r.options.length===0?m:[],k=e.pendingPlanApproval&&l==="ask"&&!u?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:d}):!e.pendingPlanApproval&&y.length?this.deps.getQuestionButtons(e.id,y,{requestId:e.pendingInputState?.requestId,questionId:r?.id}):void 0,S=ak(e,d),b=r?dk(r):[],A=r?lk({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:b}):c,x=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await Ou({sessionName:e.name,question:A??f,context:p,provider:this.deps.questionContextSummaryProvider}):void 0,R=As({session:e,preview:f,questionText:e.pendingPlanApproval?void 0:A,questionContextPreview:p,questionContextSummary:x,planArtifact:S,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:l,planApprovalButtons:k,questionButtons:e.pendingPlanApproval?void 0:k}),h=R.planReviewSummary??f;if(R.label==="plan-approval"&&l==="ask"&&u){this.deps.dispatchSessionNotification(e,{label:R.label,idempotencyKey:`plan-approval:${e.id}:v${d??"unknown"}:canonical`,userMessage:R.userMessage,userMessages:R.userMessages,notifyUser:"never",buttons:R.buttons,wakeMessage:R.wakeMessage});return}if(R.label==="plan-approval"&&l==="ask"){this.deps.dispatchSessionNotification(e,{label:R.label,idempotencyKey:`plan-approval:${e.id}:v${d??"unknown"}:canonical`,userMessage:R.userMessage,userMessages:R.userMessages,notifyUser:"always",buttons:R.buttons,hooks:{onNotifyStarted:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.deps.updatePersistedSession(e.id,{canonicalPlanPromptVersion:d,approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>Ln(e,d),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,d,h),wakeMessageOnNotifySuccess:zt(e,d)});return}if(R.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:R.label,idempotencyKey:`plan-approval:${e.id}:v${d??"unknown"}:wake-only`,userMessage:R.userMessage,wakeMessage:R.wakeMessage,notifyUser:"never",buttons:R.buttons});return}this.deps.dispatchSessionNotification(e,{label:R.label,idempotencyKey:`waiting:${e.id}:${s??`${R.label}:${R.userMessage}`}`,userMessage:R.userMessage,notifyUser:"always",buttons:R.buttons,shouldDispatch:o?()=>uk(e,o,i):void 0,wakeMessageOnNotifyFailed:R.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=ys({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=fs({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=hs({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})}};X();ke();import{existsSync as ck}from"fs";var Vo=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,l=r?.name??n?.name??e;if(!s)return`Error: No workdir found for session "${e}".`;let d=ue(o);!d&&i&&ck(i)&&pe(s,i,{destructive:!0}),a&&ye(s,a);for(let c of fe(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=d?`🗑️ [${l}] Branch \`${a??"unknown"}\` dismissed. Native backend worktree released for backend cleanup.`:`🗑️ [${l}] Branch \`${a??"unknown"}\` dismissed and permanently deleted.`;return this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:U(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:${U(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 l of fe(r))this.deps.updatePersistedSession(l,{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:U(r)??E(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${U(r)??E(r)??r.harnessSessionId}:${i}`,userMessage:a,notifyUser:"always"}),a}};var Nu=new Set(["starting","running"]);function Lu(t,e){JSON.stringify({component:"SessionRuntimeRegistry",event:t,at:new Date().toISOString(),...e})}function Bu(t){return{sessionId:t.id,name:t.name,status:t.status,lifecycle:t.lifecycle,runtimeState:t.runtimeState,harness:t.harnessName,hasHarnessSessionId:!!t.harnessSessionId,backendRefKind:t.backendRef?.kind,hasBackendConversationId:!!t.backendRef?.conversationId,hasBackendRunId:!!t.backendRef?.runId,hasBackendWorktreeId:!!t.backendRef?.worktreeId,hasBackendWorktreePath:!!t.backendRef?.worktreePath}}var Go=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>Nu.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>Nu.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,n="spawn"){Lu("runtime.add",{reason:n,...Bu(e),activeCountBefore:this.activeSessionCount()}),this.sessions.set(e.id,e)}remove(e,n="unknown"){let r=this.sessions.get(e);Lu("runtime.remove",{reason:n,sessionId:e,existed:!!r,...r?Bu(r):{},activeCountBefore:this.activeSessionCount()}),this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var jo=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).catch(a=>{console.error(`[SessionRuntimeBootstrap] handleTurnEnd threw for session ${e.id}:`,a)})}),e.start(),o.notifyLaunch!==!1){let i=this.deps.formatLaunchWorkdirLabel(e),s=`🚀 [${e.name}] Launched | ${i} | ${fn({harness:e.harnessName,model:e.model})??"default"}`;this.deps.notifySession(e,s,"launch")}return e}};var Ho=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,worktreeBranch:s,preview:a,originThreadLine:l,preservedSummary:d}=e,u=d?"preserved":o?"cleaned":"cleanup-failed",c=[s?.trim()||"unknown-branch",i.trim()||"unknown-worktree",n.completedAt??"unknown-completed-at"].join(":"),p=d??(o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`);return{label:d?"worktree-no-changes-preserved":o?"worktree-no-changes":"worktree-no-changes-cleanup-failed",idempotencyKey:`worktree-no-change:${n.id}:${u}:${c}`,userMessage:d?`ℹ️ [${n.name}] Session completed with no worktree changes to merge — ${d}`:o?r?`ℹ️ [${n.name}] Session completed with no worktree changes to merge — native backend worktree released for backend cleanup`:`ℹ️ [${n.name}] Session completed with no worktree changes to merge — worktree cleaned up`:`⚠️ [${n.name}] Session completed with no worktree changes to merge, but worktree cleanup failed. Worktree still exists at ${i}`,wakeMessage:vs({sessionName:n.name,sessionId:n.id,cleanupSummary:p,preview:a,originThreadLine:l,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=[],policyReason:l}=e,d=i.commitMessages.slice(0,5).map(p=>`• ${p.hash} ${p.message} (${p.author})`),u=i.commits>5?`...and ${i.commits-5} more`:"",c=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(p=>p.hash).join(",")].join(":"),userMessage:[`🔀 Worktree decision required for session \`${n.name}\``,"",c,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`,"",...a.length>0?["Summary:",...a.map(p=>`- ${p}`),""]:[],...l?[`Policy: ${l}`,""]:[],"Recent commits:",...d,...u?[u]:[],"",`⚠️ Discard will permanently delete branch \`${r}\` and all local changes. This cannot be undone.`].join(`
252
+ `)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=De(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=De(e.session);jy({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 Ky("sha256").update(e).digest("hex").slice(0,16)}};ke();import{existsSync as Hy}from"fs";var Fo=class{getCompletionState(e,n,r,o){let i=vn(e,r,o);if(i===void 0)return"has-commits";if(i===0){let s=vn(e,o,r);return s===void 0?"has-commits":s>0?dt(e,r,o)?"merged":"base-advanced":ut(n)?"dirty-uncommitted":"no-change"}return ut(n)?"dirty-uncommitted":Rr(e,r,o)?"released":"has-commits"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!Hy(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}};import{randomUUID as zy}from"node:crypto";function Qy(t){let e=t.pendingInputState,n=e?.activeQuestionIndex??0;return e?.questions?.[n]?.id??(e?.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:void 0)}var qo=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=`❓ [${e.name}] ${s.question}`,l=Qy(e),u=e.pendingInputState?.requestId??`legacy:${zy()}`,c=this.getQuestionButtons(e.id,a,{requestId:u,questionId:l}),p=[`[ASK USER QUESTION] Session "${e.name}" has a question requiring user input.`,"",`Question: ${s.question}`,...a.length>0?["Options:",...a.map((f,m)=>` ${m+1}. ${f.label}`)]:[],"",`Send the question to the user and call agent_respond(session="${e.id}", message="<answer>") with their answer.`].join(`
253
+ `);return new Promise((f,m)=>{let y=this.pendingQuestions.get(e.id);y&&(clearTimeout(y.timeoutHandle),y.reject(new Error(`AskUserQuestion superseded by a newer question for session "${e.name}".`)));let k=setTimeout(()=>{this.pendingQuestions.delete(e.id),m(new Error(`AskUserQuestion timed out after ${6e5/1e3}s for session "${e.name}"`))},6e5);k.unref?.(),this.pendingQuestions.set(e.id,{resolve:f,reject:m,questions:i,timeoutHandle:k,requestId:u,questionId:l}),this.dispatchSessionNotification(e,{label:"ask-user-question",idempotencyKey:`ask-user-question:${e.id}:${u}`,userMessage:d,notifyUser:"always",buttons:c,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(`
254
+ `),wakeMessageOnNotifyFailed:p})})}resolveAskUserQuestion(e,n,r={}){let o=this.pendingQuestions.get(e);if(!o)return`${e}`,!1;if(r.requestId&&r.requestId!==o.requestId)return`${e}${o.requestId}${r.requestId}`,!1;if(r.questionId&&r.questionId!==o.questionId)return`${e}${o.questionId??""}${r.questionId}`,!1;let i=o.questions[0],s=i.options??[],a=s[n];return a?(clearTimeout(o.timeoutHandle),this.pendingQuestions.delete(e),this.clearWaitingTimestamp(e),o.resolve({behavior:"allow",updatedInput:{questions:o.questions,answers:{[i.question]:a.label}}}),!0):(`${n}${e}${s.length}`,!1)}dispose(){for(let e of this.pendingQuestions.values())clearTimeout(e.timeoutHandle),e.reject(new Error("SessionManager disposed before AskUserQuestion resolved."));this.pendingQuestions.clear()}};ee();wn();var Jy=new Set(["merged","released","dismissed","none","cleanup_failed"]),Yy=new Set(["merged","released","dismissed","no_change","none","cleanup_failed"]),Ko=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 fe(e))this.updatePersistedSession(s,{lastWorktreeReminderAt:new Date(n).toISOString()});return!0}sendReminderNotification(e,n){let r=this.buildRoutingProxy({id:e.sessionId??e.name??$(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:ws(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(`
255
+ `);this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,userMessage:o,notifyUser:"always",buttons:this.getWorktreeDecisionButtons(V(e)??e.harnessSessionId,e)})}clearResolvedReminderState(e){if(!e.pendingWorktreeDecisionSince&&!e.lastWorktreeReminderAt&&!e.worktreeDecisionSnoozedUntil||!this.isResolvedWorktreeDecision(e))return!1;let n=!1;for(let r of fe(e))n=this.updatePersistedSession(r,{pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0})||n;return n}getWorktreeDecisionReminderStatus(e,n){if(this.hasResolvedWorktreeDecisionMarker(e))return"resolved";if(!e.pendingWorktreeDecisionSince)return"inactive";let r=n??new Date(e.pendingWorktreeDecisionSince).getTime();if(!Number.isFinite(r))return"inactive";let o=e.worktreeState==="pending_decision"||e.lifecycle==="awaiting_worktree_decision"||e.worktreeLifecycle?.state==="pending_decision",i=e.worktreeState==null&&e.lifecycle==null&&e.worktreeLifecycle?.state==null&&!e.worktreeMerged&&!e.worktreePrUrl;if(!o&&!i)return"inactive";let s=Xe(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(s.derivedState)?"resolved":"pending"}isResolvedWorktreeDecision(e){if(this.hasResolvedWorktreeDecisionMarker(e))return!0;let n=Xe(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(n.derivedState)}hasResolvedWorktreeDecisionMarker(e){return!!(e.worktreeMerged||e.worktreePrUrl||e.lifecycle==="terminal"||e.worktreeState&&Jy.has(e.worktreeState)||e.worktreeLifecycle?.state&&Yy.has(e.worktreeLifecycle.state))}isResolvedDerivedWorktreeState(e){return e==="merged"||e==="released"||e==="no_change"||e==="cleanup_failed"}};ke();ee();xe();function Bn(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&Zy(t.approvalPromptStatus)}function Zy(t){return t==="delivered"||t==="fallback_delivered"}function Fn(t,e){return!t||e==null?!1:!!(t.pendingPlanApproval&&t.approvalState==="pending"&&t.lifecycle==="awaiting_plan_decision"&&(t.actionablePlanDecisionVersion??t.planDecisionVersion)===e)}function Yt(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(`
256
+ `)}function Uo(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(`
257
+ `)}import{existsSync as dk,readFileSync as lk}from"fs";var Xy=4e3,Wu=180,ek=300;function Nu(){let t=Dt(),e=rk(t);if(e)return{async generateQuestionContextSummary(n){if(typeof e.generateQuestionContextSummary=="function")return await e.generateQuestionContextSummary(n);if(typeof e.summarizeQuestionContext=="function")return await e.summarizeQuestionContext(n);let r=ok(n);if(typeof e.generateObject=="function")return await e.generateObject({task:"openclaw-code-agent.question-context-summary",prompt:r,input:n});if(typeof e.generateText=="function")return await e.generateText({task:"openclaw-code-agent.question-context-summary",prompt:r});if(typeof e.complete=="function")return await e.complete({prompt:r})}}}async function Lu(t){let e=Vo(t.question??""),n=Vo(ik(e,t.context??""));if(!t.provider||!e||!n)return;let r={sessionName:t.sessionName,question:e,context:sk(n,Xy)};try{let o=await ak(t.provider.generateQuestionContextSummary(r),t.timeoutMs??ek);return tk(o)}catch(o){let i=o instanceof Error?o.message:String(o);i!=="question-context-summary timed out"&&`${i}`;return}}function tk(t){let e=nk(t),n=typeof e=="string"?e:e&&typeof e=="object"&&typeof e.summary=="string"?e.summary:void 0,r=Vo(n??"").replace(/^[-*•]\s+/,"").trim();if(!(!r||r.length>Wu)&&!(r.split(/[.!?]+/).filter(o=>o.trim()).length>1))return r}function nk(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return e}}function rk(t){return[t?.questionContextSummary,t?.llm,t?.ai,t?.model,t?.models].find(n=>!!(n&&typeof n=="object"&&(typeof n.generateQuestionContextSummary=="function"||typeof n.summarizeQuestionContext=="function"||typeof n.generateObject=="function"||typeof n.generateText=="function"||typeof n.complete=="function")))}function ok(t){return["Summarize why an OpenClaw Code Agent question is being asked.",'Return only JSON with shape {"summary":"..."}.',`Write one concise user-facing sentence under ${Wu} characters.`,"Do not answer the question. Do not invent choices. Do not alter option labels or semantics.","","Evidence:",JSON.stringify(t,null,2)].join(`
258
+ `)}function ik(t,e){return t?e.split(/\r?\n/).filter(n=>Vo(n)!==t).join(`
259
+ `):e}function Vo(t){return t.replace(/\s+/g," ").trim()}function sk(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function ak(t,e){return new Promise((n,r)=>{let o=setTimeout(()=>r(new Error("question-context-summary timed out")),e);o.unref?.(),t.then(i=>{clearTimeout(o),n(i)},i=>{clearTimeout(o),r(i)})})}var uk=280;function ck(t,e){if(t.latestPlanArtifactVersion===e&&t.latestPlanArtifact)return t.latestPlanArtifact;let n=t.planFilePath?.trim();if(!(!n||!dk(n)))try{let r=lk(n,"utf-8").trim();return r?{markdown:r,steps:[]}:void 0}catch{return}}function pk(t){let e=[t.total>1?`Question ${t.index+1}`:void 0,t.question.header].filter(Boolean).join(" - "),n=[...e?[e]:[],t.question.question];return t.optionDescriptions.length>0&&n.push("","Options:",...t.optionDescriptions.map(r=>`${r.label} - ${r.description}`)),n.join(`
260
+ `)}function mk(t){return t.options.map(e=>({label:e.label,description:e.description?.trim()??""})).filter(e=>e.description&&e.description.length<=uk)}function Fu(t){let e=t?.activeQuestionIndex??0;return t?.questions?.[e]?.id??(t?.activeQuestionIndex!=null?`q${t.activeQuestionIndex}`:void 0)}function fk(t,e,n){let r=t.pendingInputState;return!!(r&&r.requestId===e&&Fu(r)===n)}function gk(t){return[t.startedAt??"unknown-started-at",t.result?.session_id??"unknown-backend-session",t.result?.num_turns??0].join(":")}function Bu(t){return[t.status,t.startedAt??"unknown-started-at",t.result?.session_id??"unknown-backend-session",t.result?.num_turns??0,t.killReason??"unknown"].join(":")}var Go=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:On({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>Fn(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:Yt(e,n,!0),wakeMessageOnNotifyFailed:Uo({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:!!De(e)}async handleTurnEnd(e,n){if(e.status!=="running"){`${e.id}${e.status}`;return}if(!e.goalTaskId){if(n||e.pendingPlanApproval){await 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=ue(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(a&&!l&&(u=pe(a,e.worktreePath)),a&&d&&!l&&u&&ye(a,d),u){for(let c of fe(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=ue(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:a&&!d&&pe(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,de(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=Bn(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(`
261
+ `),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(`
262
+ `)}),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} | ${Te(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(`
263
+ `),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} | ${Te(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${fs(e.killReason)} | ${i} | ${Te(s)}`),this.deps.clearRetryTimersForSession(e.id)}async emitWaitingForInput(e){let n=e.pendingInputState?.questions,r=n?.[e.pendingInputState?.activeQuestionIndex??0],o=e.pendingInputState?.requestId,i=Fu(e.pendingInputState),s=o?[o,i].filter(Boolean).join(":"):void 0,a=s?`pending-input:${s}`:void 0;if(!this.deps.debounceWaitingEvent(e.id,a))return;let d=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0,l=e.actionablePlanDecisionVersion??e.planDecisionVersion,u=e.pendingPlanApproval&&d==="ask"&&Bn(e,l),c=e.pendingInputState?.promptText?.trim()||void 0,p=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),f=!e.pendingPlanApproval&&c?c:!e.pendingPlanApproval&&p!==void 0?p:this.deps.getOutputPreview(e,e.pendingPlanApproval&&d!=="delegate"?Number.POSITIVE_INFINITY:void 0),m=e.pendingInputState?.options.map(w=>({label:w}))??[],y=!n||n.length===0?m:r&&r.options.length>0&&r.options.length<=6&&!r.options.some(w=>w.isOther)&&!r.multiSelect?r.options:n.length===1&&r&&r.options.length===0?m:[],k=e.pendingPlanApproval&&d==="ask"&&!u?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:l}):!e.pendingPlanApproval&&y.length?this.deps.getQuestionButtons(e.id,y,{requestId:e.pendingInputState?.requestId,questionId:r?.id}):void 0,S=ck(e,l),b=r?mk(r):[],A=r?pk({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:b}):c,x=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await Lu({sessionName:e.name,question:A??f,context:p,provider:this.deps.questionContextSummaryProvider}):void 0,R=xs({session:e,preview:f,questionText:e.pendingPlanApproval?void 0:A,questionContextPreview:p,questionContextSummary:x,planArtifact:S,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:d,planApprovalButtons:k,questionButtons:e.pendingPlanApproval?void 0:k}),h=R.planReviewSummary??f;if(R.label==="plan-approval"&&d==="ask"&&u){this.deps.dispatchSessionNotification(e,{label:R.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:R.userMessage,userMessages:R.userMessages,notifyUser:"never",buttons:R.buttons,wakeMessage:R.wakeMessage});return}if(R.label==="plan-approval"&&d==="ask"){this.deps.dispatchSessionNotification(e,{label:R.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:R.userMessage,userMessages:R.userMessages,notifyUser:"always",buttons:R.buttons,hooks:{onNotifyStarted:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.deps.updatePersistedSession(e.id,{canonicalPlanPromptVersion:l,approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>Fn(e,l),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,l,h),wakeMessageOnNotifySuccess:Yt(e,l)});return}if(R.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:R.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:wake-only`,userMessage:R.userMessage,wakeMessage:R.wakeMessage,notifyUser:"never",buttons:R.buttons});return}this.deps.dispatchSessionNotification(e,{label:R.label,idempotencyKey:`waiting:${e.id}:${s??`${R.label}:${R.userMessage}`}`,userMessage:R.userMessage,notifyUser:"always",buttons:R.buttons,shouldDispatch:o?()=>fk(e,o,i):void 0,wakeMessageOnNotifyFailed:R.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=Ss({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${gk(e)}`,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=hs({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i=Bu(e),s=`terminal:${e.id}:${i}`,a;this.deps.dispatchSessionNotification(e,{label:"completed",idempotencyKey:`terminal-completed:${e.id}:${i}`,userMessage:o.userMessage,notifyUser:"always",completionSummary:{required:r,producer:"terminal",outcomeKey:s},completionWakeSummaryRequired:r,completionWakeOutcomeKey:s,requireDirectUserNotification:!0,wakeMessageOnNotifySuccess:r?o.wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:r?o.wakeMessageOnNotifyFailed:void 0,hooks:{onNotifySucceeded:()=>{a=!0,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_succeeded",canonicalStatusDelivered:a,followupSummaryRequired:r})},onNotifyFailed:()=>{a=!1,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_failed",canonicalStatusDelivered:a,followupSummaryRequired:r})},onWakeSucceeded:()=>{this.logCompletionWakeDiagnostic({session:e,event:"completion_wake_succeeded",canonicalStatusDelivered:a,followupSummaryRequired:r})}}})}emitFailed(e,n,r){let o=ks({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}:${Bu(e)}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};ee();ke();import{existsSync as hk}from"fs";var jo=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=ue(o);!l&&i&&hk(i)&&pe(s,i,{destructive:!0}),a&&ye(s,a);for(let c of fe(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:V(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:${V(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 fe(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:V(r)??$(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${V(r)??$(r)??r.harnessSessionId}:${i}`,userMessage:a,notifyUser:"always"}),a}};var qu=new Set(["starting","running"]);function Ku(t,e){JSON.stringify({component:"SessionRuntimeRegistry",event:t,at:new Date().toISOString(),...e})}function Uu(t){return{sessionId:t.id,name:t.name,status:t.status,lifecycle:t.lifecycle,runtimeState:t.runtimeState,harness:t.harnessName,hasHarnessSessionId:!!t.harnessSessionId,backendRefKind:t.backendRef?.kind,hasBackendConversationId:!!t.backendRef?.conversationId,hasBackendRunId:!!t.backendRef?.runId,hasBackendWorktreeId:!!t.backendRef?.worktreeId,hasBackendWorktreePath:!!t.backendRef?.worktreePath}}var Ho=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>qu.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>qu.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,n="spawn"){Ku("runtime.add",{reason:n,...Uu(e),activeCountBefore:this.activeSessionCount()}),this.sessions.set(e.id,e)}remove(e,n="unknown"){let r=this.sessions.get(e);Ku("runtime.remove",{reason:n,sessionId:e,existed:!!r,...r?Uu(r):{},activeCountBefore:this.activeSessionCount()}),this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var zo=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).catch(a=>{console.error(`[SessionRuntimeBootstrap] handleTurnEnd threw for session ${e.id}:`,a)})}),e.start(),o.notifyLaunch!==!1){let i=this.buildLaunchNotification(e);this.deps.notifySession(e,i.text,i.label,i.idempotencyKey)}return e}buildLaunchNotification(e){let n=this.deps.formatLaunchWorkdirLabel(e),r=yn({harness:e.harnessName,model:e.model})??"default";return e.resumeSessionId?{text:`▶️ [${e.name}] Resumed | ${n} | ${r}`,label:"resumed-launch",idempotencyKey:`resumed-launch:${e.id}:${e.startedAt}:${e.resumeSessionId}`}:{text:`🚀 [${e.name}] Launched | ${n} | ${r}`,label:"launch"}}};var Qo=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,worktreeBranch:s,preview:a,originThreadLine:d,preservedSummary:l}=e,u=l?"preserved":o?"cleaned":"cleanup-failed",c=[s?.trim()||"unknown-branch",i.trim()||"unknown-worktree",n.startedAt].join(":"),p=l??(o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`);return{label:l?"worktree-no-changes-preserved":o?"worktree-no-changes":"worktree-no-changes-cleanup-failed",idempotencyKey:`worktree-no-change:${n.id}:${u}:${c}`,userMessage:l?`ℹ️ [${n.name}] Session completed with no worktree changes to merge — ${l}`:o?r?`ℹ️ [${n.name}] Session completed with no worktree changes to merge — native backend worktree released for backend cleanup`:`ℹ️ [${n.name}] Session completed with no worktree changes to merge — worktree cleaned up`:`⚠️ [${n.name}] Session completed with no worktree changes to merge, but worktree cleanup failed. Worktree still exists at ${i}`,wakeMessage:Ps({sessionName:n.name,sessionId:n.id,cleanupSummary:p,preview:a,originThreadLine:d,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=[],policyReason:d}=e,l=i.commitMessages.slice(0,5).map(p=>`• ${p.hash} ${p.message} (${p.author})`),u=i.commits>5?`...and ${i.commits-5} more`:"",c=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(p=>p.hash).join(",")].join(":"),userMessage:[`🔀 Worktree decision required for session \`${n.name}\``,"",c,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`,"",...a.length>0?["Summary:",...a.map(p=>`- ${p}`),""]:[],...d?[`Policy: ${d}`,""]:[],"Recent commits:",...l,...u?[u]:[],"",`⚠️ Discard will permanently delete branch \`${r}\` and all local changes. This cannot be undone.`].join(`
264
264
  `),notifyUser:"always",buttons:s,wakeMessageOnNotifySuccess:["Worktree decision buttons delivered to the user.",`Session: ${n.name} | ID: ${n.id}`,c,"Wait for their button callback — do NOT act on this worktree yourself."].join(`
265
265
  `),wakeMessageOnNotifyFailed:[`🔀 Worktree decision required for session \`${n.name}\``,"",c,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`].join(`
266
- `)}}buildDelegateNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,policyReason:s,allowedActions:a,originThreadLine:l}=e,d=i.commitMessages.slice(0,5).map(p=>`• ${p.hash} ${p.message} (${p.author})`),u=i.commits>5?`...and ${i.commits-5} more`:void 0,c=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(p=>p.hash).join(",")].join(":"),wakeMessage:ks({sessionName:n.name,sessionId:n.id,branchName:r,baseBranch:o,promptSnippet:c,commitLines:d,moreNote:u,originThreadLine:l,diffSummary:i,allowedActions:a,policyReason:s}),notifyUser:"never"}}};function Fu(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
267
- `):pk(t);return n?o:o.length>e?qu(t)?Da(o,e):Oa(o,e):o}function pk(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
268
- `).trim();return n?qu(t)?mk(n)??n:e.slice(-20).join(`
269
- `):""}function qu(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 mk(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(`
270
- `)?n:void 0}Ie();ke();ae();import{unlinkSync as fk}from"fs";var zo=class t{timers=new Map;disposed=!1;static MAX_DELAY_MS=2147483647;schedule(e,n,r){if(this.disposed||(this.cancel(e),!Number.isFinite(n)))return;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()}};X();Sn();ke();var Ku=10080*60*1e3,gk=300*1e3,Uu="tmp-output:cleanup",hk=60*1e3;function yk(t){return t instanceof Error?t.message:String(t)}var Qo=class{constructor(e){this.deps=e}deps;scheduler=new zo;lastTmpOutputCleanupAttemptAt;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.runTmpOutputCleanup(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,"runtime-gc"),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=Je(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+Ku,()=>{let l=this.deps.store.getPersistedSession(n);l&&this.reconcileResolvedWorktreeRetention(l,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=Je(e,{activeSession:!1,includePrSync:e.worktreeLifecycle?.state==="pr_open"||!!e.worktreePrUrl}),o=this.resolvedAtIso(e),i=o?new Date(o).getTime():0,s=this.legacyResolvedWorktreeState(e);if(!(!r.cleanupSafe&&!s||!o||!Number.isFinite(i)||n-i<Ku))try{if(!e.worktreePath&&!ue(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let l=ue(e)?!1:pe(a,e.worktreePath);if(!ue(e)&&!l)return;for(let d of fe(e))this.deps.updatePersistedSession(d,{worktreePath:void 0,worktreeBranch:void 0,worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{...e.worktreeLifecycle??r.lifecycle,state:r.cleanupSafe?r.derivedState:s??r.derivedState,updatedAt:new Date(n).toISOString(),resolvedAt:e.worktreeLifecycle?.resolvedAt??o,resolutionSource:e.worktreeLifecycle?.resolutionSource??"maintenance",notes:r.reasons}})}catch(a){`${e.worktreePath}${yk(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())||this.syncActionTokenExpiryDeadline()})}syncTmpOutputCleanupDeadline(e=Date.now()){this.cancel(Uu);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(Uu,this.getTmpOutputCleanupScheduleAt(n,e),()=>{let r=Date.now();this.runTmpOutputCleanup(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??E(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(D.sessionGcAgeMinutes??1440)*6e4}runTmpOutputCleanup(e){this.lastTmpOutputCleanupAttemptAt=e,this.deps.store.cleanupTmpOutputFiles(e)}getTmpOutputCleanupScheduleAt(e,n){if(e>n||this.lastTmpOutputCleanupAttemptAt==null)return e;let r=this.lastTmpOutputCleanupAttemptAt+hk;return r>n?r:e}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()+gk))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{fk(e)}catch{}}resolvedAtIso(e){return e.worktreeLifecycle?.resolvedAt??e.worktreeMergedAt??e.worktreeDismissedAt??(e.completedAt?new Date(e.completedAt).toISOString():void 0)}isLegacyResolvedWorktree(e){return this.legacyResolvedWorktreeState(e)!=null}legacyResolvedWorktreeState(e){if(e.worktreeMerged===!0||e.worktreeDisposition==="merged"||e.worktreeState==="merged")return"merged";if(e.worktreeDisposition==="dismissed"||e.worktreeState==="dismissed")return"dismissed";if(e.worktreeDisposition==="no-change-cleaned")return"no_change"}};Rn();var Vu=new Set(["completed","failed","killed"]),kk=new Set(["starting","running"]),Sk=5e3;function vk(t,e){return Gu("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.prompt,workdir:t.workdir,name:t.name,model:t.model,reasoningEffort:t.reasoningEffort,fastMode:t.fastMode,systemPrompt:t.systemPrompt,allowedTools:t.allowedTools?[...t.allowedTools].sort():t.allowedTools,resumeSessionId:t.resumeSessionId,resumeWorktreeFrom:t.resumeWorktreeFrom,sessionIdOverride:t.sessionIdOverride,clearedPersistedCodexResume:t.clearedPersistedCodexResume,forkSession:t.forkSession,forceNewSession:t.forceNewSession,permissionMode:t.permissionMode,planApproval:t.planApproval,harness:t.harness,worktreeStrategy:t.worktreeStrategy,effectiveWorktreeStrategy:e,worktreeBaseBranch:t.worktreeBaseBranch,worktreePrTargetRepo:t.worktreePrTargetRepo,originAgentId:t.originAgentId})).digest("hex").slice(0,16)}function wk(t){return Gu("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.launchPrompt,workdir:t.launchWorkdir,name:t.launchName,model:t.launchModel,reasoningEffort:t.launchReasoningEffort,fastMode:t.launchFastMode,systemPrompt:t.launchSystemPrompt,allowedTools:t.launchAllowedTools?[...t.launchAllowedTools].sort():t.launchAllowedTools,resumeSessionId:t.launchResumeSessionId,resumeWorktreeFrom:t.launchResumeWorktreeFrom,sessionIdOverride:t.launchSessionIdOverride,clearedPersistedCodexResume:t.launchClearedPersistedCodexResume,forkSession:t.launchForkSession,forceNewSession:t.launchForceNewSession,permissionMode:t.launchPermissionMode,planApproval:t.launchPlanApproval,harness:t.launchHarness,worktreeStrategy:t.launchWorktreeStrategy,worktreeBaseBranch:t.launchWorktreeBaseBranch,worktreePrTargetRepo:t.launchWorktreePrTargetRepo,originAgentId:t.launchOriginAgentId})).digest("hex").slice(0,16)}var Jo=class t{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;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.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 Go,o=r.sessions,i=new bo(n.store),s=new Ro,a=new $o,l=new Eo(i.actionTokenStore,Te),d=new po(o,i),u=new co({store:i,sessions:o,resolveSession:h=>d.resolveActive(h)}),c=new No(a,(h,w)=>u.applySessionPatch(h,w),{getPersistedSession:h=>i.getPersistedSession(h)}),p=new Lo,f=new uo(h=>i.getPersistedSession(h)),m=new Ho,y=new ko({shouldRunWorktreeStrategy:h=>e.shouldRunWorktreeStrategy(h),isAlreadyMerged:h=>e.isAlreadyMerged(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),getWorktreeCompletionState:(h,w,L,ne)=>e.getWorktreeCompletionState(h,w,L,ne),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchSessionNotification:(h,w)=>e.dispatchSessionNotification(h,w),getOutputPreview:(h,w)=>e.getOutputPreview(h,w),originThreadLine:h=>e.originThreadLine(h),getWorktreeDecisionButtons:h=>e.getWorktreeDecisionButtons(h),getPolicyAwareWorktreeDecisionButtons:(h,w,L)=>e.getWorktreeDecisionButtons(h,w,L),makeOpenPrButton:h=>e.makeActionButton(h,"worktree-create-pr","Open PR"),isPrAvailable:h=>e.resolveRepoPolicy(h).prAvailable,hasOpenPrForBranch:(h,w,L)=>{let ne=Be(h,w,L);return ne.exists&&ne.state==="open"},resolveRepoPolicy:h=>e.resolveRepoPolicy(h),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:m,enqueueMerge:(h,w,L)=>e.enqueueMerge(h,w,L),mergeBranch:Ir,spawnConflictResolver:async({session:h,worktreePath:w,prompt:L})=>e.spawn({prompt:L,workdir:w,name:`${h.name}-conflict-resolver`,harness:h.harnessName||de(),model:h.model,reasoningEffort:h.reasoningEffort,fastMode:h.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:h.id,route:h.route,originChannel:h.originChannel,originThreadId:h.originThreadId,originAgentId:h.originAgentId,originSessionKey:h.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(h,w)=>{let{makeAgentPrTool:L}=await Promise.resolve().then(()=>(zr(),Kl));return{success:(await L().execute("auto-pr",{session:h.id,base_branch:w}))?.meta?.success===!0}}}),k=new Bo(e.pendingAskUserQuestions,(h,w)=>e.dispatchSessionNotification(h,w),h=>{e.clearWaitingTimestampsForSession(h)},(h,w,L)=>l.getQuestionButtons(h,w,L)),S=new Fo(h=>e.buildRoutingProxy(h),(h,w)=>c.dispatch(h,w),(h,w)=>e.updatePersistedSession(h,w),(h,w)=>e.getPolicyAwareWorktreeDecisionButtons(h,{},void 0,w)),b=new Qo({store:i,sessions:o,reminders:S,removeRuntimeSession:(h,w)=>r.remove(h,w),persistSession:(h,w)=>e.persistSession(h,w),clearRuntimeSessionState:h=>{e.clearWaitingTimestampsForSession(h),e.lastTurnCompleteMarkers.delete(h),e.lastTerminalWakeMarkers.delete(h)},resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let A=new Uo({persistSession:h=>e.persistSession(h),clearWaitingTimestamp:h=>{e.clearWaitingTimestampsForSession(h)},handleWorktreeStrategy:h=>e.handleWorktreeStrategy(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchSessionNotification:(h,w)=>e.dispatchSessionNotification(h,w),notifySession:(h,w,L)=>e.notifySession(h,w,L),clearRetryTimersForSession:h=>a.clearRetryTimersForSession(h),hasTurnCompleteWakeMarker:h=>e.lastTurnCompleteMarkers.has(h),shouldEmitTurnCompleteWake:h=>e.shouldEmitTurnCompleteWake(h),shouldEmitTerminalWake:h=>e.shouldEmitTerminalWake(h),resolvePlanApprovalMode:h=>e.resolvePlanApprovalMode(h),getPlanApprovalButtons:(h,w)=>l.getPlanApprovalButtons(h,w),getResumeButtons:(h,w)=>l.getResumeButtons(h,w),getQuestionButtons:(h,w,L)=>l.getQuestionButtons(h,w,L),extractLastOutputLine:h=>e.extractLastOutputLine(h),getOutputPreview:(h,w)=>e.getOutputPreview(h,w),originThreadLine:h=>e.originThreadLine(h),debounceWaitingEvent:(h,w)=>e.debounceWaitingEvent(h,w),isAlreadyMerged:h=>e.isAlreadyMerged(h),questionContextSummaryProvider:n.questionContextSummaryProvider??Du()}),x=new Vo({getPersistedSession:h=>i.getPersistedSession(h),resolveActiveSession:h=>d.resolveActive(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchNotification:(h,w)=>c.dispatch(h,w),buildRoutingProxy:h=>e.buildRoutingProxy(h)}),R=new jo({hydrateSpawnedSession:(h,w,L)=>{f.hydrateSpawnedSession(h,w,L)},markRunning:h=>{i.markRunning(h),e.onPersistedSessionChanged(i.getPersistedSession(h.id))},handleTerminal:async h=>e.onSessionTerminal(h),handleTurnEnd:(h,w)=>A.handleTurnEnd(h,w),formatLaunchWorkdirLabel:h=>e.formatLaunchWorkdirLabel(h),notifySession:(h,w,L)=>e.notifySession(h,w,L)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:a,interactions:l,notifications:c,worktrees:p,questions:k,lifecycle:A,restore:f,stateSync:u,references:d,worktreeStrategy:y,worktreeDecisions:x,runtimeBootstrap:R,worktreeMessages:m,maintenance:b}}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 f=this.registry.get(e.sessionIdOverride);if(f?.status==="starting"||f?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${f.status}.`);f&&this.registry.remove(f.id,"session-id-override-replacement"),this.clearWaitingTimestampsForSession(e.sessionIdOverride),this.lastTurnCompleteMarkers.delete(e.sessionIdOverride),this.lastTerminalWakeMarkers.delete(e.sessionIdOverride),this.maintenance.cancelRuntimeGc(e.sessionIdOverride)}let o=e.name||$a(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.checkRepoPolicyForLaunch(e.workdir,e.worktreeStrategy);if(!s.ok){let f=s;throw new Error(f.text)}e.repoIntegrationPolicy=s.resolution.policy,e.repoIntegrationPolicySource=s.resolution.source==="none"?void 0:s.resolution.source,e.repoProvider=s.resolution.provider;let a=this.restore.prepareSpawn(e,i),l=e.harness??"claude-code",d=this,u,c=l==="claude-code"&&!e.canUseTool?async(f,m)=>{if(!u)throw new Error("canUseTool called before session ID was set");return d.handleAskUserQuestion(u,m)}:e.canUseTool,p=new Tr({...e,workdir:a.actualWorkdir,systemPrompt:a.effectiveSystemPrompt,canUseTool:c},i);return u=p.id,this.registry.add(p),this.metrics.incrementLaunched(),this.runtimeBootstrap.initializeSession(p,a,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(Vu.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=(l,d)=>{if(d==="running"){a(),o();return}Vu.has(d)&&(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 Bn({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??D.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)}resolveRepoPolicy(e){let n=Pn(e);if(!n)return{source:"none",provider:"unsupported",prAvailable:!1};let r=this.store.getRepoPolicy(n.key);if(r)return{identity:n,policy:r.policy,source:"stored",provider:n.provider,prAvailable:n.provider==="github"&&Te(),record:r};let o=$l(n);if(o){let i=Gi(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:ji({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:ji({provider:n.provider})}}checkRepoPolicyForLaunch(e,n){let r=n??D.defaultWorktreeStrategy??"off",o=this.resolveRepoPolicy(e);return r==="off"?{ok:!0,resolution:o}:o.source==="none"?{ok:!0,resolution:o}:o.source==="unknown"&&o.identity?{ok:!1,text:Hi(o.identity,r,o.prAvailable)}:{ok:!0,resolution:o}}getRepoPolicyRecordForWorkdir(e){return this.resolveRepoPolicy(e).record}listRepoPolicies(){return this.store.listRepoPolicies()}cleanupRepoPolicies(){let e=[...this.store.cleanupRepoPolicies()],n=[];for(let r of this.store.listRepoPolicies()){let o=Pn(r.repoRoot);!o||o.key===r.key||n.push(r.key)}return e.push(...this.store.removeRepoPolicies(n)),e.sort((r,o)=>r.repoRoot.localeCompare(o.repoRoot)||r.key.localeCompare(o.key))}setRepoPolicy(e,n){let r=Pn(e);if(r)return this.store.setRepoPolicy(Gi(r,n,"stored"))}resetRepoPolicy(e){let n=Pn(e);return n?this.store.resetRepoPolicy(n.key):!1}requestRepoPolicyForLaunch(e){let n=e.worktreeStrategy??D.defaultWorktreeStrategy??"off",r=this.resolveRepoPolicy(e.workdir);if(!r.identity)return`Error: ${e.workdir} is not a git repository.`;let o=Hi(r.identity,n,r.prAvailable);if(!e.route?.provider||!e.route.target)return o;let i=`repo-policy:${r.identity.key}`,s=this.interactions.getRepoPolicyChoiceButtons({choiceId:i,route:e.route,repoRoot:r.identity.repoRoot,launchPrompt:e.prompt,launchWorkdir:e.workdir,launchName:e.name,launchModel:e.model,launchReasoningEffort:e.reasoningEffort,launchFastMode:e.fastMode,launchSystemPrompt:e.systemPrompt,launchAllowedTools:e.allowedTools,launchResumeSessionId:e.resumeSessionId,launchResumeWorktreeFrom:e.resumeWorktreeFrom,launchSessionIdOverride:e.sessionIdOverride,launchClearedPersistedCodexResume:e.clearedPersistedCodexResume,launchForkSession:e.forkSession,launchForceNewSession:e.forceNewSession,launchPermissionMode:e.permissionMode,launchPlanApproval:e.planApproval,launchHarness:e.harness,launchWorktreeStrategy:n,launchWorktreeBaseBranch:e.worktreeBaseBranch,launchWorktreePrTargetRepo:e.worktreePrTargetRepo,launchOriginAgentId:e.originAgentId,prAvailable:r.prAvailable}),a=vk(e,n);return this.notifications.dispatch(this.buildRoutingProxy({id:i,name:"repo-policy",route:e.route}),{label:"repo-policy-choice",idempotencyKey:`repo-policy-choice:${r.identity.key}:${n}:${a}`,userMessage:[o,"","After you choose a policy, OCA will continue this launch automatically."].join(`
266
+ `)}}buildDelegateNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,policyReason:s,allowedActions:a,originThreadLine:d}=e,l=i.commitMessages.slice(0,5).map(p=>`• ${p.hash} ${p.message} (${p.author})`),u=i.commits>5?`...and ${i.commits-5} more`:void 0,c=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(p=>p.hash).join(",")].join(":"),wakeMessage:vs({sessionName:n.name,sessionId:n.id,branchName:r,baseBranch:o,promptSnippet:c,commitLines:l,moreNote:u,originThreadLine:d,diffSummary:i,allowedActions:a,policyReason:s}),notifyUser:"never"}}};function Vu(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
267
+ `):yk(t);return n?o:o.length>e?Gu(t)?Wa(o,e):Na(o,e):o}function yk(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
268
+ `).trim();return n?Gu(t)?kk(n)??n:e.slice(-20).join(`
269
+ `):""}function Gu(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 kk(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(`
270
+ `)?n:void 0}xe();ke();ae();import{unlinkSync as Sk}from"fs";var Jo=class t{timers=new Map;disposed=!1;static MAX_DELAY_MS=2147483647;schedule(e,n,r){if(this.disposed||(this.cancel(e),!Number.isFinite(n)))return;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()}};ee();wn();ke();var ju=10080*60*1e3,vk=300*1e3,Hu="tmp-output:cleanup",wk=60*1e3;function Pk(t){return t instanceof Error?t.message:String(t)}var Yo=class{constructor(e){this.deps=e}deps;scheduler=new Jo;lastTmpOutputCleanupAttemptAt;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.runTmpOutputCleanup(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,"runtime-gc"),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=Xe(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+ju,()=>{let d=this.deps.store.getPersistedSession(n);d&&this.reconcileResolvedWorktreeRetention(d,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=Xe(e,{activeSession:!1,includePrSync:e.worktreeLifecycle?.state==="pr_open"||!!e.worktreePrUrl}),o=this.resolvedAtIso(e),i=o?new Date(o).getTime():0,s=this.legacyResolvedWorktreeState(e);if(!(!r.cleanupSafe&&!s||!o||!Number.isFinite(i)||n-i<ju))try{if(!e.worktreePath&&!ue(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let d=ue(e)?!1:pe(a,e.worktreePath);if(!ue(e)&&!d)return;for(let l of fe(e))this.deps.updatePersistedSession(l,{worktreePath:void 0,worktreeBranch:void 0,worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{...e.worktreeLifecycle??r.lifecycle,state:r.cleanupSafe?r.derivedState:s??r.derivedState,updatedAt:new Date(n).toISOString(),resolvedAt:e.worktreeLifecycle?.resolvedAt??o,resolutionSource:e.worktreeLifecycle?.resolutionSource??"maintenance",notes:r.reasons}})}catch(a){`${e.worktreePath}${Pk(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())||this.syncActionTokenExpiryDeadline()})}syncTmpOutputCleanupDeadline(e=Date.now()){this.cancel(Hu);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(Hu,this.getTmpOutputCleanupScheduleAt(n,e),()=>{let r=Date.now();this.runTmpOutputCleanup(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??$(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(E.sessionGcAgeMinutes??1440)*6e4}runTmpOutputCleanup(e){this.lastTmpOutputCleanupAttemptAt=e,this.deps.store.cleanupTmpOutputFiles(e)}getTmpOutputCleanupScheduleAt(e,n){if(e>n||this.lastTmpOutputCleanupAttemptAt==null)return e;let r=this.lastTmpOutputCleanupAttemptAt+wk;return r>n?r:e}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()+vk))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{Sk(e)}catch{}}resolvedAtIso(e){return e.worktreeLifecycle?.resolvedAt??e.worktreeMergedAt??e.worktreeDismissedAt??(e.completedAt?new Date(e.completedAt).toISOString():void 0)}isLegacyResolvedWorktree(e){return this.legacyResolvedWorktreeState(e)!=null}legacyResolvedWorktreeState(e){if(e.worktreeMerged===!0||e.worktreeDisposition==="merged"||e.worktreeState==="merged")return"merged";if(e.worktreeDisposition==="dismissed"||e.worktreeState==="dismissed")return"dismissed";if(e.worktreeDisposition==="no-change-cleaned")return"no_change"}};In();var zu=new Set(["completed","failed","killed"]),bk=new Set(["starting","running"]),Rk=5e3;function Ak(t,e){return Qu("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.prompt,workdir:t.workdir,name:t.name,model:t.model,reasoningEffort:t.reasoningEffort,fastMode:t.fastMode,systemPrompt:t.systemPrompt,allowedTools:t.allowedTools?[...t.allowedTools].sort():t.allowedTools,resumeSessionId:t.resumeSessionId,resumeWorktreeFrom:t.resumeWorktreeFrom,sessionIdOverride:t.sessionIdOverride,clearedPersistedCodexResume:t.clearedPersistedCodexResume,forkSession:t.forkSession,forceNewSession:t.forceNewSession,permissionMode:t.permissionMode,planApproval:t.planApproval,harness:t.harness,worktreeStrategy:t.worktreeStrategy,effectiveWorktreeStrategy:e,worktreeBaseBranch:t.worktreeBaseBranch,worktreePrTargetRepo:t.worktreePrTargetRepo,originAgentId:t.originAgentId})).digest("hex").slice(0,16)}function Ik(t){return Qu("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.launchPrompt,workdir:t.launchWorkdir,name:t.launchName,model:t.launchModel,reasoningEffort:t.launchReasoningEffort,fastMode:t.launchFastMode,systemPrompt:t.launchSystemPrompt,allowedTools:t.launchAllowedTools?[...t.launchAllowedTools].sort():t.launchAllowedTools,resumeSessionId:t.launchResumeSessionId,resumeWorktreeFrom:t.launchResumeWorktreeFrom,sessionIdOverride:t.launchSessionIdOverride,clearedPersistedCodexResume:t.launchClearedPersistedCodexResume,forkSession:t.launchForkSession,forceNewSession:t.launchForceNewSession,permissionMode:t.launchPermissionMode,planApproval:t.launchPlanApproval,harness:t.launchHarness,worktreeStrategy:t.launchWorktreeStrategy,worktreeBaseBranch:t.launchWorktreeBaseBranch,worktreePrTargetRepo:t.launchWorktreePrTargetRepo,originAgentId:t.launchOriginAgentId})).digest("hex").slice(0,16)}var Zo=class t{registry;sessions;maxSessions;maxPersistedSessions;lastWaitingEventTimestamps=new Map;lastTurnCompleteMarkers=new Map;lastTerminalWakeMarkers=new Map;mergeQueue=new Jt;pendingAskUserQuestions=new Map;store;metrics;wakeDispatcher;interactions;notifications;worktrees;questions;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.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 Ho,o=r.sessions,i=new Ao(n.store),s=new Io,a=new Do,d=new Oo(i.actionTokenStore,we),l=new fo(o,i),u=new mo({store:i,sessions:o,resolveSession:h=>l.resolveActive(h)}),c=new Bo(a,(h,w)=>u.applySessionPatch(h,w),{getPersistedSession:h=>i.getPersistedSession(h)}),p=new Fo,f=new po(h=>i.getPersistedSession(h)),m=new Qo,y=new vo({shouldRunWorktreeStrategy:h=>e.shouldRunWorktreeStrategy(h),isAlreadyMerged:h=>e.isAlreadyMerged(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),getWorktreeCompletionState:(h,w,N,Q)=>e.getWorktreeCompletionState(h,w,N,Q),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchSessionNotification:(h,w)=>e.dispatchSessionNotification(h,w),getOutputPreview:(h,w)=>e.getOutputPreview(h,w),originThreadLine:h=>e.originThreadLine(h),getWorktreeDecisionButtons:h=>e.getWorktreeDecisionButtons(h),getPolicyAwareWorktreeDecisionButtons:(h,w,N)=>e.getWorktreeDecisionButtons(h,w,N),makeOpenPrButton:h=>e.makeActionButton(h,"worktree-create-pr","Open PR"),isPrAvailable:h=>e.resolveRepoPolicy(h).prAvailable,hasOpenPrForBranch:(h,w,N)=>{let Q=Fe(h,w,N);return Q.exists&&Q.state==="open"},getPrStatusForUrl:(h,w,N)=>Ft(h,w,N),resolveRepoPolicy:h=>e.resolveRepoPolicy(h),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:m,enqueueMerge:(h,w,N)=>e.enqueueMerge(h,w,N),mergeBranch:Tr,spawnConflictResolver:async({session:h,worktreePath:w,prompt:N})=>e.spawn({prompt:N,workdir:w,name:`${h.name}-conflict-resolver`,harness:h.harnessName||le(),model:h.model,reasoningEffort:h.reasoningEffort,fastMode:h.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:h.id,route:h.route,originChannel:h.originChannel,originThreadId:h.originThreadId,originAgentId:h.originAgentId,originSessionKey:h.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(h,w)=>{let{makeAgentPrTool:N}=await Promise.resolve().then(()=>(Jr(),Gd));return{success:(await N().execute("auto-pr",{session:h.id,base_branch:w}))?.meta?.success===!0}}}),k=new qo(e.pendingAskUserQuestions,(h,w)=>e.dispatchSessionNotification(h,w),h=>{e.clearWaitingTimestampsForSession(h)},(h,w,N)=>d.getQuestionButtons(h,w,N)),S=new Ko(h=>e.buildRoutingProxy(h),(h,w)=>c.dispatch(h,w),(h,w)=>e.updatePersistedSession(h,w),(h,w)=>e.getPolicyAwareWorktreeDecisionButtons(h,{},void 0,w)),b=new Yo({store:i,sessions:o,reminders:S,removeRuntimeSession:(h,w)=>r.remove(h,w),persistSession:(h,w)=>e.persistSession(h,w),clearRuntimeSessionState:h=>{e.clearWaitingTimestampsForSession(h),e.lastTurnCompleteMarkers.delete(h),e.lastTerminalWakeMarkers.delete(h)},resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let A=new Go({persistSession:h=>e.persistSession(h),clearWaitingTimestamp:h=>{e.clearWaitingTimestampsForSession(h)},handleWorktreeStrategy:h=>e.handleWorktreeStrategy(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchSessionNotification:(h,w)=>e.dispatchSessionNotification(h,w),notifySession:(h,w,N,Q)=>e.notifySession(h,w,N,Q),clearRetryTimersForSession:h=>a.clearRetryTimersForSession(h),hasTurnCompleteWakeMarker:h=>e.lastTurnCompleteMarkers.has(h),shouldEmitTurnCompleteWake:h=>e.shouldEmitTurnCompleteWake(h),shouldEmitTerminalWake:h=>e.shouldEmitTerminalWake(h),resolvePlanApprovalMode:h=>e.resolvePlanApprovalMode(h),getPlanApprovalButtons:(h,w)=>d.getPlanApprovalButtons(h,w),getResumeButtons:(h,w)=>d.getResumeButtons(h,w),getQuestionButtons:(h,w,N)=>d.getQuestionButtons(h,w,N),extractLastOutputLine:h=>e.extractLastOutputLine(h),getOutputPreview:(h,w)=>e.getOutputPreview(h,w),originThreadLine:h=>e.originThreadLine(h),debounceWaitingEvent:(h,w)=>e.debounceWaitingEvent(h,w),isAlreadyMerged:h=>e.isAlreadyMerged(h),questionContextSummaryProvider:n.questionContextSummaryProvider??Nu()}),x=new jo({getPersistedSession:h=>i.getPersistedSession(h),resolveActiveSession:h=>l.resolveActive(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchNotification:(h,w)=>c.dispatch(h,w),buildRoutingProxy:h=>e.buildRoutingProxy(h)}),R=new zo({hydrateSpawnedSession:(h,w,N)=>{f.hydrateSpawnedSession(h,w,N)},markRunning:h=>{i.markRunning(h),e.onPersistedSessionChanged(i.getPersistedSession(h.id))},handleTerminal:async h=>e.onSessionTerminal(h),handleTurnEnd:(h,w)=>A.handleTurnEnd(h,w),formatLaunchWorkdirLabel:h=>e.formatLaunchWorkdirLabel(h),notifySession:(h,w,N,Q)=>e.notifySession(h,w,N,Q)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:a,interactions:d,notifications:c,worktrees:p,questions:k,lifecycle:A,restore:f,stateSync:u,references:l,worktreeStrategy:y,worktreeDecisions:x,runtimeBootstrap:R,worktreeMessages:m,maintenance:b}}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 f=this.registry.get(e.sessionIdOverride);if(f?.status==="starting"||f?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${f.status}.`);f&&this.registry.remove(f.id,"session-id-override-replacement"),this.clearWaitingTimestampsForSession(e.sessionIdOverride),this.lastTurnCompleteMarkers.delete(e.sessionIdOverride),this.lastTerminalWakeMarkers.delete(e.sessionIdOverride),this.maintenance.cancelRuntimeGc(e.sessionIdOverride)}let o=e.name||Da(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.checkRepoPolicyForLaunch(e.workdir,e.worktreeStrategy);if(!s.ok){let f=s;throw new Error(f.text)}e.repoIntegrationPolicy=s.resolution.policy,e.repoIntegrationPolicySource=s.resolution.source==="none"?void 0:s.resolution.source,e.repoProvider=s.resolution.provider;let a=this.restore.prepareSpawn(e,i),d=e.harness??"claude-code",l=this,u,c=d==="claude-code"&&!e.canUseTool?async(f,m)=>{if(!u)throw new Error("canUseTool called before session ID was set");return l.handleAskUserQuestion(u,m)}:e.canUseTool,p=new Mr({...e,workdir:a.actualWorkdir,systemPrompt:a.effectiveSystemPrompt,canUseTool:c},i);return u=p.id,this.registry.add(p),this.metrics.incrementLaunched(),this.runtimeBootstrap.initializeSession(p,a,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(zu.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}zu.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 qn({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)}resolveRepoPolicy(e){let n=Rn(e);if(!n)return{source:"none",provider:"unsupported",prAvailable:!1};let r=this.store.getRepoPolicy(n.key);if(r)return{identity:n,policy:r.policy,source:"stored",provider:n.provider,prAvailable:n.provider==="github"&&we(),record:r};let o=Od(n);if(o){let i=Hi(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:zi({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:zi({provider:n.provider})}}checkRepoPolicyForLaunch(e,n){let r=n??E.defaultWorktreeStrategy??"off",o=this.resolveRepoPolicy(e);return r==="off"?{ok:!0,resolution:o}:o.source==="none"?{ok:!0,resolution:o}:o.source==="unknown"&&o.identity?{ok:!1,text:Qi(o.identity,r,o.prAvailable)}:{ok:!0,resolution:o}}getRepoPolicyRecordForWorkdir(e){return this.resolveRepoPolicy(e).record}listRepoPolicies(){return this.store.listRepoPolicies()}cleanupRepoPolicies(){let e=[...this.store.cleanupRepoPolicies()],n=[];for(let r of this.store.listRepoPolicies()){let o=Rn(r.repoRoot);!o||o.key===r.key||n.push(r.key)}return e.push(...this.store.removeRepoPolicies(n)),e.sort((r,o)=>r.repoRoot.localeCompare(o.repoRoot)||r.key.localeCompare(o.key))}setRepoPolicy(e,n){let r=Rn(e);if(r)return this.store.setRepoPolicy(Hi(r,n,"stored"))}resetRepoPolicy(e){let n=Rn(e);return n?this.store.resetRepoPolicy(n.key):!1}requestRepoPolicyForLaunch(e){let n=e.worktreeStrategy??E.defaultWorktreeStrategy??"off",r=this.resolveRepoPolicy(e.workdir);if(!r.identity)return`Error: ${e.workdir} is not a git repository.`;let o=Qi(r.identity,n,r.prAvailable);if(!e.route?.provider||!e.route.target)return o;let i=`repo-policy:${r.identity.key}`,s=this.interactions.getRepoPolicyChoiceButtons({choiceId:i,route:e.route,repoRoot:r.identity.repoRoot,launchPrompt:e.prompt,launchWorkdir:e.workdir,launchName:e.name,launchModel:e.model,launchReasoningEffort:e.reasoningEffort,launchFastMode:e.fastMode,launchSystemPrompt:e.systemPrompt,launchAllowedTools:e.allowedTools,launchResumeSessionId:e.resumeSessionId,launchResumeWorktreeFrom:e.resumeWorktreeFrom,launchSessionIdOverride:e.sessionIdOverride,launchClearedPersistedCodexResume:e.clearedPersistedCodexResume,launchForkSession:e.forkSession,launchForceNewSession:e.forceNewSession,launchPermissionMode:e.permissionMode,launchPlanApproval:e.planApproval,launchHarness:e.harness,launchWorktreeStrategy:n,launchWorktreeBaseBranch:e.worktreeBaseBranch,launchWorktreePrTargetRepo:e.worktreePrTargetRepo,launchOriginAgentId:e.originAgentId,prAvailable:r.prAvailable}),a=Ak(e,n);return this.notifications.dispatch(this.buildRoutingProxy({id:i,name:"repo-policy",route:e.route}),{label:"repo-policy-choice",idempotencyKey:`repo-policy-choice:${r.identity.key}:${n}:${a}`,userMessage:[o,"","After you choose a policy, OCA will continue this launch automatically."].join(`
271
271
  `),notifyUser:"always",requireDirectUserNotification:!0,buttons:s,wakeMessageOnNotifySuccess:["Repo policy choice buttons delivered to the user.",`Repo: ${r.identity.repoRoot}`,"Wait for their policy choice; do not set the policy or relaunch separately."].join(`
272
- `),wakeMessageOnNotifyFailed:o}),[`Repo policy choice prompt sent for ${r.identity.repoRoot}.`,r.prAvailable?"Wait for the user's Require PR, Merge or PR, No PR, or Manual response.":"Wait for the user's No PR or Manual response.","Do not send a separate plain-text policy question."].join(" ")}launchAfterRepoPolicyChoice(e){let n=e.route;if(!n?.provider||!n.target)throw new Error("missing route metadata for stored launch");let r=e.harness??de(),o=e.permissionMode??D.permissionMode,i=e.planApproval??D.planApproval,s=this.spawn({prompt:e.prompt,workdir:e.workdir,sessionIdOverride:e.sessionIdOverride,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,allowedTools:e.allowedTools,resumeSessionId:e.resumeSessionId,resumeWorktreeFrom:e.resumeWorktreeFrom,forkSession:e.resumeSessionId?e.forkSession:!1,multiTurn:!0,permissionMode:o,planApproval:i,codexApprovalPolicy:r==="codex"?"never":void 0,originChannel:this.originChannelFromRoute(n),originThreadId:n.threadId,originAgentId:e.originAgentId,originSessionKey:n.sessionKey,route:n,harness:r,worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo});return{session:s,text:this.formatLaunchResult({prompt:e.prompt,workdir:e.workdir,harness:r,permissionMode:o,planApproval:i,forceNewSession:e.forceNewSession,resumeSessionId:e.resumeSessionId,forkSession:e.forkSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},s)}}continueLaunchAfterManualRepoPolicy(e,n){let r=this.resolveRepoPolicy(e);if(!r.identity)return{kind:"none"};let o=this.interactions.listActiveActionTokens("repo-policy-set").filter(u=>u.repoPolicyWorkdir===r.identity?.repoRoot),i=()=>{for(let u of new Set(o.map(c=>c.sessionId)))this.clearRepoPolicyChoiceTokens(u)},s=o.filter(u=>u.repoPolicy===n&&!!u.launchPrompt&&!!u.launchWorkdir&&!!u.route?.provider&&!!u.route?.target);if(s.length===0)return i(),{kind:"none"};let a=new Map;for(let u of s){let c=wk(u);a.has(c)||a.set(c,u)}if(a.size>1)return i(),{kind:"ambiguous",count:a.size};let l=[...a.values()][0];if(!l.launchPrompt||!l.launchWorkdir)return{kind:"none"};let d=this.launchAfterRepoPolicyChoice({route:l.route,prompt:l.launchPrompt,workdir:l.launchWorkdir,name:l.launchName,model:l.launchModel,reasoningEffort:l.launchReasoningEffort,fastMode:l.launchFastMode,systemPrompt:l.launchSystemPrompt,allowedTools:l.launchAllowedTools,resumeSessionId:l.launchResumeSessionId,resumeWorktreeFrom:l.launchResumeWorktreeFrom,sessionIdOverride:l.launchSessionIdOverride,clearedPersistedCodexResume:l.launchClearedPersistedCodexResume,forkSession:l.launchForkSession,forceNewSession:l.launchForceNewSession,permissionMode:l.launchPermissionMode,planApproval:l.launchPlanApproval,harness:l.launchHarness,worktreeStrategy:l.launchWorktreeStrategy,worktreeBaseBranch:l.launchWorktreeBaseBranch,worktreePrTargetRepo:l.launchWorktreePrTargetRepo,originAgentId:l.launchOriginAgentId});return this.consumeActionToken(l.id),this.clearRepoPolicyChoiceTokens(l.sessionId),{kind:"launched",...d}}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)}clearRepoPolicyChoiceTokens(e){this.interactions.clearRepoPolicyChoiceTokens(e)}clearPlanDecisionTokens(e,n){this.interactions.clearPlanDecisionTokens(e,n)}isCurrentPendingPlanDecision(e,n){let r=this.resolve(e)??this.getPersistedSession(e);return Ln(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:En({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:zt(e,n,!0),wakeMessageOnNotifyFailed:qo({session:e,planDecisionVersion:n})})}getWorktreeDecisionButtons(e,n={},r={merge:!0,pr:!0}){let o=this.resolve(e)??this.getPersistedSession(e);if(!(!o||o.worktreeStrategy==="delegate"&&n.allowDelegate!==!0))return this.interactions.getWorktreeDecisionButtons(e,o,r)}getPolicyAwareWorktreeDecisionButtons(e,n={},r,o){let i=r??this.resolve(e),s=o??this.getPersistedSession(e),a=this.resolveWorktreeRepoDir(i?.originalWorkdir??s?.workdir,i?.worktreePath??s?.worktreePath),l=a?this.resolveRepoPolicy(a):void 0,d=i?.repoIntegrationPolicy??s?.repoIntegrationPolicy,u=d??l?.policy,c=l?.prAvailable??!!(d&&d!=="never-pr"&&d!=="manual"),p=u?Vi({policy:u,prAvailable:c}):{merge:!0,pr:!0};return this.getWorktreeDecisionButtons(e,n,p)}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=bs(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 l=U(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 d=a.actionablePlanDecisionVersion??a.planDecisionVersion;if(Nn(a,d))return[`An actionable plan review prompt already exists for session ${a.name} [${l}].`,"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} [${l}].`,"Wait for delivery to finish before retrying."].join(" ");let u=this.interactions.getPlanApprovalButtons(l,{...a,planDecisionVersion:d}),c=[`📋 [${a.name}] Plan v${d??"?"} needs your decision:`,"","Why this was escalated:","",o,"","Choose Approve, Revise, or Reject below."].join(`
273
- `);return this.notifications.dispatch(this.buildRoutingProxy({id:l,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:${l}:v${d??"unknown"}:canonical`,userMessage:c,notifyUser:"always",buttons:u,hooks:{onNotifyStarted:()=>{this.updatePersistedSession(l,{approvalPromptRequiredVersion:d,approvalPromptStatus:"sending",approvalPromptVersion:d,approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.updatePersistedSession(l,{canonicalPlanPromptVersion:d,approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.updatePersistedSession(l,{approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>this.isCurrentPendingPlanDecision(l,d),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(this.buildRoutingProxy({id:l,name:a.name,sessionId:s?.sessionId,harnessSessionId:i?.harnessSessionId??s?.harnessSessionId,backendRef:i?.backendRef??s?.backendRef,route:i?.route??s?.route}),d,o),wakeMessageOnNotifySuccess:zt({id:l,name:a.name},d)}),[`Canonical plan approval prompt sent for session ${a.name} [${l}].`,"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 d=U(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??_e(p),m=Le(p,c,f);if(!m)return`Error: Could not compute worktree diff summary for session "${e}".`;let y=this.getPolicyAwareWorktreeDecisionButtons(d,{allowDelegate:!0},o,i);if(!y||y.length===0)return`Error: Could not create worktree decision buttons for session "${e}".`;let k=r.split(/\r?\n/).map(S=>S.replace(/^[-*]\s+/,"").trim()).filter(S=>S.length>0);return this.notifications.dispatch(this.buildRoutingProxy({id:d,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:d,name:s.name,worktreePrTargetRepo:o?.worktreePrTargetRepo??i?.worktreePrTargetRepo},branchName:c,baseBranch:f,diffSummary:m,summaryLines:k,buttons:y})),[`Canonical worktree decision prompt sent for session ${s.name} [${d}].`,"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:U(e)??E(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||!lo(e,n))||!n?e:wr(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.clearWaitingTimestampsForSession(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)",l=r?.worktreeBaseBranch??o?.worktreeBaseBranch,d=r?.worktreePrTargetRepo??o?.worktreePrTargetRepo,u=r?.worktreePushRemote??o?.worktreePushRemote;this.updatePersistedSession(n,Nr({worktreeBaseBranch:l,worktreePrTargetRepo:d,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(`
274
- `),buttons:this.getPolicyAwareWorktreeDecisionButtons(n,{allowDelegate:!0},r,o)})}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(d=>!!d).join(`
275
- `),l=d=>gs({sessionId:o,sessionName:e.sessionName,taskName:e.name,summary:n,originThreadLine:en(i),canonicalStatusDelivered:d});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?l(!0):void 0,wakeMessageOnNotifyFailed:s?l(!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:de(),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,n){let r=Date.now(),o=n?`${e}:${n}`:e,i=this.lastWaitingEventTimestamps.get(o);return i&&r-i<Sk?!1:(this.lastWaitingEventTimestamps.set(o,r),!0)}clearWaitingTimestampsForSession(e){this.lastWaitingEventTimestamps.delete(e);let n=`${e}:`;for(let r of this.lastWaitingEventTimestamps.keys())r.startsWith(n)&&this.lastWaitingEventTimestamps.delete(r)}originThreadLine(e){return en(e)}extractLastOutputLine(e){return e.getOutput(3).filter(o=>o.trim()).pop()?.trim()||void 0}getOutputPreview(e,n=1e3){return Fu(e,n)}resolvePlanApprovalMode(e){return e.planApproval??D.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())kk.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,r={}){return this.questions.resolveAskUserQuestion(e,n,r)}async resolvePendingInputOption(e,n,r={}){let o=this.sessions.get(e);return o?.canSubmitPendingInputOption?.()?await o.submitPendingInputOption(n,r)?(this.clearWaitingTimestampsForSession(e),!0):!1:this.questions.resolveAskUserQuestion(e,n,r)}dispose(){this.disposeMaintenance(),this.questions.dispose(),this.notifications.dispose()}};F();ae();import{definePluginEntry as ju}from"openclaw/plugin-sdk/plugin-entry";function Ik(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(l=>l.worktreePath).filter(l=>typeof l=="string"&&l.length>0)),i=new Set,s=process.env.OPENCLAW_WORKTREE_DIR??D.worktreeDir;if(s)i.add(s);else for(let l of t.listPersistedSessions())if(l.workdir)try{let d=Ak("git",["rev-parse","--show-toplevel"],{cwd:l.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();d&&i.add(Hu(d,".worktrees"))}catch{}if(i.size===0)return;let a=0;for(let l of i)try{let d=Pk(l);for(let u of d){if(!u.startsWith("openclaw-worktree-"))continue;let c=Hu(l,u);try{let p=bk(c);if(!p.isDirectory()||p.mtimeMs>r||o.has(c))continue;Rk(c,{recursive:!0,force:!0}),a++}catch(p){`${c}${p instanceof Error?p.message:String(p)}`}}}catch{}a>0&&`${a}${e}`}function xk(t){let e=null,n=null,r=!1,o=!1,i=t.registerTool;Mt(t.runtime);let s=c=>{if(r){c&&!o&&(Mt(t.runtime,c.config),o=!0);return}let p=t.pluginConfig??{};Vs(p),c?(Mt(t.runtime,c.config),o=!0):(Mt(t.runtime),o=!1),e=new Jo(D.maxSessions,D.maxPersistedSessions,{worktreeSummaryProvider:Zd()}),n=new ao(e),ei(e),ti(n),n.start(),Ik(e),e.bootstrapMaintenanceSchedules(),r=!0},a=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=!1,o=!1,Mt(void 0),ti(null),ei(null)},l=(c,p)=>{i(f=>(s(),c(f)),p)},d={...t,registerCommand(c){t.registerCommand({...c,handler:p=>(s(),c.handler(p))})}},u=c=>{let p=ad(c);t.registerInteractiveHandler({...p,handler:async f=>(s(),p.handler(f))})};l(c=>qa(c),{optional:!1,name:"agent_launch"}),l(c=>hl(c),{optional:!1,name:"agent_sessions"}),l(c=>yl(c),{optional:!1,name:"agent_kill"}),l(c=>Er(c),{optional:!1,name:"agent_output"}),l(c=>bl(c),{optional:!1,name:"agent_respond"}),l(c=>Rl(c),{optional:!1,name:"agent_request_plan_approval"}),l(c=>Al(c),{optional:!1,name:"agent_request_worktree_decision"}),l(c=>Tl(c),{optional:!1,name:"agent_send_plan_offer"}),l(c=>Cl(c),{optional:!1,name:"agent_stats"}),l(c=>Dl(c),{optional:!1,name:"agent_repo_policy"}),l(c=>Ur(c),{optional:!1,name:"agent_merge"}),l(c=>Cn(c),{optional:!1,name:"agent_pr"}),l(c=>Ul(c),{optional:!1,name:"agent_worktree_cleanup"}),l(c=>Vl(c),{optional:!1,name:"agent_worktree_status"}),l(c=>Gl(c),{optional:!1,name:"goal_launch"}),l(c=>Hl(c),{optional:!1,name:"goal_status"}),l(c=>zl(c),{optional:!1,name:"goal_stop"}),l(c=>Ql(c),{optional:!1,name:"goal_edit"}),u("telegram"),u("discord"),dd(d),ud(d),cd(d),pd(d),md(d),fd(d),gd(d),yd(d),kd(d),Sd(d),wd(d),t.registerService({id:"openclaw-code-agent",start:s,stop:a})}var hT=ju({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:xk});export{hT as default,xk as register};
272
+ `),wakeMessageOnNotifyFailed:o}),[`Repo policy choice prompt sent for ${r.identity.repoRoot}.`,r.prAvailable?"Wait for the user's Require PR, Merge or PR, No PR, or Manual response.":"Wait for the user's No PR or Manual response.","Do not send a separate plain-text policy question."].join(" ")}launchAfterRepoPolicyChoice(e){let n=e.route;if(!n?.provider||!n.target)throw new Error("missing route metadata for stored launch");let r=e.harness??le(),o=e.permissionMode??E.permissionMode,i=e.planApproval??E.planApproval,s=this.spawn({prompt:e.prompt,workdir:e.workdir,sessionIdOverride:e.sessionIdOverride,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,allowedTools:e.allowedTools,resumeSessionId:e.resumeSessionId,resumeWorktreeFrom:e.resumeWorktreeFrom,forkSession:e.resumeSessionId?e.forkSession:!1,multiTurn:!0,permissionMode:o,planApproval:i,codexApprovalPolicy:r==="codex"?"never":void 0,originChannel:this.originChannelFromRoute(n),originThreadId:n.threadId,originAgentId:e.originAgentId,originSessionKey:n.sessionKey,route:n,harness:r,worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo});return{session:s,text:this.formatLaunchResult({prompt:e.prompt,workdir:e.workdir,harness:r,permissionMode:o,planApproval:i,forceNewSession:e.forceNewSession,resumeSessionId:e.resumeSessionId,forkSession:e.forkSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},s)}}continueLaunchAfterManualRepoPolicy(e,n){let r=this.resolveRepoPolicy(e);if(!r.identity)return{kind:"none"};let o=this.interactions.listActiveActionTokens("repo-policy-set").filter(u=>u.repoPolicyWorkdir===r.identity?.repoRoot),i=()=>{for(let u of new Set(o.map(c=>c.sessionId)))this.clearRepoPolicyChoiceTokens(u)},s=o.filter(u=>u.repoPolicy===n&&!!u.launchPrompt&&!!u.launchWorkdir&&!!u.route?.provider&&!!u.route?.target);if(s.length===0)return i(),{kind:"none"};let a=new Map;for(let u of s){let c=Ik(u);a.has(c)||a.set(c,u)}if(a.size>1)return i(),{kind:"ambiguous",count:a.size};let d=[...a.values()][0];if(!d.launchPrompt||!d.launchWorkdir)return{kind:"none"};let l=this.launchAfterRepoPolicyChoice({route:d.route,prompt:d.launchPrompt,workdir:d.launchWorkdir,name:d.launchName,model:d.launchModel,reasoningEffort:d.launchReasoningEffort,fastMode:d.launchFastMode,systemPrompt:d.launchSystemPrompt,allowedTools:d.launchAllowedTools,resumeSessionId:d.launchResumeSessionId,resumeWorktreeFrom:d.launchResumeWorktreeFrom,sessionIdOverride:d.launchSessionIdOverride,clearedPersistedCodexResume:d.launchClearedPersistedCodexResume,forkSession:d.launchForkSession,forceNewSession:d.launchForceNewSession,permissionMode:d.launchPermissionMode,planApproval:d.launchPlanApproval,harness:d.launchHarness,worktreeStrategy:d.launchWorktreeStrategy,worktreeBaseBranch:d.launchWorktreeBaseBranch,worktreePrTargetRepo:d.launchWorktreePrTargetRepo,originAgentId:d.launchOriginAgentId});return this.consumeActionToken(d.id),this.clearRepoPolicyChoiceTokens(d.sessionId),{kind:"launched",...l}}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)}clearRepoPolicyChoiceTokens(e){this.interactions.clearRepoPolicyChoiceTokens(e)}clearPlanDecisionTokens(e,n){this.interactions.clearPlanDecisionTokens(e,n)}isCurrentPendingPlanDecision(e,n){let r=this.resolve(e)??this.getPersistedSession(e);return Fn(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:On({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:Yt(e,n,!0),wakeMessageOnNotifyFailed:Uo({session:e,planDecisionVersion:n})})}getWorktreeDecisionButtons(e,n={},r={merge:!0,pr:!0}){let o=this.resolve(e)??this.getPersistedSession(e);if(!(!o||o.worktreeStrategy==="delegate"&&n.allowDelegate!==!0))return this.interactions.getWorktreeDecisionButtons(e,o,r)}getPolicyAwareWorktreeDecisionButtons(e,n={},r,o){let i=r??this.resolve(e),s=o??this.getPersistedSession(e),a=this.resolveWorktreeRepoDir(i?.originalWorkdir??s?.workdir,i?.worktreePath??s?.worktreePath),d=a?this.resolveRepoPolicy(a):void 0,l=i?.repoIntegrationPolicy??s?.repoIntegrationPolicy,u=l??d?.policy,c=d?.prAvailable??!!(l&&l!=="never-pr"&&l!=="manual"),p=u?ji({policy:u,prAvailable:c}):{merge:!0,pr:!0};return this.getWorktreeDecisionButtons(e,n,p)}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=As(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=V(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(Bn(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(`
273
+ `);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:Yt({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=V(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??$e(p),m=Be(p,c,f);if(!m)return`Error: Could not compute worktree diff summary for session "${e}".`;let y=this.getPolicyAwareWorktreeDecisionButtons(l,{allowDelegate:!0},o,i);if(!y||y.length===0)return`Error: Could not create worktree decision buttons for session "${e}".`;let k=r.split(/\r?\n/).map(S=>S.replace(/^[-*]\s+/,"").trim()).filter(S=>S.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:m,summaryLines:k,buttons:y})),[`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:V(e)??$(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||!co(e,n))||!n?e:br(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.clearWaitingTimestampsForSession(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,Br({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(`
274
+ `),buttons:this.getPolicyAwareWorktreeDecisionButtons(n,{allowDelegate:!0},r,o)})}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",o){this.dispatchSessionNotification(e,{label:r,idempotencyKey:r==="agent-respond"?void 0:o??`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(`
275
+ `),d=l=>ys({sessionId:o,sessionName:e.sessionName,taskName:e.name,summary:n,originThreadLine:rn(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:le(),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,n){let r=Date.now(),o=n?`${e}:${n}`:e,i=this.lastWaitingEventTimestamps.get(o);return i&&r-i<Rk?!1:(this.lastWaitingEventTimestamps.set(o,r),!0)}clearWaitingTimestampsForSession(e){this.lastWaitingEventTimestamps.delete(e);let n=`${e}:`;for(let r of this.lastWaitingEventTimestamps.keys())r.startsWith(n)&&this.lastWaitingEventTimestamps.delete(r)}originThreadLine(e){return rn(e)}extractLastOutputLine(e){return e.getOutput(3).filter(o=>o.trim()).pop()?.trim()||void 0}getOutputPreview(e,n=1e3){return Vu(e,n)}resolvePlanApprovalMode(e){return e.planApproval??E.planApproval??"delegate"}shouldEmitTurnCompleteWake(e){let n=`${e.startedAt??0}|${e.result?.session_id??""}|${e.result?.num_turns??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.startedAt??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())bk.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,r={}){return this.questions.resolveAskUserQuestion(e,n,r)}async resolvePendingInputOption(e,n,r={}){let o=this.sessions.get(e);return o?.canSubmitPendingInputOption?.()?await o.submitPendingInputOption(n,r)?(this.clearWaitingTimestampsForSession(e),!0):!1:this.questions.resolveAskUserQuestion(e,n,r)}dispose(){this.disposeMaintenance(),this.questions.dispose(),this.notifications.dispose()}};K();ae();import{definePluginEntry as Ju}from"openclaw/plugin-sdk/plugin-entry";function _k(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=Mk("git",["rev-parse","--show-toplevel"],{cwd:d.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();l&&i.add(Yu(l,".worktrees"))}catch{}if(i.size===0)return;let a=0;for(let d of i)try{let l=xk(d);for(let u of l){if(!u.startsWith("openclaw-worktree-"))continue;let c=Yu(d,u);try{let p=Tk(c);if(!p.isDirectory()||p.mtimeMs>r||o.has(c))continue;Ck(c,{recursive:!0,force:!0}),a++}catch(p){`${c}${p instanceof Error?p.message:String(p)}`}}}catch{}a>0&&`${a}${e}`}function $k(t){let e=null,n=null,r=!1,o=!1,i=t.registerTool;Et(t.runtime);let s=c=>{if(r){c&&!o&&(Et(t.runtime,c.config),o=!0);return}let p=t.pluginConfig??{};js(p),c?(Et(t.runtime,c.config),o=!0):(Et(t.runtime),o=!1),e=new Zo(E.maxSessions,E.maxPersistedSessions,{worktreeSummaryProvider:tu()}),n=new uo(e),ni(e),ri(n),n.start(),_k(e),e.bootstrapMaintenanceSchedules(),r=!0},a=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=!1,o=!1,Et(void 0),ri(null),ni(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=ul(c);t.registerInteractiveHandler({...p,handler:async f=>(s(),p.handler(f))})};d(c=>Ua(c),{optional:!1,name:"agent_launch"}),d(c=>Sd(c),{optional:!1,name:"agent_sessions"}),d(c=>vd(c),{optional:!1,name:"agent_kill"}),d(c=>Or(c),{optional:!1,name:"agent_output"}),d(c=>Id(c),{optional:!1,name:"agent_respond"}),d(c=>xd(c),{optional:!1,name:"agent_request_plan_approval"}),d(c=>Td(c),{optional:!1,name:"agent_request_worktree_decision"}),d(c=>_d(c),{optional:!1,name:"agent_send_plan_offer"}),d(c=>$d(c),{optional:!1,name:"agent_stats"}),d(c=>Nd(c),{optional:!1,name:"agent_repo_policy"}),d(c=>Gr(c),{optional:!1,name:"agent_merge"}),d(c=>_n(c),{optional:!1,name:"agent_pr"}),d(c=>jd(c),{optional:!1,name:"agent_worktree_cleanup"}),d(c=>Hd(c),{optional:!1,name:"agent_worktree_status"}),d(c=>zd(c),{optional:!1,name:"goal_launch"}),d(c=>Jd(c),{optional:!1,name:"goal_status"}),d(c=>Yd(c),{optional:!1,name:"goal_stop"}),d(c=>Zd(c),{optional:!1,name:"goal_edit"}),u("telegram"),u("discord"),pl(l),ml(l),fl(l),gl(l),hl(l),yl(l),kl(l),vl(l),wl(l),Pl(l),Rl(l),t.registerService({id:"openclaw-code-agent",start:s,stop:a})}var wT=Ju({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:$k});export{wT as default,$k as register};