openclaw-code-agent 4.6.0 → 4.7.0

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,45 +1,47 @@
1
- var mc=Object.defineProperty;var z=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var fc=(t,e)=>{for(var n in e)mc(t,n,{get:e[n],enumerable:!0})};function sn(t,e){return e?{...e,...t}:t}function gc(t){return{...t,[ii]:!0}}function hc(t){return{const:t,type:typeof t}}var ii,g,re=z(()=>{ii=Symbol("optionalSchema");g={Object(t,e){let n=Object.entries(t).filter(([,o])=>!o[ii]).map(([o])=>o),r=Object.fromEntries(Object.entries(t).map(([o,i])=>{let{[ii]:s,...a}=i;return[o,a]}));return{...e,type:"object",...n.length>0?{required:n}:{},properties:r}},String(t){return sn({type:"string"},t)},Number(t){return sn({type:"number"},t)},Boolean(t){return sn({type:"boolean"},t)},Array(t,e){return sn({type:"array",items:t},e)},Literal:hc,Union(t,e){return sn({anyOf:t},e)},Optional:gc}});function si(t){v=t}function ai(t){Q=t}var v,Q,U=z(()=>{v=null,Q=null});function Qs(t){let e=t.chatId.trim(),n=t.topicId.trim();return!/^-?\d+$/.test(e)||!/^\d+$/.test(n)?null:`${e}:topic:${n}`}function wc(t){let e=t.conversationId.trim(),n=e.match(/^(-?\d+):topic:(\d+)$/i);if(n?.[1]&&n[2]){let i=Qs({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=Qs({chatId:r,topicId:e});return o?{chatId:r,topicId:e,canonicalConversationId:o}:null}function Pc(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 bc(t,e){if(!/^\d+$/.test(t))return t;let n=Pc(e);return n?`${n}:${t}`:`channel:${t}`}function Rc(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 Ac(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 Ic(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||!vc.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 xc(t,e=wc){try{return e({conversationId:t})}catch{return null}}function di(t){return{provider:"system",target:"system",sessionKey:t?.trim()||void 0}}function li(t,e){return{...t,threadId:e??t.threadId}}function Cc(t,e,n){return t==="telegram"&&n?.provider==="telegram"&&!!n.target&&e!==n.target}function Mc(t){let e=t?.trim();if(!e)return;let n=Ic(e);if(!n)return;let{provider:r,kind:o,rawId:i}=n,s=Ac(i),a=null;if(r==="telegram")try{a=Tc.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 ui(t){let e=t?.match(/:topic:(\d+)$/i);return e?parseInt(e[1],10):void 0}function Js(t){return!!(t?.provider&&t.target&&t.provider!=="system"&&t.target!=="system")}function an(t,e,n){let r=Mc(n),o=e!=null?String(e):void 0,i=t?.trim();if(!i||i.toLowerCase()==="unknown")return r?li(r,o):di(n);let s=i.split("|").map(m=>m.trim());if(s.length<2)return r?li(r,o):di(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?li(r,o):di(n);let f=p==="discord"?bc(u,n):u;return Cc(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 st(t){return an(Rc(t.route)??t.originChannel,t.route?.threadId??t.originThreadId,t.route?.sessionKey??t.originSessionKey)??t.route}function Ne(t){let e=st(t);return Js(e)?e:void 0}function _c(t){return Object.fromEntries(Object.entries(t).filter(e=>!!e[1]))}function dn(t){let e=st(t);if(!Js(e))return"";let n=_c({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 vc,Tc,xe=z(()=>{vc=new Set(["telegram","discord","slack","system","mattermost","feishu","line","whatsapp","signal","matrix","googlechat","bluebubbles","imessage","msteams"]);Tc={safeParseTelegramTopicConversation:xc}});import{readFileSync as $c}from"fs";import{homedir as Ec}from"os";import{join as Dc}from"path";function Zs(){if(ln!==void 0)return ln;try{let t=$c(Dc(Ec(),".claude.json"),"utf-8");ln=JSON.parse(t).mcpServers??{}}catch{ln={}}return ln}function Xs(t){let e=t.defaultHarness??Ys,n={};for(let[r,o]of Object.entries(un)){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});W={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 ue(){return W.defaultHarness??Ys}function mi(t){let e=un[t],n=W.harnesses[t];return{...e,...n,allowedModels:n?.allowedModels??e?.allowedModels}}function bt(t){return mi(t).defaultModel}function Vn(t){return W.harnesses[t]?.allowedModels??W.allowedModels}function Je(t){return mi(t).reasoningEffort}function Rt(t){return t==="codex"?mi(t).fastMode:void 0}function Se(t){return t==null?void 0:String(t).trim()||void 0}function fi(t){return{channel:Se(t?.deliveryContext?.channel),to:Se(t?.deliveryContext?.to),accountId:Se(t?.deliveryContext?.accountId),threadId:Se(t?.deliveryContext?.threadId)}}function ea(t,e,n){if(!(!t||!e))return n?`${t}|${n}|${e}`:`${t}|${e}`}function ci(t){return Se(t?.requesterSenderId??t?.senderId)}function pi(t){return(Se(t.deliveryContext?.channel)??t.messageChannel??t.channel)?.toLowerCase()!=="telegram"?!1:!!(ui(t.sessionKey)||Se(t.messageThreadId)||Se(t.deliveryContext?.threadId))}function jn(t){let e=fi(t),n=ea(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=ci(t);if(r.length===1&&i&&!pi(t))return`${r[0]}|${i}`}if(t.workspaceDir){let r=at(t.workspaceDir);if(r)return r}if(t.messageChannel&&t.messageChannel.includes("|"))return t.messageChannel}function cn(t,e){if(e&&String(e).includes("|"))return String(e);let n=fi(t),r=ea(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=ci(t);if(l&&!pi(t))return`${a}|${l}`}let o=Se(t?.channel),i=Se(t?.chatId);if(o&&i)return`${o}|${i}`;let s=ci(t);return o&&s&&!pi(t)?`${o}|${s}`:t?.id&&/^-?\d+$/.test(String(t.id))?`telegram|${t.id}`:W.fallbackChannel??"unknown"}function gi(t){return fi(t).threadId??t?.messageThreadId??void 0}function At(t,e,n){return an(cn(t,e),gi(t),n??t?.sessionKey)}function at(t){let e=W.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 ta(t){return ui(t)}var ln,Ys,un,W,ae=z(()=>{xe();Ys="claude-code",un={"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:{}};W={maxSessions:20,idleTimeoutMinutes:15,sessionGcAgeMinutes:1440,maxPersistedSessions:1e4,maxAutoResponds:10,permissionMode:"plan",planApproval:"delegate",defaultWorktreeStrategy:"delegate",harnesses:{"claude-code":{...un["claude-code"]},codex:{...un.codex},opencode:{...un.opencode}}}});function V(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function H(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 na(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 ra(t){if(typeof t=="string"){let s=t.trim();return s?{label:s,value:s,recommended:na(s)}:void 0}let e=V(t);if(!e)return;let n=H(e,["label","title","text","value","name","id"])?.trim();if(!n)return;let r=H(e,["description","preview","detail","details"]),o=H(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:na(n,e)}}function Gn(t){let e=V(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(ra).filter(r=>!!r):[]}function xt(t){let e=V(t);return(Array.isArray(e?.questions)?e.questions:[]).map((r,o)=>Oc(r,o)).filter(r=>!!r)}function Oc(t,e=0){let n=V(t);if(!n)return;let r=H(n,["question","prompt","message","text","summary"])?.trim();if(!r)return;let o=H(n,["id","questionId","question_id","name"]),i=H(n,["header","title","label"]),a=(Array.isArray(n.options)?n.options:Array.isArray(n.choices)?n.choices:[]).map(ra).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 oa(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 Hn(t){if(t.length===0)return;let e=t.flatMap((n,r)=>[...r>0?[""]:[],...oa(n,r,t.length)]);return t.length>1&&e.push("","Reply with answers by question, for example: Q1: ..., Q2: ..."),e.join(`
3
- `)}function Le(t,e,n){return oa(t,e,n).join(`
4
- `)}var pn=z(()=>{});function Tt(t){return{type:"backend_ref",ref:t}}function Ct(t){return{type:"run_started",...t?{runId:t}:{}}}function dt(t){return{type:"text_delta",text:t}}function zn(t,e){return{type:"tool_call",name:t,input:e}}function _e(t){return{type:"pending_input",state:t}}function Ze(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function Qn(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function Mt(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function Be(t){return{type:"run_completed",data:t}}var Ye,Jn=z(()=>{Ye=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 Wc(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 Nc(t,e,n){let r=xt(n),o=r.length>0?0:void 0,i=o!=null?r[o]:void 0,s=i?.options.map(d=>d.label)??[],a=i?Le(i,o,r.length):Hn(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 Yn,ia=z(()=>{pn();Jn();Yn=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 Ye,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,h)=>{if(m!=="AskUserQuestion")return{behavior:"allow"};let k=Nc(a,++s,h);n.enqueue(_e(k));try{let S=await d(m,h);return n.enqueue(Ze(k.requestId)),S}catch(S){throw n.enqueue(Ze(k.requestId)),S}}}:{}};e.resumeSessionId&&(l.resume=e.resumeSessionId,l.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:l});let m=await p({options:l});try{return m.query(u)}catch(h){throw await m.close?.(),h}})();return(async()=>{try{let m=await f;for await(let h of m){let k=h;if(k.type==="system"&&k.subtype==="init"){a=k.session_id??a,n.enqueue(Tt({kind:"claude-code",conversationId:a}));continue}if(k.type==="system"&&k.subtype==="status"&&k.permissionMode){n.enqueue(Mt(k.permissionMode));continue}if(k.type==="assistant"){r||(r=!0,n.enqueue(Ct()));for(let S of k.message?.content??[]){if(S.type==="text"){o+=o?`
6
- ${S.text}`:S.text,n.enqueue(dt(S.text));continue}S.type==="tool_use"&&((S.name==="ExitPlanMode"||S.name==="set_permission_mode")&&(i=!0),S.name!=="AskUserQuestion"&&n.enqueue(zn(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(Qn(b,!0))}n.enqueue(Be({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:Wc(k),session_id:k.session_id??a})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(m=>{n.enqueue(Be({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 h=await f;typeof h.setPermissionMode=="function"&&await h.setPermissionMode(m)},async streamInput(m){let h=await f;typeof h.streamInput=="function"&&await h.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 Lc}from"node:child_process";import Bc from"node:readline";function sa(t){return t instanceof Error?t.message:String(t)}function _t(t,e){JSON.stringify({component:"CodexAppServerRpc",event:t,at:new Date().toISOString(),...e})}function Fc(t,e){return{commandKind:t==="codex"?"codex":"custom",appServerSubcommand:!0,configuredArgCount:e.length}}function qc(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function Kc(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:sa(r)}})}}}function hi(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 Xn,aa=z(()=>{Xn=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=Lc(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(_t("process.spawn",{...Fc(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=>{_t("process.error",{pid:e.pid,error:sa(r)})}),e.on("close",(r,o)=>{_t("process.close",{pid:e.pid,code:r,signal:o,pendingRequests:this.pending.size,recentStderr:hi(this.stderrTail.trim())}),this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){_t("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),_t("request.timeout",{id:o,method:e,timeoutMs:d,pid:this.process?.pid,recentStderr:hi(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=qc(e);n&&await Kc(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){this.pending.size>0&&_t("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: ${hi(r)}`:"";return`codex app server timeout after ${n}ms: ${e}${o}`}}});function da(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 la=z(()=>{});function Fe(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 Uc(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>Fe("codex",r)?.toLowerCase()===n)}function er(t,e,n){return t==="codex"?Uc(e,n):da(e,n)}function $t(t,e){return t!=="codex"||!e?!0:!e.includes("/")}function tr(t,e,n){if(t!=="codex"||!e||!n||n.length===0)return e;let r=e.toLowerCase(),o=n.find(i=>Fe("codex",i)?.toLowerCase()===r);return Fe("codex",o)??e}var nr=z(()=>{la()});function Vc(t){return t instanceof Error?t.message:String(t)}function ua(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function Xe(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>Xe(n)).join("");let e=V(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=Xe(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=Xe(e[n]);if(r)return r}return""}function mn(t){let e=V(t);if(!e)return{};let n=V(e.thread)??V(e.session),r=V(e.turn)??V(e.run),o=V(e.item),i=V(e.serverRequest);return{threadId:H(e,["threadId","thread_id","conversationId","conversation_id"])??H(n,["id","threadId","thread_id","conversationId"]),runId:H(e,["turnId","turn_id","runId","run_id"])??H(r,["id","turnId","turn_id","runId","run_id"]),requestId:H(e,["requestId","request_id","serverRequestId"])??H(i,["id","requestId","request_id"]),itemId:H(e,["itemId","item_id"])??H(o,["id","itemId","item_id"])}}function rr(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=rr(i,e,n+1);if(s)return s}return}let r=V(t);if(!r)return;let o=H(r,e);if(o)return o;for(let i of Object.values(r)){let s=rr(i,e,n+1);if(s)return s}}function fn(t){return{threadId:mn(t).threadId,cwd:rr(t,["cwd","workdir","directory"])}}function ca(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function pa(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 or(t){let e=V(t);if(!e)return;let n=V(e.item)??e;return H(n,["id","itemId","item_id","messageId","message_id"])}function jc(t,e=!1){let n=V(t);if(!n)return"";let r=V(n.item)??n;return H(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?Xe(r):H(r,["text"],{trim:!1})??Xe(r)}function ma(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:Xe(e),itemId:or(e)}:n==="item/completed"?{mode:"snapshot",text:jc(e),itemId:or(e)}:{mode:"ignore",text:""}}function fa(t){return{itemId:or(t),delta:Xe(t)}}function ga(t){let e=V(t),n=V(e?.plan),o=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(i=>{let s=V(i),a=H(s,["step","title","text"]);if(!a)return null;let d=H(s,["status"])?.toLowerCase()??"pending";return{step:a,status:d==="inprogress"||d==="in_progress"?"inProgress":d==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:H(n,["explanation"])??H(e,["explanation"]),steps:o}}function ha(t){let e=V(t);if(!e)return{};let n=V(e.item)??e;return H(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:or(n),text:H(n,["text"],{trim:!1})??Xe(n)}}function ya(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=V(e)??{},o=V(r.turn)??r,i=H(o,["status"])?.toLowerCase();return i==="failed"?"failed":i==="interrupted"||i==="cancelled"?"interrupted":"completed"}function ka(t,e){let n=V(e)??{},r=V(n.turn)??n,o=V(r.error)??V(n.error);if(o)return H(o,["message","text","summary","reason"])}function Gc(t,e){let n=Vc(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 zc(t){return Hc.has(t.trim().toLowerCase())}function Qc(t){let e=V(t);return e?!!H(e,["threadId","thread_id"]):!1}async function gn(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(zc(n)&&!Qc(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,!Gc(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function Sa(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 va(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 Jc(t){return[{type:"text",text:t}]}function Yc(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 wa(t){let e={threadId:t.threadId,input:Jc(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=Yc(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function Pa(t){return[{threadId:t.threadId,turnId:t.turnId}]}function Zc(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 ba(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=xt(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let a=o?Gn(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(h=>h.label),f=(l?Le(l,d??0,s.length):Hn(s))??(o?rr(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,m=o?p.map(h=>({kind:"approval",label:h,decision:Zc(h),responseDecision:h})):p.map(h=>({kind:"option",label:h,value:h}));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 Ra(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function yi(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var Hc,Aa=z(()=>{pn();Hc=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function op(t){let e=t?.trim();return e&&rp.test(e)?e:void 0}function ip(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return ki;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:ki}function hn(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 sp(t){return{commandKind:t.command==="codex"?"codex":"custom",configuredArgCount:t.args.length,requestTimeoutMs:t.requestTimeoutMs}}function qe(t){return{hasThreadId:!!t.threadId,hasTurnId:!!t.turnId,hasBackendWorktreePath:!!t.backendWorktreePath,hasBackendWorktreeId:!!t.backendWorktreeId}}function ap(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 xa(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:Le(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}function dp(t){if(t===void 0)return Ia;let e=ua(t);return e.length>0?e:Ia}var Xc,ki,Ia,ep,tp,np,rp,ir,Ta=z(()=>{aa();Jn();pn();nr();Aa();Xc="1.0",ki=12e4,Ia=["--listen","stdio://"],ep="OPENCLAW_CODEX_APP_SERVER_COMMAND",tp="OPENCLAW_CODEX_APP_SERVER_ARGS",np="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS",rp=/^(?: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}$/;ir=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[ep]?.trim()||"codex",args:dp(process.env[tp]),requestTimeoutMs:ip(process.env[np])},r=this.deps.createClient?.(n)??new Xn(n.command,n.args,n.requestTimeoutMs),o=new Ye,i=op(e.resumeSessionId);e.resumeSessionId;let s,a=e.backendRef?.worktreePath,d=e.backendRef?.worktreeId,l=e.permissionMode??"default",u=Fe(this.name,e.model);if(!$t(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=[],h,k=new Map,S=new Set,b=E=>{let C=E?.trim();if(!C)return;let x=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&C!==x&&ca(C)&&(a=C,d=pa(C))},A=()=>{i&&o.enqueue(Tt({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...d?{worktreeId:d}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async(E,C)=>{let x=E.trim().toLowerCase(),$=mn(C),q=fn(C);if($.threadId&&i&&$.threadId!==i)return;if($.threadId&&(i=$.threadId),$.runId&&(s=$.runId),b(q.cwd),($.threadId||$.runId||q.cwd)&&A(),x==="serverrequest/resolved"){c&&(o.enqueue(Ze(c.requestId)),c=void 0);return}if(x==="turn/plan/updated"){let G=ga(C);f=G.explanation??f,G.steps.length>0&&(m=G.steps);return}if(x==="item/plan/delta"){let G=fa(C);if(G.itemId&&G.delta){let se=k.get(G.itemId)??"";k.set(G.itemId,`${se}${G.delta}`)}return}if(x==="item/completed"){let G=ha(C);if(G.text?.trim()){let se={explanation:f||void 0,steps:m,markdown:G.text.trim()};o.enqueue(Qn(se,!0));return}}let L=ma(x,C);if(L.mode==="delta"&&L.text){L.itemId&&S.add(L.itemId),o.enqueue(dt(L.text));return}L.mode==="snapshot"&&L.text&&(!L.itemId||!S.has(L.itemId))&&o.enqueue(dt(L.text)),(x==="turn/completed"||x==="turn/failed"||x==="turn/cancelled")&&h&&(h.method=E,h.params=C,h.resolve())}),r.setRequestHandler(async(E,C)=>{if(!Ra(E))return{};let x=mn(C),$=fn(C);if(x.threadId&&i&&x.threadId!==i)return{};x.threadId&&(i=x.threadId),x.runId&&(s=x.runId),b($.cwd),(x.threadId||x.runId||$.cwd)&&A();let q=x.requestId??`${i??"codex"}-${Date.now().toString(36)}`,L;try{L=ba(E,q,C)}catch(nn){let rn=hn(nn);return`${rn}`,{error:rn}}let G=E.trim().toLowerCase(),se=L.options,Ie=L.actions??[],wt=await new Promise(nn=>{c={requestId:q,methodLower:G,state:L,options:se,actions:Ie,answers:{...L.answers??{}},resolveResponse:nn},o.enqueue(_e(L))});return c=void 0,o.enqueue(Ze(q)),wt});let M=async()=>{ve("client.initialize.start",{...sp(n),hasResumeSessionId:!!e.resumeSessionId}),await r.connect(),await r.request("initialize",{protocolVersion:Xc,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 E=yi(l,e.codexApprovalPolicy);if(i){ve("thread.resume.start",qe({threadId:i}));let $=await gn({client:r,methods:["thread/resume"],payloads:va({threadId:i,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:E.approvalPolicy,sandbox:E.sandbox}),timeoutMs:n.requestTimeoutMs}),q=fn($);i=q.threadId??i,b(q.cwd),A(),ve("thread.resume.done",{...qe({threadId:i,backendWorktreePath:a,backendWorktreeId:d})});return}ve("thread.start.start",{hasCwd:!!e.cwd});let C=await gn({client:r,methods:["thread/start","thread/new"],payloads:Sa({cwd:e.cwd,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:E.approvalPolicy,sandbox:E.sandbox}),timeoutMs:n.requestTimeoutMs}),x=fn(C);if(i=x.threadId,!i)throw new Error("Codex App Server did not return a thread id.");b(x.cwd),A(),ve("thread.start.done",{...qe({threadId:i,backendWorktreePath:a,backendWorktreeId:d})})},y=async E=>{await R(),ve("turn.start",{...qe({threadId:i}),runCounter:p+1,promptChars:E.length,permissionMode:l}),o.enqueue(Ct()),p+=1,f="",m=[],k.clear(),S.clear();let C="",x,$,q=new Promise(L=>{$=L});h={resolve:$};try{let L=yi(l,e.codexApprovalPolicy),G=await gn({client:r,methods:["turn/start"],payloads:wa({threadId:i,prompt:E,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:l,approvalPolicy:L.approvalPolicy,sandbox:L.sandbox}),timeoutMs:n.requestTimeoutMs}),se=mn(G);se.runId&&(s=se.runId,A()),await q,C=h?.method??"turn/failed",x=h?.params;let Ie=ya(C,x);ve("turn.terminal",{...qe({threadId:i,turnId:s}),terminalMethod:C,outcome:Ie}),o.enqueue(Be({success:Ie==="completed",outcome:Ie,duration_ms:0,total_cost_usd:0,num_turns:p,result:ka(C,x),session_id:i}))}catch(L){ve("turn.error",{...qe({threadId:i,turnId:s}),error:hn(L)}),o.enqueue(Be({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:hn(L),session_id:i??""}))}finally{h=void 0}},w=async E=>{let C=c;if(!C)return!1;let x=E.trim();if(C.methodLower.includes("requestapproval"))return C.resolveResponse({decision:x||"decline"}),!0;let $=C.state.questions??[];if($.length>0){if(!x)return!1;let q=C.state.activeQuestionIndex??0,L=$[q];if(!L)return!1;C.answers={...C.answers,[L.id]:{answers:[x]}};let G=q+1;if(G<$.length)return C.state=xa(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:x});return!0},T=async(E,C={})=>{let x=c;if(!x||C.requestId&&C.requestId!==x.state.requestId)return!1;let $=x.actions[E];if($?.kind==="approval")return x.resolveResponse({decision:$.responseDecision,...$.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:$.proposedExecpolicyAmendment}:{}}),!0;let q=x.state.questions??[],L=x.state.activeQuestionIndex??0,G=q.length>0?q[L]:void 0;if(C.questionId&&C.questionId!==G?.id)return!1;let se=G?.options[E];if(G&&se){x.answers={...x.answers,[G.id]:{answers:[se.value??se.label]}};let wt=L+1;return wt<q.length?(x.state=xa(x.state,wt,x.answers),x.options=x.state.options,o.enqueue(_e(x.state)),!0):(x.resolveResponse({answers:x.answers}),!0)}let Ie=x.options[E];return Ie?(x.methodLower.includes("requestapproval")?x.resolveResponse({decision:Ie}):x.resolveResponse({option:Ie,index:E}),!0):!1},K=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{await M();for await(let E of K){let C=ap(E).trim();!C||await w(C)||await y(C)}}catch(E){ve("session.error",{...qe({threadId:i,turnId:s}),error:hn(E)}),o.enqueue(Be({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:hn(E),session_id:i??e.resumeSessionId??""}))}finally{ve("client.close.start",qe({threadId:i,turnId:s})),await r.close().catch(()=>{}),ve("client.close.done",qe({threadId:i,turnId:s})),o.close()}})(),{messages:o.messages(),async setPermissionMode(E){l=E,o.enqueue(Mt(E))},async submitPendingInputOption(E,C){return T(E,C)},async submitPendingInputText(E){return w(E)},async interrupt(){!i||!s||await gn({client:r,methods:["turn/interrupt"],payloads:Pa({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as lp}from"node:child_process";import{constants as up,accessSync as cp}from"node:fs";import{createServer as pp}from"node:net";import{delimiter as mp,dirname as Si,join as _a,sep as fp}from"node:path";function Dt(t){return t instanceof Error?t.message:String(t)}function Sp(t){try{return cp(t,up.X_OK),!0}catch{return!1}}function vp(t){return t.includes("/")||fp==="\\"&&t.includes("\\")}function wp(t){let e=(t??"").split(mp).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(_a(Si(Si(Si(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function Pp(t,e=process.env.PATH){if(vp(t))return t;for(let n of wp(e)){let r=_a(n,t);if(Sp(r))return r}return t}function oe(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function bp(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 $a(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 Rp(t){let e=$a(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function Ca(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return kp.map(r=>({permission:r,pattern:"*",action:n}))}function vi(){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 Ap(){return new Promise((t,e)=>{let n=pp();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 Ea(t){await new Promise(e=>setTimeout(e,t))}async function sr(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 Et(t){t.exitCode===null&&await new Promise(e=>{let n,r=setTimeout(()=>{t.exitCode===null&&t.kill("SIGKILL"),n=setTimeout(e,1e3)},2e3);t.once("exit",()=>{clearTimeout(r),n&&clearTimeout(n),e()}),t.kill("SIGTERM")})}function Ip(t){return t.headers.get("content-type")?.toLowerCase()??""}function Pi(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function xp(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function Tp(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=Pi(r),s=xp(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 Cp(t,e,n){let r=$a(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function Mp(t,e){if(!oe(t))return!1;if(!(e in t))return!0;let n=t[e];return oe(n)&&n.type==="idle"}function _p(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function $p(t){return new Promise((e,n)=>{Ma=Ma.then(()=>t().then(e,n)).catch(()=>{})})}async function Ep(t){return $p(async()=>{let e=await Ap(),n=process.env[gp]?.trim()||"opencode",r=Pp(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??Ai,1e4),a=t.startupTimeoutMs??hp,d=lp(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??""}.`,h=()=>{let S=[u.trim(),c.trim()].filter(Boolean).join(`
8
- `).trim();return`${m()}${S?` Output:
9
- ${S}`:""}`},k=()=>{Et(d)};if(t.signal?.aborted)throw await Et(d),new Error(`OpenCode server startup aborted before readiness.${h()}`);t.signal?.addEventListener("abort",k,{once:!0});try{let S=Date.now();for(;Date.now()-S<a;){if(t.signal?.aborted)throw await Et(d),new Error(`OpenCode server startup aborted before readiness.${h()}`);if(p)throw new Error(`OpenCode server failed to start: ${p.message}${h()}`);if(d.exitCode!==null)throw new Error(`OpenCode server exited before readiness.${h()}`);try{if(await Op({baseUrl:l,fetchImpl:i,requestTimeoutMs:s,startupSignal:t.signal,timeoutMessage:`OpenCode GET /api/health timed out after ${s}ms during server readiness.${h()}`,abortMessage:`OpenCode server startup aborted before readiness.${h()}`}))return{baseUrl:l,close:async()=>{await Et(d)}}}catch{if(t.signal?.aborted)throw await Et(d),new Error(`OpenCode server startup aborted before readiness.${h()}`)}await Ea(100)}throw await Et(d),new Error(`Timed out waiting for OpenCode server readiness.${h()}`)}finally{t.signal?.removeEventListener("abort",k)}})}async function Dp(t){for(let e=1;;e+=1)try{return await Ep(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(Dt(n)))throw n}}async function Op(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await sr(t.fetchImpl(`${t.baseUrl}/api/health`,{headers:vi(),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 Wp(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 Np(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function Lp(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=xt(t),o=Gn(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?Le(a,s??0,i.length):n,options:d,...i.length>0?{questions:i}:{},...s!=null?{activeQuestionIndex:s}:{},allowsFreeText:!0}}function Fp(t,e,n){let r=t.questions??[],o=r[e],i=o?.options.map(s=>s.label)??[];return{...t,promptText:o?Le(o,e,r.length):t.promptText,options:i,activeQuestionIndex:e,answers:n}}function qp(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}
1
+ var Uc=Object.defineProperty;var Q=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var Kc=(t,e)=>{for(var n in e)Uc(t,n,{get:e[n],enumerable:!0})};function ya(t){try{return t?.config?.current?.()}catch{return}}function _t(t,e){if(t&&typeof t=="object"){pt=t,arguments.length>=2?(pn=e,Mt=!0):Mt||(pn=ya(pt),Mt=!0);return}pt=void 0,pn=void 0,Mt=!1}function tt(){return pt}function vi(){return pt?.tasks?.managedFlows??pt?.taskFlow}function ka(){return Mt||(pn=ya(pt),Mt=!0),pn}var pt,pn,Mt,mt=Q(()=>{Mt=!1});function Ra(t){let e=t.chatId.trim(),n=t.topicId.trim();return!/^-?\d+$/.test(e)||!/^\d+$/.test(n)?null:`${e}:topic:${n}`}function sp(t){let e=t.conversationId.trim(),n=e.match(/^(-?\d+):topic:(\d+)$/i);if(n?.[1]&&n[2]){let i=Ra({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=Ra({chatId:r,topicId:e});return o?{chatId:r,topicId:e,canonicalConversationId:o}:null}function ap(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 dp(t,e){if(!/^\d+$/.test(t))return t;let n=ap(e);return n?`${n}:${t}`:`channel:${t}`}function lp(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 up(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 cp(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||!ip.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 pp(t,e=sp){try{return e({conversationId:t})}catch{return null}}function bi(t){return{provider:"system",target:"system",sessionKey:t?.trim()||void 0}}function Ri(t,e){return{...t,threadId:e??t.threadId}}function fp(t,e,n){return t==="telegram"&&n?.provider==="telegram"&&!!n.target&&e!==n.target}function gp(t){let e=t?.trim();if(!e)return;let n=cp(e);if(!n)return;let{provider:r,kind:o,rawId:i}=n,s=up(i),a=null;if(r==="telegram")try{a=mp.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 Ai(t){let e=t?.match(/:topic:(\d+)$/i);return e?parseInt(e[1],10):void 0}function mn(t){return!!(t?.provider&&t.target&&t.provider!=="system"&&t.target!=="system")}function Te(t,e,n){let r=gp(n),o=e!=null?String(e):void 0,i=t?.trim();if(!i||i.toLowerCase()==="unknown")return r?Ri(r,o):bi(n);let s=i.split("|").map(f=>f.trim());if(s.length<2)return r?Ri(r,o):bi(n);let[a,d,l]=s,u=s.length>=3?l:d,m=s.length>=3?d:void 0,p=a?.toLowerCase();if(!p||!u)return r?Ri(r,o):bi(n);let y=p==="discord"?dp(u,n):u;return fp(p,y,r)?{provider:p,accountId:m,target:r.target,threadId:o??r.threadId,sessionKey:n?.trim()||void 0}:{provider:p,accountId:m,target:y,threadId:o??(r?.provider===p?r.threadId:void 0),sessionKey:n?.trim()||void 0}}function Ee(t){return Te(lp(t.route)??t.originChannel,t.route?.threadId??t.originThreadId,t.route?.sessionKey??t.originSessionKey)??t.route}function Be(t){let e=Ee(t);return mn(e)?e:void 0}function hp(t){return Object.fromEntries(Object.entries(t).filter(e=>!!e[1]))}function fn(t){let e=Ee(t);if(!mn(e))return"";let n=hp({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 ip,mp,he=Q(()=>{ip=new Set(["telegram","discord","slack","system","mattermost","feishu","line","whatsapp","signal","matrix","googlechat","bluebubbles","imessage","msteams"]);mp={safeParseTelegramTopicConversation:pp}});import{readFileSync as yp}from"fs";import{homedir as kp}from"os";import{join as Sp}from"path";function Ia(){if(gn!==void 0)return gn;try{let t=yp(Sp(kp(),".claude.json"),"utf-8");gn=JSON.parse(t).mcpServers??{}}catch{gn={}}return gn}function xa(t){let e=t.defaultHarness??Aa,n={};for(let[r,o]of Object.entries(hn)){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});L={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 ue(){return L.defaultHarness??Aa}function Ti(t){let e=hn[t],n=L.harnesses[t];return{...e,...n,allowedModels:n?.allowedModels??e?.allowedModels}}function Dt(t){return Ti(t).defaultModel}function er(t){return L.harnesses[t]?.allowedModels??L.allowedModels}function rt(t){return Ti(t).reasoningEffort}function Ot(t){return t==="codex"?Ti(t).fastMode:void 0}function be(t){return t==null?void 0:String(t).trim()||void 0}function Ci(t){return{channel:be(t?.deliveryContext?.channel),to:be(t?.deliveryContext?.to),accountId:be(t?.deliveryContext?.accountId),threadId:be(t?.deliveryContext?.threadId)}}function Ta(t,e,n){if(!(!t||!e))return n?`${t}|${n}|${e}`:`${t}|${e}`}function Ii(t){return be(t?.requesterSenderId??t?.senderId)}function xi(t){return(be(t.deliveryContext?.channel)??t.messageChannel??t.channel)?.toLowerCase()!=="telegram"?!1:!!(Ai(t.sessionKey)||be(t.messageThreadId)||be(t.deliveryContext?.threadId))}function tr(t){let e=Ci(t),n=Ta(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=be(t.chatId);if(r.length===1&&o)return`${r[0]}|${o}`;let i=Ii(t);if(r.length===1&&i&&!xi(t))return`${r[0]}|${i}`}if(t.workspaceDir){let r=ft(t.workspaceDir);if(r)return r}if(t.messageChannel&&t.messageChannel.includes("|"))return t.messageChannel}function yn(t,e){if(e&&String(e).includes("|"))return String(e);let n=Ci(t),r=Ta(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=be(t.chatId);if(d)return`${a}|${d}`;let l=Ii(t);if(l&&!xi(t))return`${a}|${l}`}let o=be(t?.channel),i=be(t?.chatId);if(o&&i)return`${o}|${i}`;let s=Ii(t);return o&&s&&!xi(t)?`${o}|${s}`:t?.id&&/^-?\d+$/.test(String(t.id))?`telegram|${t.id}`:L.fallbackChannel??"unknown"}function Mi(t){return Ci(t).threadId??t?.messageThreadId??void 0}function Nt(t,e,n){return Te(yn(t,e),Mi(t),n??t?.sessionKey)}function ft(t){let e=L.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 Ca(t){return Ai(t)}var gn,Aa,hn,L,oe=Q(()=>{he();Aa="claude-code",hn={"claude-code":{defaultModel:"anthropic/claude-sonnet-4-7",allowedModels:["sonnet","opus"]},codex:{defaultModel:"gpt-5.6-sol",allowedModels:["gpt-5.6-sol","gpt-5.6-terra","gpt-5.6-luna"],reasoningEffort:"medium"},opencode:{}};L={maxSessions:20,idleTimeoutMinutes:15,sessionGcAgeMinutes:1440,maxPersistedSessions:1e4,maxAutoResponds:10,permissionMode:"plan",planApproval:"delegate",defaultWorktreeStrategy:"delegate",harnesses:{"claude-code":{...hn["claude-code"]},codex:{...hn.codex},opencode:{...hn.opencode}}}});function kn(t,e){return e?{...e,...t}:t}function Np(t){return{...t,[$i]:!0}}function Wp(t){return{const:t,type:typeof t}}var $i,g,re=Q(()=>{$i=Symbol("optionalSchema");g={Object(t,e){let n=Object.entries(t).filter(([,o])=>!o[$i]).map(([o])=>o),r=Object.fromEntries(Object.entries(t).map(([o,i])=>{let{[$i]:s,...a}=i;return[o,a]}));return{...e,type:"object",...n.length>0?{required:n}:{},properties:r}},String(t){return kn({type:"string"},t)},Number(t){return kn({type:"number"},t)},Boolean(t){return kn({type:"boolean"},t)},Array(t,e){return kn({type:"array",items:t},e)},Literal:Wp,Union(t,e){return kn({anyOf:t},e)},Optional:Np}});function Ei(t){v=t}function Di(t){J=t}function Oi(t){De=t}var v,J,De,K=Q(()=>{v=null,J=null,De=null});function j(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function H(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 Na(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 Wa(t){if(typeof t=="string"){let s=t.trim();return s?{label:s,value:s,recommended:Na(s)}:void 0}let e=j(t);if(!e)return;let n=H(e,["label","title","text","value","name","id"])?.trim();if(!n)return;let r=H(e,["description","preview","detail","details"]),o=H(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:Na(n,e)}}function ir(t){let e=j(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(Wa).filter(r=>!!r):[]}function Ft(t){let e=j(t);return(Array.isArray(e?.questions)?e.questions:[]).map((r,o)=>qp(r,o)).filter(r=>!!r)}function qp(t,e=0){let n=j(t);if(!n)return;let r=H(n,["question","prompt","message","text","summary"])?.trim();if(!r)return;let o=H(n,["id","questionId","question_id","name"]),i=H(n,["header","title","label"]),a=(Array.isArray(n.options)?n.options:Array.isArray(n.choices)?n.choices:[]).map(Wa).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 La(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 sr(t){if(t.length===0)return;let e=t.flatMap((n,r)=>[...r>0?[""]:[],...La(n,r,t.length)]);return t.length>1&&e.push("","Reply with answers by question, for example: Q1: ..., Q2: ..."),e.join(`
3
+ `)}function qe(t,e,n){return La(t,e,n).join(`
4
+ `)}var Sn=Q(()=>{});function Bt(t){return{type:"backend_ref",ref:t}}function qt(t){return{type:"run_started",...t?{runId:t}:{}}}function ht(t){return{type:"text_delta",text:t}}function ar(t,e){return{type:"tool_call",name:t,input:e}}function Oe(t){return{type:"pending_input",state:t}}function it(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function dr(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function Ut(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function Ue(t){return{type:"run_completed",data:t}}var ot,lr=Q(()=>{ot=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 cr from"@anthropic-ai/claude-agent-sdk";function Up(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 Kp(t,e,n){let r=Ft(n),o=r.length>0?0:void 0,i=o!=null?r[o]:void 0,s=i?.options.map(d=>d.label)??[],a=i?qe(i,o,r.length):sr(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 ur,Fa=Q(()=>{Sn();lr();ur=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 ot,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(f,c)=>{if(f!=="AskUserQuestion")return{behavior:"allow"};let h=Kp(a,++s,c);n.enqueue(Oe(h));try{let S=await d(f,c);return n.enqueue(it(h.requestId)),S}catch(S){throw n.enqueue(it(h.requestId)),S}}}:{}};e.resumeSessionId&&(l.resume=e.resumeSessionId,l.forkSession=e.forkSession??!1);let u=e.prompt,m=this.deps.query??cr.query,p=this.deps.startup??cr.startup,y=(async()=>{if(typeof p!="function")return m({prompt:u,options:l});let f=await p({options:l});try{return f.query(u)}catch(c){throw await f.close?.(),c}})();return(async()=>{try{let f=await y;for await(let c of f){let h=c;if(h.type==="system"&&h.subtype==="init"){a=h.session_id??a,n.enqueue(Bt({kind:"claude-code",conversationId:a}));continue}if(h.type==="system"&&h.subtype==="status"&&h.permissionMode){n.enqueue(Ut(h.permissionMode));continue}if(h.type==="assistant"){r||(r=!0,n.enqueue(qt()));for(let S of h.message?.content??[]){if(S.type==="text"){o+=o?`
6
+ ${S.text}`:S.text,n.enqueue(ht(S.text));continue}S.type==="tool_use"&&((S.name==="ExitPlanMode"||S.name==="set_permission_mode")&&(i=!0),S.name!=="AskUserQuestion"&&n.enqueue(ar(S.name,S.input)))}continue}if(h.type==="result"){let S=o.trim();if(S&&(e.permissionMode==="plan"||i)){let b={explanation:void 0,steps:[],markdown:S};n.enqueue(dr(b,!0))}n.enqueue(Ue({success:h.subtype==="success",duration_ms:h.duration_ms??0,total_cost_usd:h.total_cost_usd??0,num_turns:h.num_turns??0,result:Up(h),session_id:h.session_id??a})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(f=>{n.enqueue(Ue({success:!1,duration_ms:0,total_cost_usd:0,num_turns:0,result:f instanceof Error?f.message:String(f),session_id:a})),n.close()}),{messages:n.messages(),async setPermissionMode(f){let c=await y;typeof c.setPermissionMode=="function"&&await c.setPermissionMode(f)},async streamInput(f){let c=await y;typeof c.streamInput=="function"&&await c.streamInput(f)},async interrupt(){let f=await y;typeof f.interrupt=="function"&&await f.interrupt()}}}buildUserMessage(e,n){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:n}}}});import{spawn as Vp}from"node:child_process";import jp from"node:readline";function Ba(t){return t instanceof Error?t.message:String(t)}function Kt(t,e){JSON.stringify({component:"CodexAppServerRpc",event:t,at:new Date().toISOString(),...e})}function Gp(t,e){return{commandKind:t==="codex"?"codex":"custom",appServerSubcommand:!0,configuredArgCount:e.length}}function Hp(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function zp(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:Ba(r)}})}}}function Ni(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 pr,qa=Q(()=>{pr=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=Vp(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(Kt("process.spawn",{...Gp(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,jp.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=>{Kt("process.error",{pid:e.pid,error:Ba(r)})}),e.on("close",(r,o)=>{Kt("process.close",{pid:e.pid,code:r,signal:o,pendingRequests:this.pending.size,recentStderr:Ni(this.stderrTail.trim())}),this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){Kt("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),Kt("request.timeout",{id:o,method:e,timeoutMs:d,pid:this.process?.pid,recentStderr:Ni(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=Hp(e);n&&await zp(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){this.pending.size>0&&Kt("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: ${Ni(r)}`:"";return`codex app server timeout after ${n}ms: ${e}${o}`}}});function Ua(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 Ka=Q(()=>{});function Ke(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 Qp(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>Ke("codex",r)?.toLowerCase()===n)}function mr(t,e,n){return t==="codex"?Qp(e,n):Ua(e,n)}function Vt(t,e){return t!=="codex"||!e?!0:!e.includes("/")}function fr(t,e,n){if(t!=="codex"||!e||!n||n.length===0)return e;let r=e.toLowerCase(),o=n.find(i=>Ke("codex",i)?.toLowerCase()===r);return Ke("codex",o)??e}var gr=Q(()=>{Ka()});function Jp(t){return t instanceof Error?t.message:String(t)}function Va(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function st(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>st(n)).join("");let e=j(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=st(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=st(e[n]);if(r)return r}return""}function vn(t){let e=j(t);if(!e)return{};let n=j(e.thread)??j(e.session),r=j(e.turn)??j(e.run),o=j(e.item),i=j(e.serverRequest);return{threadId:H(e,["threadId","thread_id","conversationId","conversation_id"])??H(n,["id","threadId","thread_id","conversationId"]),runId:H(e,["turnId","turn_id","runId","run_id"])??H(r,["id","turnId","turn_id","runId","run_id"]),requestId:H(e,["requestId","request_id","serverRequestId"])??H(i,["id","requestId","request_id"]),itemId:H(e,["itemId","item_id"])??H(o,["id","itemId","item_id"])}}function hr(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=hr(i,e,n+1);if(s)return s}return}let r=j(t);if(!r)return;let o=H(r,e);if(o)return o;for(let i of Object.values(r)){let s=hr(i,e,n+1);if(s)return s}}function wn(t){return{threadId:vn(t).threadId,cwd:hr(t,["cwd","workdir","directory"])}}function ja(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function Ga(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 yr(t){let e=j(t);if(!e)return;let n=j(e.item)??e;return H(n,["id","itemId","item_id","messageId","message_id"])}function Yp(t,e=!1){let n=j(t);if(!n)return"";let r=j(n.item)??n;return H(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?st(r):H(r,["text"],{trim:!1})??st(r)}function Ha(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:st(e),itemId:yr(e)}:n==="item/completed"?{mode:"snapshot",text:Yp(e),itemId:yr(e)}:{mode:"ignore",text:""}}function za(t){return{itemId:yr(t),delta:st(t)}}function Qa(t){let e=j(t),n=j(e?.plan),o=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(i=>{let s=j(i),a=H(s,["step","title","text"]);if(!a)return null;let d=H(s,["status"])?.toLowerCase()??"pending";return{step:a,status:d==="inprogress"||d==="in_progress"?"inProgress":d==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:H(n,["explanation"])??H(e,["explanation"]),steps:o}}function Ja(t){let e=j(t);if(!e)return{};let n=j(e.item)??e;return H(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:yr(n),text:H(n,["text"],{trim:!1})??st(n)}}function Ya(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=j(e)??{},o=j(r.turn)??r,i=H(o,["status"])?.toLowerCase();return i==="failed"?"failed":i==="interrupted"||i==="cancelled"?"interrupted":"completed"}function Za(t,e){let n=j(e)??{},r=j(n.turn)??n,o=j(r.error)??j(n.error);if(o)return H(o,["message","text","summary","reason"])}function Zp(t,e){let n=Jp(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 em(t){return Xp.has(t.trim().toLowerCase())}function tm(t){let e=j(t);return e?!!H(e,["threadId","thread_id"]):!1}async function Pn(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(em(n)&&!tm(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,!Zp(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function Xa(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 ed(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 nm(t){return[{type:"text",text:t}]}function rm(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 td(t){let e={threadId:t.threadId,input:nm(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=rm(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function nd(t){return[{threadId:t.threadId,turnId:t.turnId}]}function om(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 rd(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=Ft(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let a=o?ir(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(c=>c.label),y=(l?qe(l,d??0,s.length):sr(s))??(o?hr(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,f=o?p.map(c=>({kind:"approval",label:c,decision:om(c),responseDecision:c})):p.map(c=>({kind:"option",label:c,value:c}));return{requestId:e,kind:o?"approval":"question",promptText:y,options:p,...s.length>0?{questions:s}:{},...d!=null?{activeQuestionIndex:d}:{},actions:f,allowsFreeText:!0}}function od(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function Wi(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var Xp,id=Q(()=>{Sn();Xp=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function um(t){let e=t?.trim();return e&&lm.test(e)?e:void 0}function cm(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return Li;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:Li}function bn(t){return t instanceof Error?t.message:String(t)}function Re(t,e){JSON.stringify({component:"CodexHarness",event:t,at:new Date().toISOString(),...e})}function pm(t){return{commandKind:t.command==="codex"?"codex":"custom",configuredArgCount:t.args.length,requestTimeoutMs:t.requestTimeoutMs}}function Ve(t){return{hasThreadId:!!t.threadId,hasTurnId:!!t.turnId,hasBackendWorktreePath:!!t.backendWorktreePath,hasBackendWorktreeId:!!t.backendWorktreeId}}function mm(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 ad(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:qe(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}function fm(t){if(t===void 0)return sd;let e=Va(t);return e.length>0?e:sd}var im,Li,sd,sm,am,dm,lm,kr,dd=Q(()=>{qa();lr();Sn();gr();id();im="1.0",Li=12e4,sd=["--listen","stdio://"],sm="OPENCLAW_CODEX_APP_SERVER_COMMAND",am="OPENCLAW_CODEX_APP_SERVER_ARGS",dm="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS",lm=/^(?: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}$/;kr=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[sm]?.trim()||"codex",args:fm(process.env[am]),requestTimeoutMs:cm(process.env[dm])},r=this.deps.createClient?.(n)??new pr(n.command,n.args,n.requestTimeoutMs),o=new ot,i=um(e.resumeSessionId);e.resumeSessionId;let s,a=e.backendRef?.worktreePath,d=e.backendRef?.worktreeId,l=e.permissionMode??"default",u=Ke(this.name,e.model);if(!Vt(this.name,u))throw new Error(`Codex model "${e.model}" is not supported. Use a bare Codex model id such as "gpt-5.6-sol".`);let m,p=0,y="",f=[],c,h=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&&ja(T)&&(a=T,d=Ga(T))},A=()=>{i&&o.enqueue(Bt({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...d?{worktreeId:d}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async($,T)=>{let C=$.trim().toLowerCase(),N=vn(T),B=wn(T);if(N.threadId&&i&&N.threadId!==i)return;if(N.threadId&&(i=N.threadId),N.runId&&(s=N.runId),b(B.cwd),(N.threadId||N.runId||B.cwd)&&A(),C==="serverrequest/resolved"){m&&(o.enqueue(it(m.requestId)),m=void 0);return}if(C==="turn/plan/updated"){let V=Qa(T);y=V.explanation??y,V.steps.length>0&&(f=V.steps);return}if(C==="item/plan/delta"){let V=za(T);if(V.itemId&&V.delta){let ae=h.get(V.itemId)??"";h.set(V.itemId,`${ae}${V.delta}`)}return}if(C==="item/completed"){let V=Ja(T);if(V.text?.trim()){let ae={explanation:y||void 0,steps:f,markdown:V.text.trim()};o.enqueue(dr(ae,!0));return}}let D=Ha(C,T);if(D.mode==="delta"&&D.text){D.itemId&&S.add(D.itemId),o.enqueue(ht(D.text));return}D.mode==="snapshot"&&D.text&&(!D.itemId||!S.has(D.itemId))&&o.enqueue(ht(D.text)),(C==="turn/completed"||C==="turn/failed"||C==="turn/cancelled")&&c&&(c.method=$,c.params=T,c.resolve())}),r.setRequestHandler(async($,T)=>{if(!od($))return{};let C=vn(T),N=wn(T);if(C.threadId&&i&&C.threadId!==i)return{};C.threadId&&(i=C.threadId),C.runId&&(s=C.runId),b(N.cwd),(C.threadId||C.runId||N.cwd)&&A();let B=C.requestId??`${i??"codex"}-${Date.now().toString(36)}`,D;try{D=rd($,B,T)}catch(ln){let un=bn(ln);return`${un}`,{error:un}}let V=$.trim().toLowerCase(),ae=D.options,xe=D.actions??[],Tt=await new Promise(ln=>{m={requestId:B,methodLower:V,state:D,options:ae,actions:xe,answers:{...D.answers??{}},resolveResponse:ln},o.enqueue(Oe(D))});return m=void 0,o.enqueue(it(B)),Tt});let x=async()=>{Re("client.initialize.start",{...pm(n),hasResumeSessionId:!!e.resumeSessionId}),await r.connect(),await r.request("initialize",{protocolVersion:im,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},n.requestTimeoutMs),await r.notify("initialized",{}),Re("client.initialize.done",{hasResumeSessionId:!!e.resumeSessionId})},R=async()=>{let $=Wi(l,e.codexApprovalPolicy);if(i){Re("thread.resume.start",Ve({threadId:i}));let N=await Pn({client:r,methods:["thread/resume"],payloads:ed({threadId:i,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:$.approvalPolicy,sandbox:$.sandbox}),timeoutMs:n.requestTimeoutMs}),B=wn(N);i=B.threadId??i,b(B.cwd),A(),Re("thread.resume.done",{...Ve({threadId:i,backendWorktreePath:a,backendWorktreeId:d})});return}Re("thread.start.start",{hasCwd:!!e.cwd});let T=await Pn({client:r,methods:["thread/start","thread/new"],payloads:Xa({cwd:e.cwd,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:$.approvalPolicy,sandbox:$.sandbox}),timeoutMs:n.requestTimeoutMs}),C=wn(T);if(i=C.threadId,!i)throw new Error("Codex App Server did not return a thread id.");b(C.cwd),A(),Re("thread.start.done",{...Ve({threadId:i,backendWorktreePath:a,backendWorktreeId:d})})},k=async $=>{await R(),Re("turn.start",{...Ve({threadId:i}),runCounter:p+1,promptChars:$.length,permissionMode:l}),o.enqueue(qt()),p+=1,y="",f=[],h.clear(),S.clear();let T="",C,N,B=new Promise(D=>{N=D});c={resolve:N};try{let D=Wi(l,e.codexApprovalPolicy),V=await Pn({client:r,methods:["turn/start"],payloads:td({threadId:i,prompt:$,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:l,approvalPolicy:D.approvalPolicy,sandbox:D.sandbox}),timeoutMs:n.requestTimeoutMs}),ae=vn(V);ae.runId&&(s=ae.runId,A()),await B,T=c?.method??"turn/failed",C=c?.params;let xe=Ya(T,C);Re("turn.terminal",{...Ve({threadId:i,turnId:s}),terminalMethod:T,outcome:xe}),o.enqueue(Ue({success:xe==="completed",outcome:xe,duration_ms:0,total_cost_usd:0,num_turns:p,result:Za(T,C),session_id:i}))}catch(D){Re("turn.error",{...Ve({threadId:i,turnId:s}),error:bn(D)}),o.enqueue(Ue({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:bn(D),session_id:i??""}))}finally{c=void 0}},P=async $=>{let T=m;if(!T)return!1;let C=$.trim();if(T.methodLower.includes("requestapproval"))return T.resolveResponse({decision:C||"decline"}),!0;let N=T.state.questions??[];if(N.length>0){if(!C)return!1;let B=T.state.activeQuestionIndex??0,D=N[B];if(!D)return!1;T.answers={...T.answers,[D.id]:{answers:[C]}};let V=B+1;if(V<N.length)return T.state=ad(T.state,V,T.answers),T.options=T.state.options,o.enqueue(Oe(T.state)),!0;T.resolveResponse({answers:T.answers})}else T.resolveResponse({text:C});return!0},_=async($,T={})=>{let C=m;if(!C||T.requestId&&T.requestId!==C.state.requestId)return!1;let N=C.actions[$];if(N?.kind==="approval")return C.resolveResponse({decision:N.responseDecision,...N.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:N.proposedExecpolicyAmendment}:{}}),!0;let B=C.state.questions??[],D=C.state.activeQuestionIndex??0,V=B.length>0?B[D]:void 0;if(T.questionId&&T.questionId!==V?.id)return!1;let ae=V?.options[$];if(V&&ae){C.answers={...C.answers,[V.id]:{answers:[ae.value??ae.label]}};let Tt=D+1;return Tt<B.length?(C.state=ad(C.state,Tt,C.answers),C.options=C.state.options,o.enqueue(Oe(C.state)),!0):(C.resolveResponse({answers:C.answers}),!0)}let xe=C.options[$];return xe?(C.methodLower.includes("requestapproval")?C.resolveResponse({decision:xe}):C.resolveResponse({option:xe,index:$}),!0):!1},M=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 M){let T=mm($).trim();!T||await P(T)||await k(T)}}catch($){Re("session.error",{...Ve({threadId:i,turnId:s}),error:bn($)}),o.enqueue(Ue({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:bn($),session_id:i??e.resumeSessionId??""}))}finally{Re("client.close.start",Ve({threadId:i,turnId:s})),await r.close().catch(()=>{}),Re("client.close.done",Ve({threadId:i,turnId:s})),o.close()}})(),{messages:o.messages(),async setPermissionMode($){l=$,o.enqueue(Ut($))},async submitPendingInputOption($,T){return _($,T)},async submitPendingInputText($){return P($)},async interrupt(){!i||!s||await Pn({client:r,methods:["turn/interrupt"],payloads:nd({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as gm}from"node:child_process";import{constants as hm,accessSync as ym}from"node:fs";import{createServer as km}from"node:net";import{delimiter as Sm,dirname as Fi,join as cd,sep as vm}from"node:path";function Gt(t){return t instanceof Error?t.message:String(t)}function Am(t){try{return ym(t,hm.X_OK),!0}catch{return!1}}function Im(t){return t.includes("/")||vm==="\\"&&t.includes("\\")}function xm(t){let e=(t??"").split(Sm).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(cd(Fi(Fi(Fi(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function Tm(t,e=process.env.PATH){if(Im(t))return t;for(let n of xm(e)){let r=cd(n,t);if(Am(r))return r}return t}function ie(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Cm(t){if(typeof t=="string")return t;if(!ie(t))return String(t);if(typeof t.text=="string")return t.text;let e=ie(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function pd(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 Mm(t){let e=pd(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function ld(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return Rm.map(r=>({permission:r,pattern:"*",action:n}))}function Bi(){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 _m(){return new Promise((t,e)=>{let n=km();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 md(t){await new Promise(e=>setTimeout(e,t))}async function Sr(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 jt(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 $m(t){return t.headers.get("content-type")?.toLowerCase()??""}function Ui(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function Em(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function Dm(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=Ui(r),s=Em(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 Om(t,e,n){let r=pd(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function Nm(t,e){if(!ie(t))return!1;if(!(e in t))return!0;let n=t[e];return ie(n)&&n.type==="idle"}function Wm(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function Lm(t){return new Promise((e,n)=>{ud=ud.then(()=>t().then(e,n)).catch(()=>{})})}async function Fm(t){return Lm(async()=>{let e=await _m(),n=process.env[wm]?.trim()||"opencode",r=Tm(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??ji,1e4),a=t.startupTimeoutMs??Pm,d=gm(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),l=`http://127.0.0.1:${e}`,u="",m="",p,y=(S,b)=>{let A=S+String(b);return A.length>8e3?A.slice(-8e3):A};d.stdout.on("data",S=>{u=y(u,S)}),d.stderr.on("data",S=>{m=y(m,S)}),d.once("error",S=>{p=S});let f=()=>` Command: ${n===r?r:`${r} (resolved from ${n})`} ${o.join(" ")}. Cwd: ${t.cwd}. Port: ${e}. PATH: ${process.env.PATH??""}.`,c=()=>{let S=[u.trim(),m.trim()].filter(Boolean).join(`
8
+ `).trim();return`${f()}${S?` Output:
9
+ ${S}`:""}`},h=()=>{jt(d)};if(t.signal?.aborted)throw await jt(d),new Error(`OpenCode server startup aborted before readiness.${c()}`);t.signal?.addEventListener("abort",h,{once:!0});try{let S=Date.now();for(;Date.now()-S<a;){if(t.signal?.aborted)throw await jt(d),new Error(`OpenCode server startup aborted before readiness.${c()}`);if(p)throw new Error(`OpenCode server failed to start: ${p.message}${c()}`);if(d.exitCode!==null)throw new Error(`OpenCode server exited before readiness.${c()}`);try{if(await qm({baseUrl:l,fetchImpl:i,requestTimeoutMs:s,startupSignal:t.signal,timeoutMessage:`OpenCode GET /api/health timed out after ${s}ms during server readiness.${c()}`,abortMessage:`OpenCode server startup aborted before readiness.${c()}`}))return{baseUrl:l,close:async()=>{await jt(d)}}}catch{if(t.signal?.aborted)throw await jt(d),new Error(`OpenCode server startup aborted before readiness.${c()}`)}await md(100)}throw await jt(d),new Error(`Timed out waiting for OpenCode server readiness.${c()}`)}finally{t.signal?.removeEventListener("abort",h)}})}async function Bm(t){for(let e=1;;e+=1)try{return await Fm(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(Gt(n)))throw n}}async function qm(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await Sr(t.fetchImpl(`${t.baseUrl}/api/health`,{headers:Bi(),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 Um(t){let e=ie(t)&&ie(t.payload)?t.payload:t;return ie(e)?e.type==="sync"?{type:typeof e.name=="string"?e.name.replace(/\.\d+$/,""):void 0,properties:ie(e.data)?e.data:{}}:{type:typeof e.type=="string"?e.type:void 0,properties:ie(e.properties)?e.properties:e}:{properties:{}}}function Km(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function Vm(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 jm(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=Ft(t),o=ir(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?qe(a,s??0,i.length):n,options:d,...i.length>0?{questions:i}:{},...s!=null?{activeQuestionIndex:s}:{},allowsFreeText:!0}}function Gm(t,e,n){let r=t.questions??[],o=r[e],i=o?.options.map(s=>s.label)??[];return{...t,promptText:o?qe(o,e,r.length):t.promptText,options:i,activeQuestionIndex:e,answers:n}}function Hm(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 Kp(t){return Ri(t).result}function Ri(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 gp,hp,Ai,yp,kp,wi,Ma,bi,ar,Da=z(()=>{pn();Jn();gp="OPENCLAW_OPENCODE_COMMAND",hp=15e3,Ai=6e4,yp=15*6e4,kp=["edit","bash","task","todowrite","external_directory"];wi=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};Ma=Promise.resolve();bi=class{constructor(e,n,r=Ai){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 sr(this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:{...vi(),...r===void 0?{}:{"content-type":"application/json"}},body:r===void 0?void 0:JSON.stringify(r),signal:i.signal}),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!p.ok){let h=await sr(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}}).catch(()=>"");throw new wi(e,n,p.status,Pi(h))}if(p.status===204)return;let f=await sr(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!f)return;let m=Ip(p);if(!m.includes("application/json")&&!m.includes("+json"))throw new Error(Tp(e,n,m,f));try{return JSON.parse(f)}catch(h){let k=Pi(f);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${Dt(h)}${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:vi(),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)}};ar=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 Ye,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,h,k=!1,S=!1,b=!1,A=!1,M=!1,R=!1,y,w=new Set,T=_=>A?!1:(A=!0,n.enqueue(Be(_)),!0),K=(_,I,D)=>T({success:_,outcome:I,duration_ms:0,total_cost_usd:0,num_turns:d,result:D,session_id:a??""}),E=()=>{a&&y!==a&&(y=a,n.enqueue(Tt({kind:"opencode-server",conversationId:a})))},C=_=>{_&&w.has(_)||(_&&w.add(_),n.enqueue(Ze(_)),_&&u?.requestId===_&&(u=void 0))},x=async()=>{if(i)return i;s??=(async()=>{let _=await(this.deps.createServer??Dp)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(M||e.abortController?.signal.aborted)throw await _.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=_,i=new bi(_.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(_){throw s=void 0,_}},$=async(_,I)=>{!i||!a||await i.request("POST",`/permission/${encodeURIComponent(_)}/reply`,{reply:I})},q=async(_,I)=>{!i||!a||await i.request("POST",`/question/${encodeURIComponent(_)}/reply`,{answers:[[I]]})},L=async _=>{let I=Wp(_),D=Np(I.properties);if(!(D&&D!==a)){if((I.type==="session.next.text.delta"||I.type==="message.part.delta")&&I.properties.field!=="reasoning"&&typeof I.properties.delta=="string"){n.enqueue(dt(I.properties.delta));return}if(I.type==="session.next.tool.called"||I.type==="message.part.updated"){let B=oe(I.properties.part)?I.properties.part:void 0;if(I.type==="message.part.updated"&&B?.type!=="tool"){n.enqueue({type:"activity"});return}let ne=typeof I.properties.tool=="string"?I.properties.tool:typeof B?.tool=="string"?B.tool:"tool";n.enqueue(zn(ne,I.properties.input));return}if(I.type==="session.next.step.failed"||I.type==="session.error"){let B=oe(I.properties.error)&&typeof I.properties.error.message=="string"?I.properties.error.message:`${I.type} failed`;S&&!b&&(h?.abort(),K(!1,"failed",B));return}if(I.type==="permission.asked"){if(l==="bypassPermissions"){let ne=typeof I.properties.id=="string"?I.properties.id:void 0;ne&&(await $(ne,"once").catch(()=>{}),C(ne));return}let B=Lp(I.properties);u={requestId:B.requestId,kind:"approval",options:B.options,actions:B.actions??[],state:B},n.enqueue(_e(B));return}if(I.type==="permission.replied"){let B=typeof I.properties.requestID=="string"?I.properties.requestID:void 0;C(B);return}if(I.type==="question.asked"){let B=Bp(I.properties);u={requestId:B.requestId,kind:"question",options:B.options,actions:[],state:B},n.enqueue(_e(B));return}if(I.type==="question.replied"||I.type==="question.rejected"){let B=typeof I.properties.requestID=="string"?I.properties.requestID:void 0;C(B);return}(I.type?.startsWith("session.next.")||I.type?.startsWith("message.")||I.type==="session.status"||I.type==="session.idle")&&(_p(I)&&(R=!0),n.enqueue({type:"activity"}))}},G=()=>{k||!i||(k=!0,i.streamEvents(L,m.signal).catch(_=>{!m.signal.aborted&&S&&!b&&(h?.abort(),K(!1,"failed",Dt(_)))}).finally(()=>{k=!1}))},se=async(_,I)=>await _.request("GET",`/session/${encodeURIComponent(I)}/message`),Ie=async(_,I,D,B,ne)=>{await _.request("POST",`/session/${encodeURIComponent(I)}/prompt_async`,Cp(D,e.model,B),{signal:ne})},wt=async(_,I,D,B)=>{let ne=Date.now(),Me=!1,he=D,He,Pt=0,ze,Hs=this.deps.turnTimeoutMs??yp;for(;;){if(B.aborted)throw new Error("wait aborted");let pc=await se(_,I).catch(()=>{}),Qe=Ri(pc),zs=Qe.count>D&&!!Qe.result;zs&&Qe.count===he&&Qe.result===He?Pt+=1:(Pt=zs?1:0,he=Qe.count,He=Qe.result);let oi=!1;try{let on=await _.request("GET","/session/status",void 0,{signal:B,timeoutMs:Math.min(this.deps.requestTimeoutMs??Ai,1e4)});oi=Mp(on,I),ze=void 0,oi||(Me=!0)}catch(on){if(B.aborted)throw new Error("wait aborted");ze=Dt(on)}if(oi&&(Me||Qe.count>D)||R&&Qe.count>D||Pt>=2&&ze)return;if(Date.now()-ne>Hs){let on=ze?` Last status error: ${ze}`:"";throw new Error(`Timed out waiting for OpenCode session ${I} to become idle after ${Hs}ms.${on}`)}await Ea(250)}},nn=async()=>{let _=await x();if(a){if(e.forkSession&&!p){let B=await _.request("POST",`/session/${encodeURIComponent(a)}/fork`,{});if(!B.id)throw new Error("OpenCode fork did not return a session id.");a=B.id,p=!0,c=!0}else c||(await se(_,a),c=!0);return E(),G(),a}let I=Rp(e.model),D=await _.request("POST","/session",{...I?{model:I}:{},metadata:{client:"openclaw-code-agent"},permission:Ca(l)});if(!D.id)throw new Error("OpenCode did not return a session id.");return a=D.id,c=!0,E(),G(),a},rn=async(_,I,D=_?"completed":"failed")=>{let B=I;if(_&&i&&a){let ne=await se(i,a).catch(()=>{});B=B??Kp(ne)}K(_,D,B)},uc=async _=>{S=!0,b=!1,A=!1,R=!1;try{let I=await x();if(M)return;let D=await nn();if(M)return;n.enqueue(Ct()),d+=1;let B=f?void 0:e.systemPrompt,ne=await se(I,D).catch(()=>{}),Me=Ri(ne).count,he=new AbortController;h=he,await Ie(I,D,_,B,he.signal),f=!0,await wt(I,D,Me,he.signal),h=void 0,b=!0,await rn(!0)}catch(I){h=void 0,await rn(!1,Dt(I))}finally{S=!1,b=!1}},ri=async(_,I={})=>{let D=u;if(!D||D.kind!=="question"||I.requestId&&I.requestId!==D.requestId)return!1;let B=_.trim();if(!B)return!1;let ne=D.state?.questions??[];if(ne.length>0){let Me=D.state?.activeQuestionIndex??0,he=ne[Me];if(!he||I.questionId&&I.questionId!==he.id)return!1;D.answers={...D.answers,[he.id]:{answers:[B]}};let He=Me+1;return He<ne.length?(D.state=Fp(D.state,He,D.answers),D.options=D.state.options,n.enqueue(_e(D.state)),!0):(await q(D.requestId,qp(ne,D.answers)),C(D.requestId),!0)}return await q(D.requestId,B),C(D.requestId),!0},cc=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{for await(let _ of cc){if(M)break;let I=bp(_).trim();if(I){if(u?.kind==="question"){await ri(I);continue}if(await uc(I),M)break}}}catch(_){M||(S||(A=!1),K(!1,"failed",Dt(_)))}finally{m.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(_){a&&await(await x()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:Ca(_)}),l=_,n.enqueue(Mt(_))},async submitPendingInputOption(_,I={}){let D=u;if(!D||I.requestId&&I.requestId!==D.requestId)return!1;if(D.kind==="approval"){let Pt=D.actions[_],ze=Pt?.kind==="approval"?Pt.responseDecision:void 0;return ze?(await $(D.requestId,ze),C(D.requestId),!0):!1}let B=D.state?.questions??[],ne=D.state?.activeQuestionIndex??0,Me=B[ne];if(I.questionId&&I.questionId!==Me?.id)return!1;let he=Me?.options[_],He=he?.value??he?.label??D.options[_];return He?await ri(He,I):!1},async submitPendingInputText(_){return await ri(_)},async interrupt(){if(M=!0,m.abort(),h?.abort(),S||(A=!1),K(!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 xi(t){Ii.set(t.name,t)}function yn(t){let e=Ii.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...Ii.keys()].join(", ")}`);return e}function Oa(){return yn(ue())}var Ii,Ti=z(()=>{ia();Ta();Da();ae();Ii=new Map;xi(new Yn);xi(new ir);xi(new ar)});function O(t){return t.backendRef?.conversationId??t.harnessSessionId}function j(t){return t.id??t.sessionId??t.name??O(t)??t.harnessSessionId}function Up(t){return t.harnessSessionId}function fe(t){let e=[j(t),O(t),Up(t)].filter(n=>!!n);return[...new Set(e)]}function Ci(t){return t.harnessName??t.persistedHarness??ue()}function kn(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return yn(Ci(t)).capabilities.worktrees}catch{return"plugin-managed"}}function Mi(t){return t==="native-execution"}function dr(t){return t==="native-restore"}function Vp(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function ce(t){let e=kn(t);return(Mi(e)||dr(e))&&Vp(t)}var ee=z(()=>{ae();Ti()});import{execFileSync as ie}from"child_process";import*as Ar from"fs";import{tmpdir as bm}from"os";import{dirname as id,join as Rm}from"path";function Am(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 Ir(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(W.worktreeDir)return W.worktreeDir;if(t){let e=Am(t);if(e)return Rm(e,".worktrees")}return bm()}function sd(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100).replace(/[-.]+$/,"")||"session"}function xr(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")?id(e):void 0}catch{return}}function Im(){if(br!==void 0)return br;try{return ie("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),br=!0,!0}catch{return br=!1,!1}}function we(){if(Rr!==void 0)return Rr;try{return ie("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Rr=!0,!0}catch{return Rr=!1,!1}}function Wi(t){if(!Im())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 ad(t){try{let e=Tm(t);if(!e)return`${Ir(t)}`,!0;let n=Ar.statfsSync(e),r=n.bavail*n.bsize;return Cm(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function ct(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 xm(t){let e=t;for(;;){if(Ar.existsSync(e))return e;let n=id(e);if(n===e)return;e=n}}function Tm(t){return xm(Ir(t))}function Cm(t){return t>=104857600}function Ee(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 De(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 Pn(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 dd(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 Te(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 Tr(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 ld(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 br,Rr,Ft=z(()=>{ae()});import{execFileSync as qt}from"child_process";import{randomBytes as Mm}from"crypto";import{appendFileSync as _m,existsSync as pd,mkdirSync as ud,readFileSync as $m,rmSync as Ni}from"fs";import{relative as Em,sep as cd}from"path";function Dm(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function Om(t){try{return qt("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}-${Mm(8).toString("hex")}`}function Nm(t,e){let n=Om(t);if(!n)return;let r=Em(n,e);if(!r||r.startsWith("..")||r.includes(`..${cd}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(cd).join("/").replace(/\/$/,"")}/`;try{let s=pd(o)?$m(o,"utf-8"):"";s.split(/\r?\n/).map(d=>d.trim()).some(d=>d===i||d===`/${i}`)||_m(o,`${s.endsWith(`
12
+ `)}function zm(t){return Vi(t).result}function Vi(t){let e=Array.isArray(t)?t:ie(t)&&Array.isArray(t.messages)?t.messages:ie(t)&&Array.isArray(t.items)?t.items:[],n=[];for(let r of e){let o=ie(r)&&ie(r.info)?r.info:r;if(!ie(o)||(typeof o.role=="string"?o.role:o.type)!=="assistant")continue;let s=Array.isArray(o.content)?o.content:[],a=ie(r)&&Array.isArray(r.parts)?r.parts:[];for(let d of[...s,...a])ie(d)&&d.type==="text"&&typeof d.text=="string"&&n.push(d.text)}return{count:n.length,result:n.at(-1)}}var wm,Pm,ji,bm,Rm,qi,ud,Ki,vr,fd=Q(()=>{Sn();lr();wm="OPENCLAW_OPENCODE_COMMAND",Pm=15e3,ji=6e4,bm=15*6e4,Rm=["edit","bash","task","todowrite","external_directory"];qi=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};ud=Promise.resolve();Ki=class{constructor(e,n,r=ji){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.`,m=()=>{s=!0,i.abort()};o.signal?.aborted?(s=!0,i.abort()):o.signal?.addEventListener("abort",m,{once:!0});try{let p=await Sr(this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:{...Bi(),...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 c=await Sr(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}}).catch(()=>"");throw new qi(e,n,p.status,Ui(c))}if(p.status===204)return;let y=await Sr(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!y)return;let f=$m(p);if(!f.includes("application/json")&&!f.includes("+json"))throw new Error(Dm(e,n,f,y));try{return JSON.parse(y)}catch(c){let h=Ui(y);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${Gt(c)}${h?`: ${h}`:""}`)}}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",m)}}async streamEvents(e,n){let r=await this.fetchImpl(`${this.baseUrl}/event`,{headers:Bi(),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(m=>m.startsWith("data:")).map(m=>m.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 m=/\r?\n\r?\n/.exec(s);for(;m;){let p=s.slice(0,m.index);s=s.slice(m.index+m[0].length),await a(p),m=/\r?\n\r?\n/.exec(s)}}let d=s.trim();d&&await a(d)}};vr=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 ot,r=this.deps.fetch??fetch,o,i,s,a=e.resumeSessionId,d=0,l=e.permissionMode??"default",u,m=!e.resumeSessionId,p=!1,y=!1,f=new AbortController,c,h=!1,S=!1,b=!1,A=!1,x=!1,R=!1,k,P=new Set,_=E=>A?!1:(A=!0,n.enqueue(Ue(E)),!0),M=(E,I,W)=>_({success:E,outcome:I,duration_ms:0,total_cost_usd:0,num_turns:d,result:W,session_id:a??""}),$=()=>{a&&k!==a&&(k=a,n.enqueue(Bt({kind:"opencode-server",conversationId:a})))},T=E=>{E&&P.has(E)||(E&&P.add(E),n.enqueue(it(E)),E&&u?.requestId===E&&(u=void 0))},C=async()=>{if(i)return i;s??=(async()=>{let E=await(this.deps.createServer??Bm)({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 E.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=E,i=new Ki(E.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(E){throw s=void 0,E}},N=async(E,I)=>{!i||!a||await i.request("POST",`/permission/${encodeURIComponent(E)}/reply`,{reply:I})},B=async(E,I)=>{!i||!a||await i.request("POST",`/question/${encodeURIComponent(E)}/reply`,{answers:[[I]]})},D=async E=>{let I=Um(E),W=Km(I.properties);if(!(W&&W!==a)){if((I.type==="session.next.text.delta"||I.type==="message.part.delta")&&I.properties.field!=="reasoning"&&typeof I.properties.delta=="string"){n.enqueue(ht(I.properties.delta));return}if(I.type==="session.next.tool.called"||I.type==="message.part.updated"){let q=ie(I.properties.part)?I.properties.part:void 0;if(I.type==="message.part.updated"&&q?.type!=="tool"){n.enqueue({type:"activity"});return}let ne=typeof I.properties.tool=="string"?I.properties.tool:typeof q?.tool=="string"?q.tool:"tool";n.enqueue(ar(ne,I.properties.input));return}if(I.type==="session.next.step.failed"||I.type==="session.error"){let q=ie(I.properties.error)&&typeof I.properties.error.message=="string"?I.properties.error.message:`${I.type} failed`;S&&!b&&(c?.abort(),M(!1,"failed",q));return}if(I.type==="permission.asked"){if(l==="bypassPermissions"){let ne=typeof I.properties.id=="string"?I.properties.id:void 0;ne&&(await N(ne,"once").catch(()=>{}),T(ne));return}let q=Vm(I.properties);u={requestId:q.requestId,kind:"approval",options:q.options,actions:q.actions??[],state:q},n.enqueue(Oe(q));return}if(I.type==="permission.replied"){let q=typeof I.properties.requestID=="string"?I.properties.requestID:void 0;T(q);return}if(I.type==="question.asked"){let q=jm(I.properties);u={requestId:q.requestId,kind:"question",options:q.options,actions:[],state:q},n.enqueue(Oe(q));return}if(I.type==="question.replied"||I.type==="question.rejected"){let q=typeof I.properties.requestID=="string"?I.properties.requestID:void 0;T(q);return}(I.type?.startsWith("session.next.")||I.type?.startsWith("message.")||I.type==="session.status"||I.type==="session.idle")&&(Wm(I)&&(R=!0),n.enqueue({type:"activity"}))}},V=()=>{h||!i||(h=!0,i.streamEvents(D,f.signal).catch(E=>{!f.signal.aborted&&S&&!b&&(c?.abort(),M(!1,"failed",Gt(E)))}).finally(()=>{h=!1}))},ae=async(E,I)=>await E.request("GET",`/session/${encodeURIComponent(I)}/message`),xe=async(E,I,W,q,ne)=>{await E.request("POST",`/session/${encodeURIComponent(I)}/prompt_async`,Om(W,e.model,q),{signal:ne})},Tt=async(E,I,W,q)=>{let ne=Date.now(),$e=!1,ke=W,Ye,Ct=0,Ze,la=this.deps.turnTimeoutMs??bm;for(;;){if(q.aborted)throw new Error("wait aborted");let qc=await ae(E,I).catch(()=>{}),Xe=Vi(qc),ua=Xe.count>W&&!!Xe.result;ua&&Xe.count===ke&&Xe.result===Ye?Ct+=1:(Ct=ua?1:0,ke=Xe.count,Ye=Xe.result);let gi=!1;try{let cn=await E.request("GET","/session/status",void 0,{signal:q,timeoutMs:Math.min(this.deps.requestTimeoutMs??ji,1e4)});gi=Nm(cn,I),Ze=void 0,gi||($e=!0)}catch(cn){if(q.aborted)throw new Error("wait aborted");Ze=Gt(cn)}if(gi&&($e||Xe.count>W)||R&&Xe.count>W||Ct>=2&&Ze)return;if(Date.now()-ne>la){let cn=Ze?` Last status error: ${Ze}`:"";throw new Error(`Timed out waiting for OpenCode session ${I} to become idle after ${la}ms.${cn}`)}await md(250)}},ln=async()=>{let E=await C();if(a){if(e.forkSession&&!p){let q=await E.request("POST",`/session/${encodeURIComponent(a)}/fork`,{});if(!q.id)throw new Error("OpenCode fork did not return a session id.");a=q.id,p=!0,m=!0}else m||(await ae(E,a),m=!0);return $(),V(),a}let I=Mm(e.model),W=await E.request("POST","/session",{...I?{model:I}:{},metadata:{client:"openclaw-code-agent"},permission:ld(l)});if(!W.id)throw new Error("OpenCode did not return a session id.");return a=W.id,m=!0,$(),V(),a},un=async(E,I,W=E?"completed":"failed")=>{let q=I;if(E&&i&&a){let ne=await ae(i,a).catch(()=>{});q=q??zm(ne)}M(E,W,q)},Fc=async E=>{S=!0,b=!1,A=!1,R=!1;try{let I=await C();if(x)return;let W=await ln();if(x)return;n.enqueue(qt()),d+=1;let q=y?void 0:e.systemPrompt,ne=await ae(I,W).catch(()=>{}),$e=Vi(ne).count,ke=new AbortController;c=ke,await xe(I,W,E,q,ke.signal),y=!0,await Tt(I,W,$e,ke.signal),c=void 0,b=!0,await un(!0)}catch(I){c=void 0,await un(!1,Gt(I))}finally{S=!1,b=!1}},fi=async(E,I={})=>{let W=u;if(!W||W.kind!=="question"||I.requestId&&I.requestId!==W.requestId)return!1;let q=E.trim();if(!q)return!1;let ne=W.state?.questions??[];if(ne.length>0){let $e=W.state?.activeQuestionIndex??0,ke=ne[$e];if(!ke||I.questionId&&I.questionId!==ke.id)return!1;W.answers={...W.answers,[ke.id]:{answers:[q]}};let Ye=$e+1;return Ye<ne.length?(W.state=Gm(W.state,Ye,W.answers),W.options=W.state.options,n.enqueue(Oe(W.state)),!0):(await B(W.requestId,Hm(ne,W.answers)),T(W.requestId),!0)}return await B(W.requestId,q),T(W.requestId),!0},Bc=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{for await(let E of Bc){if(x)break;let I=Cm(E).trim();if(I){if(u?.kind==="question"){await fi(I);continue}if(await Fc(I),x)break}}}catch(E){x||(S||(A=!1),M(!1,"failed",Gt(E)))}finally{f.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(E){a&&await(await C()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:ld(E)}),l=E,n.enqueue(Ut(E))},async submitPendingInputOption(E,I={}){let W=u;if(!W||I.requestId&&I.requestId!==W.requestId)return!1;if(W.kind==="approval"){let Ct=W.actions[E],Ze=Ct?.kind==="approval"?Ct.responseDecision:void 0;return Ze?(await N(W.requestId,Ze),T(W.requestId),!0):!1}let q=W.state?.questions??[],ne=W.state?.activeQuestionIndex??0,$e=q[ne];if(I.questionId&&I.questionId!==$e?.id)return!1;let ke=$e?.options[E],Ye=ke?.value??ke?.label??W.options[E];return Ye?await fi(Ye,I):!1},async submitPendingInputText(E){return await fi(E)},async interrupt(){if(x=!0,f.abort(),c?.abort(),S||(A=!1),M(!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 Hi(t){Gi.set(t.name,t)}function Rn(t){let e=Gi.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...Gi.keys()].join(", ")}`);return e}function gd(){return Rn(ue())}var Gi,zi=Q(()=>{Fa();dd();fd();oe();Gi=new Map;Hi(new ur);Hi(new kr);Hi(new vr)});function F(t){return t.backendRef?.conversationId??t.harnessSessionId}function G(t){return t.id??t.sessionId??t.name??F(t)??t.harnessSessionId}function Qm(t){return t.harnessSessionId}function ce(t){let e=[G(t),F(t),Qm(t)].filter(n=>!!n);return[...new Set(e)]}function Qi(t){return t.harnessName??t.persistedHarness??ue()}function An(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return Rn(Qi(t)).capabilities.worktrees}catch{return"plugin-managed"}}function Ji(t){return t==="native-execution"}function wr(t){return t==="native-restore"}function Jm(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function pe(t){let e=An(t);return(Ji(e)||wr(e))&&Jm(t)}var ee=Q(()=>{oe();zi()});import{execFileSync as se}from"child_process";import*as Lr from"fs";import{tmpdir as Mf}from"os";import{dirname as Wd,join as _f}from"path";function $f(t){try{return se("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Fr(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(L.worktreeDir)return L.worktreeDir;if(t){let e=$f(t);if(e)return _f(e,".worktrees")}return Mf()}function Ld(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=se("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")?Wd(e):void 0}catch{return}}function Ef(){if(Nr!==void 0)return Nr;try{return se("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Nr=!0,!0}catch{return Nr=!1,!1}}function ge(){if(Wr!==void 0)return Wr;try{return se("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Wr=!0,!0}catch{return Wr=!1,!1}}function ts(t){if(!Ef())return!1;try{return se("git",["rev-parse","--git-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Fd(t){try{let e=Of(t);if(!e)return`${Fr(t)}`,!0;let n=Lr.statfsSync(e),r=n.bavail*n.bsize;return Nf(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function kt(t,e){try{return se("git",["-C",t,"rev-parse","--verify",e],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Df(t){let e=t;for(;;){if(Lr.existsSync(e))return e;let n=Wd(e);if(n===e)return;e=n}}function Of(t){return Df(Fr(t))}function Nf(t){return t>=104857600}function We(t){let e=process.env.OPENCLAW_WORKTREE_BASE_BRANCH?.trim();if(e)return e;try{let r=se("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 se("git",["-C",t,"rev-parse","--verify","main"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"main"}catch{}try{return se("git",["-C",t,"rev-parse","--verify","master"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"master"}catch{return"main"}}function Ce(t){try{let n=se("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 Tn(t,e,n){try{let r=se("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 Bd(t,e,n){try{let r=se("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 Me(t,e,n){try{return se("git",["-C",t,"merge-base","--is-ancestor",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function qr(t,e,n){try{let r=se("git",["-C",t,"merge-tree","--write-tree",n,e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),o=se("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 Se(t,e){try{return se("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 qd(t,e){if(e)return e;let n;try{n=se("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}try{let r=se("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 Nr,Wr,zt=Q(()=>{oe()});import{execFileSync as Qt}from"child_process";import{randomBytes as Wf}from"crypto";import{appendFileSync as Lf,existsSync as Vd,mkdirSync as Ud,readFileSync as Ff,rmSync as ns}from"fs";import{relative as Bf,sep as Kd}from"path";function qf(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function Uf(t){try{return Qt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Kf(t){return t===0?"":`-${t}-${Wf(8).toString("hex")}`}function Vf(t,e){let n=Uf(t);if(!n)return;let r=Bf(n,e);if(!r||r.startsWith("..")||r.includes(`..${Kd}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(Kd).join("/").replace(/\/$/,"")}/`;try{let s=Vd(o)?Ff(o,"utf-8"):"";s.split(/\r?\n/).map(d=>d.trim()).some(d=>d===i||d===`/${i}`)||Lf(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 Li(t,e,n={}){let r=sd(e),o=Ir(t);Nm(t,o),ud(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&&ct(t,m))continue;let h=!1;do{h=!1;try{ud(f,{recursive:!1}),s=f,a=m;break}catch(k){if(Dm(k,"EEXIST")){if(i&&c===0&&!l)try{Ni(f,{recursive:!0,force:!0}),l=!0,h=!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(h);if(s&&a)break}if(!s||!a)throw new Error(`Failed to create unique worktree directory and branch after ${d} attempts`);let u=ct(t,a);try{u?qt("git",["-C",t,"worktree","add",s,a],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):qt("git",["-C",t,"worktree","add","-b",a,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{Ni(s,{recursive:!0,force:!0})}catch{}throw c}return s}function pt(t){if(!pd(t))return[];try{let e=qt("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 mt(t){return pt(t).length>0}function me(t,e,n={}){let r=n.destructive===!0,o=pt(e);if(o.length>0&&!r)return`${e}${o[0]}`,!1;try{return qt("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 Ni(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 Cr(t){try{qt("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 Bi=z(()=>{Ft()});import{execFileSync as J}from"child_process";import{existsSync as Lm}from"fs";function Kt(t){return(t.warnings??[]).filter(e=>!(t.stashPopConflict&&e.startsWith("Failed to pop auto-stash after merge"))).map(e=>`Recovery warning: ${e}`)}function Oe(t,e){let n=Kt(e);return n.length===0?t:`${t}
16
+ `,"utf-8")}catch(s){`${i}${o}${s instanceof Error?s.message:String(s)}`}}function rs(t,e,n={}){let r=Ld(e),o=Fr(t);Vf(t,o),Ud(o,{recursive:!0});let i=n.allowExistingBranch===!0,s,a,d=10,l=!1;for(let m=0;m<d;m++){let p=Kf(m),y=`${o}/openclaw-worktree-${r}${p}`,f=`agent/${r}${p}`;if(!i&&kt(t,f))continue;let c=!1;do{c=!1;try{Ud(y,{recursive:!1}),s=y,a=f;break}catch(h){if(qf(h,"EEXIST")){if(i&&m===0&&!l)try{ns(y,{recursive:!0,force:!0}),l=!0,c=!0}catch(S){throw new Error(`Failed to recreate existing worktree branch ${f}: could not clear blocked path ${y}: ${S instanceof Error?S.message:String(S)}`)}else if(i&&m===0)throw new Error(`Failed to recreate existing worktree branch ${f}: path ${y} remains blocked after one cleanup attempt`);continue}throw h}}while(c);if(s&&a)break}if(!s||!a)throw new Error(`Failed to create unique worktree directory and branch after ${d} attempts`);let u=kt(t,a);try{u?Qt("git",["-C",t,"worktree","add",s,a],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):Qt("git",["-C",t,"worktree","add","-b",a,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){try{ns(s,{recursive:!0,force:!0})}catch{}throw m}return s}function St(t){if(!Vd(t))return[];try{let e=Qt("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 vt(t){return St(t).length>0}function fe(t,e,n={}){let r=n.destructive===!0,o=St(e);if(o.length>0&&!r)return`${e}${o[0]}`,!1;try{return Qt("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 ns(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 Ur(t){try{Qt("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 os=Q(()=>{zt()});import{execFileSync as Z}from"child_process";import{existsSync as jf}from"fs";function Jt(t){return(t.warnings??[]).filter(e=>!(t.stashPopConflict&&e.startsWith("Failed to pop auto-stash after merge"))).map(e=>`Recovery warning: ${e}`)}function Le(t,e){let n=Jt(e);return n.length===0?t:`${t}
18
18
  ${n.map(r=>`⚠️ ${r}`).join(`
19
- `)}`}function Mr(t){return t instanceof Error?t.message:String(t)}function Ke(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,M]=S.split("|");return{hash:b||"",message:A||"",author:M||""}});return{commits:o,filesChanged:a,insertions:d,deletions:l,changedFiles:m,commitMessages:k}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function _r(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 md(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 $r(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}: ${Mr(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"]}),md(t)){let h;try{h=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: ${Mr(k)}. Commit or stash changes manually, then retry.`})}if(!h.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(h){m=!0,l("Failed to pop auto-stash after merge",h)}return d({success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:m||void 0})}let c=o&&Lm(o),p=c?o:t;if(c||J("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),md(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(h){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: ${Mr(h)}. 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(h){l("Failed to determine auto-stash ref",h)}}}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:Mr(c),stashed:i||void 0,stashRef:s})}}var fd=z(()=>{});import{execFileSync as Ut}from"child_process";function yd(t){let e=t.toLowerCase();return e==="open"?"open":e==="merged"?"merged":e==="closed"?"closed":"none"}function Bm(t){return t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:""}function gd(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function hd(t,e,n){let r=Ue(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 kd(t){try{return Ut("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function Fm(t,e,n){if(!n)return e;let r=kd(t);return r?`${r}:${e}`:e}function Sd(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",Fm(t,e,i)),r&&o?a.push("--title",r,"--body",o):a.push("--fill-verbose"),{success:!0,prUrl:Ut("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(gd(l))return hd(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:Ut("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 gd(c)?hd(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 Ue(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=Ut("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?kd(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:yd(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 Ve(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=Ut("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim()),s={exists:!0,state:yd(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 vd(t,e,n,r){if(!we())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),Ut("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 ft(t){let e=Bm(t);return t.kind==="merge"?`✅ Merged: ${t.branch} → ${t.base??"main"}${e}`:t.kind==="pr-updated"?`✅ PR updated: ${t.prUrl??""}${e}`:t.targetRepo?`✅ PR opened against ${t.targetRepo}: ${t.prUrl??""}${e}`:`✅ PR opened: ${t.prUrl??""}${e}`}var Fi=z(()=>{Ft()});import{existsSync as qi}from"fs";function wd(){return new Date().toISOString()}function qm(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:wd(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function Km(t){let e=Pd(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&qi(e)?Ee(e):void 0)}function Pd(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function tt(t,e={}){let n=qm(t),r=wd(),o=new Set,i=Pd(t),s=!!(i&&qi(i)),a=!!(t.worktreePath&&qi(t.worktreePath)),d=t.worktreeBranch,l=Km(t),u=!1,c=!1,p=!1,f=!1,m=!1,h,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=ct(i,d),u||o.add("branch_missing")),a&&t.worktreePath&&(c=mt(t.worktreePath),c&&o.add("dirty_worktree_entries")),s&&i&&u&&d&&l){let x=dd(i,d,l);h=x?.ahead,k=x?.behind,p=Te(i,d,l),p?o.add("topology_merged"):(f=Tr(i,d,l),f&&o.add("merge_noop_content_already_on_base"),!f&&(h??0)>0&&o.add("unique_content"));let $=De(i);if(e.includePrSync&&t.worktreePrUrl&&$&&$!==d&&$!==l){let q=Ve(i,t.worktreePrUrl,t.worktreePrTargetRepo??n.targetRepo);m=!!((q.state==="open"||q.state==="merged")&&q.headRefName===$&&q.baseRefName===l&&Te(i,d,$)),m&&(o.delete("unique_content"),o.add(`released_by_branch:${$}`))}}else l||o.add("base_branch_missing");if(e.includePrSync&&s&&i&&d){let x=Ue(i,d,t.worktreePrTargetRepo??n.targetRepo);S=x.state,b=x.url??b,A=x.number??A}S==="open"&&o.add("pr_open"),S==="merged"&&!p&&!f&&o.add("pr_merged_not_reflected_locally");let M=e.includePrSync&&n.state==="pr_open"&&S!=="open";M&&o.add("stale_pr_open");let R;p?R="merged":(f||m)&&(R="released");let y=e.activeSession||c,w=n.state;!y&&R?w=R:M?w="pending_decision":!u&&n.state==="pending_decision"&&(w="cleanup_failed");let T=w==="merged"||w==="released",K=e.activeSession||c||!T&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||S==="open"||o.has("pr_merged_not_reflected_locally"),E=!K&&(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:h,baseAheadCount:k,prState:S,prUrl:b,prNumber:A,reasons:[...o]};return{lifecycle:n,evidence:C,derivedState:w,cleanupSafe:E,preserve:K,reasons:[...o]}}var bn=z(()=>{Ft();Fi();Bi()});var ke=z(()=>{Ft();Bi();fd();Fi();bn()});function Kr(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function Ur(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:Kr(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function Hd(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:Kr(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function jt(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:Kr(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function zd(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:Kr(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 Tn=z(()=>{});function Gt(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?j(n):r?j(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,...r.costUsd!==void 0?{costUsd:r.costUsd}:{},...r.createdAt!==void 0?{createdAt:r.createdAt}:{},...r.completedAt!==void 0?{completedAt:r.completedAt}:{},...r.harness!==void 0?{harnessName:r.harness}:{},...r.model!==void 0?{model:r.model}:{}}:void 0)}}function Cn(t){return[...t.persistedSession?fe(t.persistedSession):[],...t.activeSession?fe(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function Wf(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 Vr(t,e,n={}){let{activeSession:r,persistedSession:o}=Wf(t,e),i=tt({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 jr(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(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(o),harnessSessionId:o.harnessSessionId});return Array.from(r.values())}function Gr(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function ht(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 Hr(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 Mn=z(()=>{ee();bn()});function Jd(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
19
+ `)}`}function Kr(t){return t instanceof Error?t.message:String(t)}function je(t,e,n){try{let r=Z("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10),s=Z("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 m=s.match(/(\d+)\s+insertions?\(/);m&&(d=parseInt(m[1],10));let p=s.match(/(\d+)\s+deletions?\(/);p&&(l=parseInt(p[1],10));let f=Z("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),h=Z("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:f,commitMessages:h}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function Vr(t,e,n="origin"){try{return Z("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 jd(t){try{return Z("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 jr(t,e,n,r="merge",o){let i=!1,s,a=[],d=m=>a.length>0?{...m,warnings:[...a]}:m,l=(m,p)=>{a.push(`${m}: ${Kr(p)}`)},u=m=>{if(i)try{Z("git",["-C",m,"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(Z("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),jd(t)){let c;try{c=Z("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(h){return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Kr(h)}. Commit or stash changes manually, then retry.`})}if(!c.includes("No local changes to save")){i=!0;try{s=Z("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(h){l("Failed to determine auto-stash ref",h)}}}Z("git",["-C",t,"merge","--squash",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Z("git",["-C",t,"commit","-m",`Squash merge ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let f=!1;if(i)try{Z("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){f=!0,l("Failed to pop auto-stash after merge",c)}return d({success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:f||void 0})}let m=o&&jf(o),p=m?o:t;if(m||Z("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),jd(t)){let f;try{f=Z("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{Z("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(h){l(`Failed to check out ${n} after auto-stash failure`,h)}return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Kr(c)}. Commit or stash changes manually, then retry.`})}if(!f.includes("No local changes to save")){i=!0;try{s=Z("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(c){l("Failed to determine auto-stash ref",c)}}}try{Z("git",["-C",p,"rebase",n],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{try{Z("git",["-C",p,"rebase","--abort"],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){l("Failed to abort rebase during recovery",f)}try{Z("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){l(`Failed to check out ${n} during recovery`,f)}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
+ `)})}Z("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Z("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let y=!1;if(i)try{Z("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){y=!0,l("Failed to pop auto-stash after merge",f)}return d({success:!0,fastForward:!0,stashed:i||void 0,stashRef:s,stashPopConflict:y||void 0})}catch(m){try{Z("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:Kr(m),stashed:i||void 0,stashRef:s})}}var Gd=Q(()=>{});import{execFileSync as Ge}from"child_process";function Qd(t){let e=t.toLowerCase();return e==="open"?"open":e==="merged"?"merged":e==="closed"?"closed":"none"}function Gf(t){return t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:""}function Hd(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function zd(t,e,n){let r=He(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 Jd(t){try{return Ge("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function Hf(t,e,n){if(!n)return e;let r=Jd(t);return r?`${r}:${e}`:e}function Yd(t,e,n,r,o,i,s={}){if(!ge())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",Hf(t,e,i)),r&&o?a.push("--title",r,"--body",o):a.push("--fill-verbose"),{success:!0,prUrl:Ge("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(Hd(l))return zd(t,e,i)??{success:!1,error:l};if((s.draft??!0)&&a&&/draft/i.test(l))try{let u=a.filter(y=>y!=="--draft");return{success:!0,prUrl:Ge("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 m=u instanceof Error?u.message:String(u);return Hd(m)?zd(t,e,i)??{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${m}`}:{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${m}`}}return{success:!1,error:l}}}function He(t,e,n){if(!ge())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=Ge("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?Jd(t)?.toLowerCase():void 0,d=s.find(m=>m.headRefName===e&&(!a||m.headRepositoryOwner?.login?.toLowerCase()===a));if(!d)return{exists:!1,state:"none"};let u={exists:!0,state:Qd(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 ze(t,e,n){if(!ge())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=Ge("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim()),s={exists:!0,state:Qd(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 Zd(t,e,n){if(!ge())return{ok:!1,error:"GitHub CLI (gh) is not available"};try{let r=["pr","view",String(e),"--json","body"];n&&r.push("--repo",n);let o=Ge("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim());return{ok:!0,body:typeof i.body=="string"?i.body:void 0}}catch(r){let o=r instanceof Error?r.message:String(r);return`${e}${o}`,{ok:!1,error:o}}}function Xd(t,e,n,r){if(!ge())return!1;try{let o=["pr","edit",String(e),"--body",n];return r&&o.push("--repo",r),Ge("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 el(t,e,n,r){if(!ge())return!1;try{let o=["pr","edit",String(e),"--title",n];return r&&o.push("--repo",r),Ge("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 tl(t,e,n,r){if(!ge())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),Ge("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 wt(t){let e=Gf(t);return t.kind==="merge"?`✅ Merged: ${t.branch} → ${t.base??"main"}${e}`:t.kind==="pr-updated"?`✅ PR updated: ${t.prUrl??""}${e}`:t.targetRepo?`✅ PR opened against ${t.targetRepo}: ${t.prUrl??""}${e}`:`✅ PR opened: ${t.prUrl??""}${e}`}var is=Q(()=>{zt()});import{existsSync as ss}from"fs";function nl(){return new Date().toISOString()}function zf(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:nl(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function Qf(t){let e=rl(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&ss(e)?We(e):void 0)}function rl(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function lt(t,e={}){let n=zf(t),r=nl(),o=new Set,i=rl(t),s=!!(i&&ss(i)),a=!!(t.worktreePath&&ss(t.worktreePath)),d=t.worktreeBranch,l=Qf(t),u=!1,m=!1,p=!1,y=!1,f=!1,c,h,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=kt(i,d),u||o.add("branch_missing")),a&&t.worktreePath&&(m=vt(t.worktreePath),m&&o.add("dirty_worktree_entries")),s&&i&&u&&d&&l){let C=Bd(i,d,l);c=C?.ahead,h=C?.behind,p=Me(i,d,l),p?o.add("topology_merged"):(y=qr(i,d,l),y&&o.add("merge_noop_content_already_on_base"),!y&&(c??0)>0&&o.add("unique_content"));let N=Ce(i);if(e.includePrSync&&t.worktreePrUrl&&N&&N!==d&&N!==l){let B=ze(i,t.worktreePrUrl,t.worktreePrTargetRepo??n.targetRepo);f=!!((B.state==="open"||B.state==="merged")&&B.headRefName===N&&B.baseRefName===l&&Me(i,d,N)),f&&(o.delete("unique_content"),o.add(`released_by_branch:${N}`))}}else l||o.add("base_branch_missing");if(e.includePrSync&&s&&i&&d){let C=He(i,d,t.worktreePrTargetRepo??n.targetRepo);S=C.state,b=C.url??b,A=C.number??A}S==="open"&&o.add("pr_open"),S==="merged"&&!p&&!y&&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":(y||f)&&(R="released");let k=e.activeSession||m,P=n.state;!k&&R?P=R:x?P="pending_decision":!u&&n.state==="pending_decision"&&(P="cleanup_failed");let _=P==="merged"||P==="released",M=e.activeSession||m||!_&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||S==="open"||o.has("pr_merged_not_reflected_locally"),$=!M&&(P==="merged"||P==="released"||n.state==="dismissed"||n.state==="no_change"),T={checkedAt:r,repoExists:s,branchExists:u,worktreeExists:a,activeSession:e.activeSession===!0,dirtyTracked:m,topologyMerged:p,releaseNoopMerge:y,representedByTargetPrBranch:f,branchAheadCount:c,baseAheadCount:h,prState:S,prUrl:b,prNumber:A,reasons:[...o]};return{lifecycle:n,evidence:T,derivedState:P,cleanupSafe:$,preserve:M,reasons:[...o]}}var Cn=Q(()=>{zt();is();os()});var ve=Q(()=>{zt();os();Gd();is();Cn()});function to(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function no(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:to(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function Tl(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:to(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function Zt(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:to(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function Cl(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:to(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 Dn=Q(()=>{});function Xt(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?G(n):r?G(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,...r.costUsd!==void 0?{costUsd:r.costUsd}:{},...r.createdAt!==void 0?{createdAt:r.createdAt}:{},...r.completedAt!==void 0?{completedAt:r.completedAt}:{},...r.harness!==void 0?{harnessName:r.harness}:{},...r.model!==void 0?{model:r.model}:{}}:void 0)}}function On(t){return[...t.persistedSession?ce(t.persistedSession):[],...t.activeSession?ce(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function Ug(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 ro(t,e,n={}){let{activeSession:r,persistedSession:o}=Ug(t,e),i=lt({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 oo(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=F(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:F(o),harnessSessionId:o.harnessSessionId});return Array.from(r.values())}function io(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function bt(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 so(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 Nn=Q(()=>{ee();Cn()});function Ol(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 Ht(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function $n(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 Yr(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 Ff(t){let e=Jd(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=$n(n).replace(/\s+/g," ").trim();return r?Ht(r,180):void 0}function Yd(t){return $n(t.trim()).replace(/\s+/g," ").trim()}function qf(t,e){return t?.commitMessages.map(n=>Yd(n.message)).filter(Boolean).slice(0,e)??[]}function ns(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function Zd(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function Kf(t){let e=Ff(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:qf(n,5),validation:ns(),notes:Zd()}}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 Xd(t,e){let n=Jd(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 _n(t,e,n){let r=t.toLowerCase();return Xd(e,n.objective).some(o=>r.includes(o))}function Qd(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function rs(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)&&!Qd(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)&&!Qd(f)})}function je(t){return $n(t).replace(/\s+/g," ").trim()}function Uf(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=>Yr(a)||_n(a,n,e)))return;let i={title:je(r.title),summary:r.summary.map(je),changes:r.changes.map(je),validation:r.validation.map(je),notes:r.notes.map(je)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(a=>!a||Yr(a)||_n(a,n,e))&&!s.some(a=>rs(a,e)))return i}function Vf(t,e){let n=Ht($n(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),r=Ht(`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=je(f);if(_n(m,e,t)){l=!0;let h=Xd(e,t.objective);for(let k of h){let S=new RegExp(k.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");m=m.replace(S,"[redacted prompt detail]")}m=je(m)}return rs(m,t)&&(u=!0,m="[redacted file reference outside change set]"),m=je(m),(_n(m,e,t)||Yr(m))&&(l=!0,m="[redacted prompt detail]"),m};if(d={title:c(d.title)||Ht(`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=ns()),d.notes.length===0&&(d.notes=Zd()),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=>Yr(f)||_n(f,e,t))||p.some(f=>rs(f,t))){let f=Ht($n(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);d={title:Ht(`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:ns(),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=je(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=Kf({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:Vf(e,t.prompt),evidence:e};try{let n=await t.provider.generatePrMetadata(e),r=Uf(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 Xr(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} ${Yd(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 os=z(()=>{});var rl={};fc(rl,{buildPrCompletionWakeOutcomeKey:()=>as,buildPrMetadata:()=>Zr,buildPrOutcomeDetailLines:()=>ss,formatPrBody:()=>Xr,makeAgentPrTool:()=>En,normalizeForceNewReplacementPrStatus:()=>is,resolveExistingTargetPrUpdateBranch:()=>nl,shouldIgnoreClosedTargetPrForForceNew:()=>tl});import{execFileSync as zt}from"child_process";import{existsSync as jf}from"fs";function Gf(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function tl(t,e){return t===!0&&e?.exists===!0&&e.state!=="open"}function is(t,e,n){return n.forceNewIgnoresClosedTargetPr&&t.exists&&t.state!=="open"&&e?.exists===!0&&(t.url!==void 0&&t.url===e.url||t.number!==void 0&&t.number===e.number)?{exists:!1,state:"none"}:t}function Hf(t,e,n="origin"){let r=`refs/remotes/${n}/${e}`;try{return zt("git",["-C",t,"fetch",n,`${e}:${r}`],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),zt("git",["-C",t,"rev-parse","--verify",r],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r}catch{return}}function zf(t,e){try{let n=zt("git",["-C",t,"worktree","list","--porcelain"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r;for(let o of n.split(/\r?\n/)){if(o.startsWith("worktree ")){r=o.slice(9);continue}if(o===`branch refs/heads/${e}`)return r;o===""&&(r=void 0)}}catch{return}}function el(t,e,n){try{let r=zf(t,e);return r?(zt("git",["-C",r,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1}):(De(t)===e?zt("git",["-C",t,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):zt("git",["-C",t,"branch","-f",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1})}catch(r){return{success:!1,error:`Failed to fast-forward existing PR branch ${e} from ${n}: ${r instanceof Error?r.message:String(r)}`}}}function nl(t){let{repoDir:e,sourceBranch:n,targetPrStatus:r}=t;if(!r.exists||r.state!=="open"||!r.headRefName)return{success:!1,error:"Target PR is not an open PR with a resolvable head branch."};let o=r.headRefName;if(o===n)return{success:!0,branchName:n,alreadyRepresented:!1};let i=Hf(e,o),s=i??o;if(!ct(e,o)&&!i)return{success:!1,error:`Target PR branch ${o} is not available locally. Fetch it before updating the PR.`};if(Te(e,n,s)){if(i&&!Te(e,i,o)){let a=el(e,o,i);if("error"in a)return a}return{success:!0,branchName:o,alreadyRepresented:!0}}return Te(e,s,n)?el(e,o,n):{success:!1,error:`Refusing to create a sibling PR: target PR branch ${o} and follow-up branch ${n} have diverged. Reconcile them manually, then run agent_pr again.`}}function ss(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 as(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 En(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(!Gf(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=Gt(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}=o,{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"}};jf(a)||`${a}${u}${d}`;let c=r.base_branch??Ee(d),p=T=>{let K=zd({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:T.prUrl,prNumber:T.prNumber,baseBranch:c,targetRepo:T.targetRepo,disposition:T.disposition});for(let E of Cn(o))v.updatePersistedSession(E,K)},f=ld(d,r.target_repo??s?.worktreePrTargetRepo),m=s?.worktreePrUrl??i?.worktreePrUrl,h=m?Ve(d,m,f):void 0;if(m&&!h?.exists)return{content:[{type:"text",text:`Error: Session is associated with ${m}, but that PR could not be resolved. Refusing to create a sibling PR from ${u}.`}],meta:{success:!1,state:"error"}};let k=tl(r.force_new,h),S=k?void 0:m,b=k?void 0:h;if(b?.exists&&b.state==="open"){let T=nl({repoDir:d,sourceBranch:u,targetPrStatus:b});if("error"in T)return{content:[{type:"text",text:`Error: ${T.error}`}],meta:{success:!1,state:"error"}};u=T.branchName}let A=v.resolveRepoPolicy(d),M=is(b?.exists?b:Ue(d,u,f),h,{forceNewIgnoresClosedTargetPr:k}),R=M.exists&&M.state==="open";if(A?.policy==="never-pr"&&!R)return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${A.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};if(A&&!A.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${A.identity?.repoRoot??d}. Provider: ${A.provider}.`}],meta:{success:!1,state:"error"}};if((!b||b.state==="open")&&!_r(d,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let w=is(S?Ve(d,S,f):Ue(d,u,f),h,{forceNewIgnoresClosedTargetPr:k});if(r.force_new&&w.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${w.state}).
26
+ `:" ").replace(/[ \t]+/g," ").trim()||void 0}function en(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function Ln(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_-]{${_l},}\\b`,"g"),"[redacted token]")}function co(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_-]{${_l},}\\b`).test(t)}function Gg(t){let e=Ol(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=Ln(n).replace(/\s+/g," ").trim();return r?en(r,180):void 0}function Nl(t){return Ln(t.trim()).replace(/\s+/g," ").trim()}function Hg(t,e){return t?.commitMessages.map(n=>Nl(n.message)).filter(Boolean).slice(0,e)??[]}function Ps(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function Wl(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function zg(t){let e=Gg(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:Hg(n,5),validation:Ps(),notes:Wl()}}function uo(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 Ll(t,e){let n=Ol(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 Wn(t,e,n){let r=t.toLowerCase();return Ll(e,n.objective).some(o=>r.includes(o))}function Ml(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function bs(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 y=p[1],f=p[2]?.toLowerCase();if(f!==void 0&&d.has(f)&&!o.has(y)&&!Ml(y))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 y=p[1],f=p[2]?.toLowerCase();return f!==void 0&&d.has(f)&&!o.has(y)&&!Ml(y)})}function Qe(t){return Ln(t).replace(/\s+/g," ").trim()}function Qg(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||!uo(r.summary,5,180)||!uo(r.changes,10,160)||!uo(r.validation,5,160)||!uo(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(a=>co(a)||Wn(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||co(a)||Wn(a,n,e))&&!s.some(a=>bs(a,e)))return i}function ws(t,e,n={}){let r=en(Ln(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),o=en(`OpenClaw agent changes: ${r}`,90),i=n.reason==="provider-failed"||n.reason==="provider-invalid"?Dl:El,s=[i,`Session: ${r}.`,...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."]],a=t.changedFiles.length>0?t.changedFiles.slice(0,10).map(c=>`\`${c}\``):["Review the pushed worktree branch for the full set of changes."],d=t.changedFiles.length>10?[`...and ${t.changedFiles.length-10} more changed files.`]:[],l=["Fallback metadata is conservative; review the diff and CI/checks before marking the draft PR ready.",...t.notes],u={title:o,summary:s,changes:[...a,...d],validation:t.validation,notes:l},m=!1,p=!1,y=c=>{let h=Qe(c);if(Wn(h,e,t)){m=!0;let S=Ll(e,t.objective);for(let b of S){let A=new RegExp(b.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");h=h.replace(A,"[redacted prompt detail]")}h=Qe(h)}return bs(h,t)&&(p=!0,h="[redacted file reference outside change set]"),h=Qe(h),(Wn(h,e,t)||co(h))&&(m=!0,h="[redacted prompt detail]"),h};if(u={title:y(u.title)||en(`OpenClaw agent changes: ${r}`,90),summary:u.summary.map(y).filter(c=>c&&c.length>0),changes:u.changes.map(y).filter(c=>c&&c.length>0),validation:u.validation.map(y).filter(c=>c&&c.length>0),notes:u.notes.map(y).filter(c=>c&&c.length>0)},u.summary.length===0&&(u.summary=[i]),u.changes.length===0&&(u.changes=["Review the pushed worktree branch for the full set of changes."]),u.validation.length===0&&(u.validation=Ps()),u.notes.length===0&&(u.notes=Wl()),m||p){let c="Some content was stripped from fallback metadata due to safety checks (prompt leak guard or references to files outside the diff).";u.notes.some(h=>h.toLowerCase().includes("stripped")||h.toLowerCase().includes("sanitized"))||(u.notes=[...u.notes,c])}let f=[u.title,...u.summary,...u.changes,...u.validation,...u.notes];if(f.some(c=>!c)||f.some(c=>co(c)||Wn(c,e,t))||f.some(c=>bs(c,t))){let c=en(Ln(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);u={title:en(`OpenClaw agent changes: ${c}`,90),summary:["Deterministic fallback metadata (sanitized for safety)."],changes:t.changedFiles.length>0?t.changedFiles.slice(0,5).map(h=>`\`${h}\``):["See the worktree branch diff for the full set of changes."],validation:Ps(),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 c=Qe(t.branchName);u.notes.some(h=>h.toLowerCase().includes(c.toLowerCase()))||(u.notes=[...u.notes,`Branch: ${c}`])}return u}async function Fn(t){let e=zg({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:ws(e,t.prompt,{reason:"no-provider"}),evidence:e,fallbackReason:"no-provider"};try{let n=await t.provider.generatePrMetadata(e),r=Qg(Zg(n),e,t.prompt);return r?{ok:!0,metadata:r,evidence:e}:{ok:!0,metadata:ws(e,t.prompt,{reason:"provider-invalid"}),evidence:e,fallbackReason:"provider-invalid"}}catch(n){return`${n instanceof Error?n.message:String(n)}`,{ok:!0,metadata:ws(e,t.prompt,{reason:"provider-failed"}),evidence:e,fallbackReason:"provider-failed"}}}function po(){let t=tt(),e=Jg(t);if(e)return{async generatePrMetadata(n){if(typeof e.generatePrMetadata=="function")return await e.generatePrMetadata(n);if(typeof e.generatePullRequestMetadata=="function")return await e.generatePullRequestMetadata(n);let r=Yg(n);if(typeof e.generateObject=="function")return await e.generateObject({task:"openclaw-code-agent.pr-metadata",prompt:r,input:n});if(typeof e.generateText=="function")return await e.generateText({task:"openclaw-code-agent.pr-metadata",prompt:r});if(typeof e.complete=="function")return await e.complete({prompt:r})}}}function Jg(t){return[t?.prMetadata,t?.pullRequestMetadata,t?.llm,t?.ai,t?.model,t?.models].find(n=>!!(n&&typeof n=="object"&&(typeof n.generatePrMetadata=="function"||typeof n.generatePullRequestMetadata=="function"||typeof n.generateObject=="function"||typeof n.generateText=="function"||typeof n.complete=="function")))}function Yg(t){return["Generate concise pull request metadata for OpenClaw Code Agent work.",'Return only JSON with shape {"title":"...","summary":["..."],"changes":["..."],"validation":["..."],"notes":["..."]}.',"Use only the supplied evidence. Do not invent files, commands, tests, risks, links, paths, prompts, chat IDs, credentials, tokens, or secrets.","Keep the title under 90 characters. Keep bullets short and reviewable.","","Evidence:",JSON.stringify(t,null,2)].join(`
27
+ `)}function Zg(t){if(typeof t!="string")return t&&typeof t=="object"&&"object"in t?t.object:t&&typeof t=="object"&&"data"in t?t.data:t;let e=t.trim();if(!e)return;let n=e.replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/,"").trim();try{return JSON.parse(n)}catch{return}}function mo(t){return t?t.includes($l)||t.includes(El)||t.includes(Dl):!1}function fo(t){return t?/^OpenClaw agent changes:/i.test(t.trim()):!1}function Bn(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} ${Nl(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("---",$l),e.join(`
28
+ `)}var _l,$l,El,Dl,Rs=Q(()=>{mt();_l=32,$l="Generated with [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)",El="Deterministic fallback metadata generated because no LLM PR metadata provider is configured.",Dl="Deterministic fallback metadata generated because the LLM PR metadata provider failed or returned unusable output."});var Vl={};Kc(Vl,{buildPrCompletionWakeOutcomeKey:()=>Ts,buildPrMetadata:()=>Fn,buildPrOutcomeDetailLines:()=>xs,createRuntimePrMetadataProvider:()=>po,formatPrBody:()=>Bn,isOcaGeneratedPrBody:()=>mo,isOcaGeneratedPrTitle:()=>fo,makeAgentPrTool:()=>qn,normalizeForceNewReplacementPrStatus:()=>Is,refreshOpenPrMetadata:()=>Kl,resolveExistingTargetPrUpdateBranch:()=>ql,resolveExistingTargetPrUpdateSourceBranch:()=>Ul,shouldIgnoreClosedTargetPrForForceNew:()=>Bl});import{execFileSync as tn}from"child_process";import{existsSync as Xg}from"fs";function eh(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Bl(t,e){return t===!0&&e?.exists===!0&&e.state!=="open"}function Is(t,e,n){return n.forceNewIgnoresClosedTargetPr&&t.exists&&t.state!=="open"&&e?.exists===!0&&(t.url!==void 0&&t.url===e.url||t.number!==void 0&&t.number===e.number)?{exists:!1,state:"none"}:t}function th(t,e,n="origin"){let r=`refs/remotes/${n}/${e}`;try{return tn("git",["-C",t,"fetch",n,`${e}:${r}`],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),tn("git",["-C",t,"rev-parse","--verify",r],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r}catch{return}}function nh(t,e){try{let n=tn("git",["-C",t,"worktree","list","--porcelain"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r;for(let o of n.split(/\r?\n/)){if(o.startsWith("worktree ")){r=o.slice(9);continue}if(o===`branch refs/heads/${e}`)return r;o===""&&(r=void 0)}}catch{return}}function Fl(t,e,n){try{let r=nh(t,e);return r?(tn("git",["-C",r,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1}):(Ce(t)===e?tn("git",["-C",t,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):tn("git",["-C",t,"branch","-f",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1})}catch(r){return{success:!1,error:`Failed to fast-forward existing PR branch ${e} from ${n}: ${r instanceof Error?r.message:String(r)}`}}}function ql(t){let{repoDir:e,sourceBranch:n,targetPrStatus:r}=t;if(!r.exists||r.state!=="open"||!r.headRefName)return{success:!1,error:"Target PR is not an open PR with a resolvable head branch."};let o=r.headRefName;if(o===n)return{success:!0,branchName:n,alreadyRepresented:!1};let i=th(e,o),s=i??o;if(!kt(e,o)&&!i)return{success:!1,error:`Target PR branch ${o} is not available locally. Fetch it before updating the PR.`};if(Me(e,n,s)){if(i&&!Me(e,i,o)){let a=Fl(e,o,i);if("error"in a)return a}return{success:!0,branchName:o,alreadyRepresented:!0}}return Me(e,s,n)?Fl(e,o,n):{success:!1,error:`Refusing to create a sibling PR: target PR branch ${o} and follow-up branch ${n} have diverged. Reconcile them manually, then run agent_pr again.`}}function Ul(t){let e=t.targetPrStatus.headRefName;if(!e||e===t.fallbackBranch)return t.fallbackBranch;let n=Ce(t.repoDir);return n===e?n:t.fallbackBranch}function xs(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 Ts(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(":")}async function Kl(t){let e=t.prStatus.number??t.prStatus.url;if(!e)return{status:"skipped",reason:"missing-pr-identity"};let n=t.operations?.getBody??Zd,r=t.operations?.updateBody??Xd,o=t.operations?.updateTitle??el;if(t.explicitTitle!==void 0||t.explicitBody!==void 0){let y=t.explicitTitle===void 0?!1:o(t.repoDir,e,t.explicitTitle,t.targetRepo);if(t.explicitTitle!==void 0&&!y)return{status:"failed",reason:"failed to update explicit PR title"};let f=t.explicitBody===void 0?!1:r(t.repoDir,e,t.explicitBody,t.targetRepo);return t.explicitBody!==void 0&&!f?{status:"failed",reason:"failed to update explicit PR body"}:{status:"updated",updatedTitle:y,updatedBody:f,reason:"explicit"}}let i=n(t.repoDir,e,t.targetRepo);if(i.ok===!1)return{status:"failed",reason:`failed to read PR body: ${i.error}`};let s=i.body??"";if(s.trim()===""&&!t.forceRefresh)return{status:"skipped",reason:"empty-body"};if(!(t.forceRefresh||mo(s)))return{status:"skipped",reason:"human-edited"};let d=await Fn({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,diffSummary:t.diffSummary,provider:t.metadataProvider});if(d.ok===!1)return{status:"failed",reason:d.error};if(d.fallbackReason!==void 0)return{status:"failed",reason:"generated PR metadata was unavailable; preserved existing generated PR metadata"};let l=Bn({sessionName:t.sessionName,metadata:d.metadata,diffSummary:t.diffSummary}),u=t.forceRefresh||fo(t.prStatus.title),m=!1;if(u&&t.prStatus.title?.trim()!==d.metadata.title.trim()&&(m=o(t.repoDir,e,d.metadata.title,t.targetRepo),!m))return{status:"failed",reason:"failed to update generated PR title"};if(l.trim()===s.trim())return m?{status:"updated",updatedTitle:m,updatedBody:!1,reason:t.forceRefresh?"forced":"generated"}:{status:"skipped",reason:"unchanged"};let p=r(t.repoDir,e,l,t.targetRepo);return p?{status:"updated",updatedTitle:m,updatedBody:p,reason:t.forceRefresh?"forced":"generated"}:{status:"failed",reason:"failed to update generated PR body"}}function As(t){if(t.status==="updated"){if(t.updatedTitle&&t.updatedBody)return t.reason==="explicit"?"📝 Replaced PR title/body with explicitly provided metadata.":"📝 Refreshed PR title/body from current OpenClaw metadata.";if(t.updatedTitle)return t.reason==="explicit"?"📝 Replaced PR title with the explicitly provided title.":"📝 Refreshed PR title from current OpenClaw metadata.";if(t.updatedBody)return t.reason==="explicit"?"📝 Replaced PR body with the explicitly provided body.":"📝 Refreshed PR body from current OpenClaw metadata."}if(t.status==="failed")return`⚠️ PR metadata refresh failed: ${t.reason}`}function qn(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). For existing open PRs, passing body explicitly replaces the PR body."})),update_body:g.Optional(g.Boolean({description:"For existing open PRs, refresh generated PR metadata when true. Alias for update_metadata; retained for compatibility."})),update_metadata:g.Optional(g.Boolean({description:"For existing open PRs, refresh title/body when true. Default: only refresh bodies clearly generated by OpenClaw and titles that are fallback-generated, or explicit title/body values."})),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(!eh(r))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, title?, body?, update_body?, update_metadata?, base_branch?, force_new? }."}],meta:{success:!1,state:"error"}};if(!ge())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=Xt(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}=o,{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"}};Xg(a)||`${a}${u}${d}`;let m=r.base_branch??We(d),p=e.metadataProvider??po(),y=M=>{let $=Cl({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??m,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:M.prUrl,prNumber:M.prNumber,baseBranch:m,targetRepo:M.targetRepo,disposition:M.disposition});for(let T of On(o))v.updatePersistedSession(T,$)},f=qd(d,r.target_repo??s?.worktreePrTargetRepo),c=s?.worktreePrUrl??i?.worktreePrUrl,h=c?ze(d,c,f):void 0;if(c&&!h?.exists)return{content:[{type:"text",text:`Error: Session is associated with ${c}, but that PR could not be resolved. Refusing to create a sibling PR from ${u}.`}],meta:{success:!1,state:"error"}};let S=Bl(r.force_new,h),b=S?void 0:c,A=S?void 0:h;if(A?.exists&&A.state==="open"){let M=Ul({repoDir:d,fallbackBranch:u,targetPrStatus:A}),$=ql({repoDir:d,sourceBranch:M,targetPrStatus:A});if("error"in $)return{content:[{type:"text",text:`Error: ${$.error}`}],meta:{success:!1,state:"error"}};u=$.branchName}let x=v.resolveRepoPolicy(d),R=Is(A?.exists?A:He(d,u,f),h,{forceNewIgnoresClosedTargetPr:S}),k=R.exists&&R.state==="open";if(x?.policy==="never-pr"&&!k)return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${x.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};if(x&&!x.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${x.identity?.repoRoot??d}. Provider: ${x.provider}.`}],meta:{success:!1,state:"error"}};if((!A||A.state==="open")&&!Vr(d,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let _=Is(b?ze(d,b,f):He(d,u,f),h,{forceNewIgnoresClosedTargetPr:S});if(r.force_new&&_.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${_.state}).
28
29
 
29
- Existing PR: ${w.url}
30
+ Existing PR: ${_.url}
30
31
 
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(w.exists&&w.state==="open"){let T=Ke(d,u,c);if(T&&T.commits>0){let K=T.commitMessages.slice(0,5).map($=>`• ${$.hash} ${$.message} (${$.author})`).join(`
32
- `),E=T.commits>5?`
33
- ...and ${T.commits-5} more commits`:"",C=["🔄 **New commits pushed**","",`${T.commits} new commits (+${T.insertions} / -${T.deletions})`,"","### Latest commits:",K+E,"","---","🤖 [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)"].join(`
34
- `);if(vd(d,w.number,C,f)){p({prUrl:w.url,prNumber:w.number,targetRepo:f});let $=ft({kind:"pr-updated",branch:u,prUrl:w.url,filesChanged:T.filesChanged,insertions:T.insertions,deletions:T.deletions});return v.notifyWorktreeOutcome(o.notificationTarget,$,{completionWakeOutcomeKey:as({action:"updated",branchName:u,prUrl:w.url,prNumber:w.number,targetRepo:f,diffSummary:T}),detailLines:ss({action:"updated",branchName:u,baseBranch:c,prUrl:w.url,prNumber:w.number,targetRepo:f,commits:T.commits,insertions:T.insertions,deletions:T.deletions})}),{content:[{type:"text",text:`${$}
32
+ 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(_.exists&&_.state==="open"){let M=je(d,u,m),$=await Kl({repoDir:d,prStatus:_,targetRepo:f,sessionName:l,branchName:u,prompt:o.prompt,diffSummary:M,explicitTitle:r.title,explicitBody:r.body,forceRefresh:r.update_body===!0||r.update_metadata===!0,metadataProvider:p});if(M&&M.commits>0){let T=M.commitMessages.slice(0,5).map(D=>`• ${D.hash} ${D.message} (${D.author})`).join(`
33
+ `),C=M.commits>5?`
34
+ ...and ${M.commits-5} more commits`:"",N=["🔄 **New commits pushed**","",`${M.commits} new commits (+${M.insertions} / -${M.deletions})`,"","### Latest commits:",T+C,"","---","🤖 [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)"].join(`
35
+ `);if(tl(d,_.number,N,f)){y({prUrl:_.url,prNumber:_.number,targetRepo:f});let D=wt({kind:"pr-updated",branch:u,prUrl:_.url,filesChanged:M.filesChanged,insertions:M.insertions,deletions:M.deletions});return v.notifyWorktreeOutcome(o.notificationTarget,D,{completionWakeOutcomeKey:Ts({action:"updated",branchName:u,prUrl:_.url,prNumber:_.number,targetRepo:f,diffSummary:M}),detailLines:xs({action:"updated",branchName:u,baseBranch:m,prUrl:_.url,prNumber:_.number,targetRepo:f,commits:M.commits,insertions:M.insertions,deletions:M.deletions})}),{content:[{type:"text",text:[`${D}`,"",`📝 Added comment detailing ${M.commits} new commits (+${M.insertions} / -${M.deletions})`,As($)].filter(Boolean).join(`
36
+ `)}],meta:{success:!0,state:"pr_updated"}}}else{let D=As($);return{content:[{type:"text",text:`⚠️ Pushed to ${_.url} but failed to add comment.
35
37
 
36
- 📝 Added comment detailing ${T.commits} new commits (+${T.insertions} / -${T.deletions})`}],meta:{success:!0,state:"pr_updated"}}}else return{content:[{type:"text",text:`⚠️ Pushed to ${w.url} but failed to add comment.
38
+ ${M.commits} new commits (+${M.insertions} / -${M.deletions})${D?`
39
+ ${D}`:""}`}],meta:{success:!0,state:"pr_open"}}}}else{y({prUrl:_.url,prNumber:_.number,targetRepo:f});let T=As($);return{content:[{type:"text",text:`ℹ️ PR already exists and is up to date: ${_.url}
37
40
 
38
- ${T.commits} new commits (+${T.insertions} / -${T.deletions})`}],meta:{success:!0,state:"pr_open"}}}else return p({prUrl:w.url,prNumber:w.number,targetRepo:f}),{content:[{type:"text",text:`ℹ️ PR already exists and is up to date: ${w.url}
41
+ No new commits to push.${T?`
42
+ ${T}`:""}`}],meta:{success:!0,state:"pr_open"}}}}else if(_.exists&&_.state==="merged"){let M={...Zt({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??m,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{resolutionSource:"agent_pr",clearResolverSessionId:!0}),worktreePrUrl:_.url,worktreePrNumber:_.number,worktreeDisposition:"merged",worktreeDecisionSnoozedUntil:void 0};for(let $ of On(o))v.updatePersistedSession($,M);return{content:[{type:"text",text:`✅ PR was already merged: ${_.url}
39
43
 
40
- No new commits to push.`}],meta:{success:!0,state:"pr_open"}}}else if(w.exists&&w.state==="merged"){let T={...jt({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{resolutionSource:"agent_pr",clearResolverSessionId:!0}),worktreePrUrl:w.url,worktreePrNumber:w.number,worktreeDisposition:"merged",worktreeDecisionSnoozedUntil:void 0};for(let K of Cn(o))v.updatePersistedSession(K,T);return{content:[{type:"text",text:`✅ PR was already merged: ${w.url}
41
-
42
- The worktree branch ${u} can be cleaned up with agent_merge(delete_branch=true).`}],meta:{success:!0,state:"merged"}}}else{if(w.exists&&w.state==="closed")return{content:[{type:"text",text:`⚠️ A PR exists but was closed without merging: ${w.url}
44
+ The worktree branch ${u} can be cleaned up with agent_merge(delete_branch=true).`}],meta:{success:!0,state:"merged"}}}else{if(_.exists&&_.state==="closed")return{content:[{type:"text",text:`⚠️ A PR exists but was closed without merging: ${_.url}
43
45
 
44
46
  What would you like to do?
45
47
 
@@ -47,230 +49,233 @@ What would you like to do?
47
49
  2. Close and delete the branch with agent_merge(delete_branch=true), then start a new session/worktree
48
50
  3. Manually delete the closed PR on GitHub, then call agent_pr(force_new=true) to create a fresh PR
49
51
 
50
- (This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{if(A?.policy==="never-pr")return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${A.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};let T=!r.title||!r.body?Ke(d,u,c):void 0,K;if(!r.title||!r.body){let $=await Zr({sessionName:l,branchName:u,prompt:o.prompt,diffSummary:T,provider:e.metadataProvider});if($.ok===!1)return{content:[{type:"text",text:`❌ ${$.error}`}],meta:{success:!1,state:"error"}};K=$.metadata}let E=r.title??K.title,C=r.body;C||(C=Xr({sessionName:l,metadata:K,diffSummary:T}));let x=Sd(d,u,c,E,C,f,{draft:!0});if(x.success&&x.prUrl){let $=Ue(d,u,f);p({prUrl:x.prUrl,prNumber:$.number,targetRepo:f,disposition:"pr-opened"});let q=ft({kind:"pr-opened",branch:u,targetRepo:f,prUrl:x.prUrl});return v.notifyWorktreeOutcome(o.notificationTarget,q,{completionWakeOutcomeKey:as({action:"opened",branchName:u,prUrl:x.prUrl,prNumber:$.number,targetRepo:f}),detailLines:ss({action:"opened",branchName:u,baseBranch:c,prUrl:x.prUrl,prNumber:$.number,targetRepo:f})}),{content:[{type:"text",text:x.warnings&&x.warnings.length>0?`${q}
51
-
52
- ⚠️ ${x.warnings.join("; ")}`:q}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${x.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var eo=z(()=>{re();U();ke();os();Tn();Mn();os()});import{readdirSync as Jk,statSync as Yk,rmSync as Zk}from"fs";import{execFileSync as Xk}from"child_process";import{join as lc}from"path";re();U();function yc(t){return t.length>80?`${t.slice(0,80)}...`:t}function kc(t){return t.worktreePath?!t.originalWorkdir||t.originalWorkdir===t.worktreePath?`${t.worktreePath} (worktree)`:`${t.worktreePath} (worktree of ${t.originalWorkdir})`:t.workdir}function Sc(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: ${kc(t)}`,` Model: ${t.model??"default"}`,` Prompt: "${yc(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 Un(t,e){return Sc({...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 It(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 lr(t){return"id"in t?t.id:t.sessionId}function Sn(t){return t.status==="completed"||t.killReason==="done"}function jp(t){return!Sn(t)||!O(t)?!1:t.backendRef?.kind==="codex-app-server"||t.backendRef?.kind==="opencode-server"}function Gp(t){return(t.killReason==="shutdown"||t.killReason==="startup-timeout")&&!O(t)}function vn(t){if(t.status==="running")return{kind:"direct",reason:"already_running"};let e=lr(t);if(Sn(t)&&!jp(t))return{kind:"unavailable",reason:"completed",stableSessionId:e};let n=O(t);if(n){let r="harnessName"in t?void 0:t,{resumeSessionId:o,clearedPersistedCodexResume:i}=It({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 Gp(t)?{kind:"relaunch",stableSessionId:e}:{kind:"unavailable",reason:"missing_backend_state",stableSessionId:e}}ae();nr();import{existsSync as Ba}from"fs";ee();function Wa(t){return t==null?void 0:String(t).trim()||void 0}function Hp(t){return t.trim().replace(/^['"`](.*)['"`]$/s,"$1").trim()}function zp(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=Hp(r?.[2]??"");if(o.startsWith("/")&&Ba(o))return o}}function Na(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&&Wa(t.originThreadId)===Wa(e.originThreadId)}function La(t){return t.slice(0,3).map(e=>` - ${e.name} [${e.ref}] | status=${e.status}${e.lifecycle?` | lifecycle=${e.lifecycle}`:""}`).join(`
55
- `)}function Qp(t,e){let n=[],r=[],o=new Set;for(let i of t.list?.("all")??[]){if(!Na(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||!Na(i,e))continue;let s=j(i)??i.harnessSessionId,a=i.sessionId??O(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 ur(t,e,n){let r=t.workdir||zp(t.prompt)||e.workspaceDir||W.defaultWorkdir||process.cwd();if(!Ba(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=t.harness??ue(),i=bt(o),s=t.model??i,a=Fe(o,s),d=t.model!==void 0,l=Vn(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&&!$t(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&&!er(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=tr(o,a,l),c=jn(e),p=cn(e,c||at(r)),f=e.sessionKey||void 0,m=ta(f)??gi(e);if(!t.resume_session_id&&!t.force_new_session){let y=Qp(n,{workdir:r,originSessionKey:f,originChannel:p,originThreadId:m});if(y.resumable.length>0||y.active.length>0){let w=y.resumable.length>0?["Linked resumable session(s) already exist for this thread/workdir:",La(y.resumable),"","Resume the latest one with:",` agent_respond(session='${y.resumable[0].ref}', message='<next instruction>')`,"Fork from it with:",` agent_launch(prompt='<new task>', resume_session_id='${y.resumable[0].ref}', fork_session=true)`].join(`
56
- `):"",T=y.active.length>0?[y.resumable.length>0?"Linked active session(s):":"Linked active session(s) already exist for this thread/workdir:",La(y.active),"","Send a follow-up instead of launching a duplicate:",` agent_respond(session='${y.active[0].ref}', message='<next instruction>')`].join(`
57
- `):"";return{kind:"blocked",text:["Resume-first protection blocked a fresh launch.","",w,T,["If you intentionally want a brand-new independent session here, call:"," agent_launch(prompt='<new task>', force_new_session=true)"].join(`
52
+ (This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{if(x?.policy==="never-pr")return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${x.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};let M=!r.title||!r.body?je(d,u,m):void 0,$;if(!r.title||!r.body){let B=await Fn({sessionName:l,branchName:u,prompt:o.prompt,diffSummary:M,provider:p});if(B.ok===!1)return{content:[{type:"text",text:`❌ ${B.error}`}],meta:{success:!1,state:"error"}};$=B.metadata}let T=r.title??$.title,C=r.body;C||(C=Bn({sessionName:l,metadata:$,diffSummary:M}));let N=Yd(d,u,m,T,C,f,{draft:!0});if(N.success&&N.prUrl){let B=He(d,u,f);y({prUrl:N.prUrl,prNumber:B.number,targetRepo:f,disposition:"pr-opened"});let D=wt({kind:"pr-opened",branch:u,targetRepo:f,prUrl:N.prUrl});return v.notifyWorktreeOutcome(o.notificationTarget,D,{completionWakeOutcomeKey:Ts({action:"opened",branchName:u,prUrl:N.prUrl,prNumber:B.number,targetRepo:f}),detailLines:xs({action:"opened",branchName:u,baseBranch:m,prUrl:N.prUrl,prNumber:B.number,targetRepo:f})}),{content:[{type:"text",text:N.warnings&&N.warnings.length>0?`${D}
53
+
54
+ ⚠️ ${N.warnings.join("; ")}`:D}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${N.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var go=Q(()=>{re();K();ve();Rs();Dn();Nn();Rs()});import{readdirSync as zS,statSync as QS,rmSync as JS}from"fs";import{execFileSync as YS}from"child_process";import{join as da}from"path";var ca={name:"openclaw-code-agent",version:"4.7.0",type:"module",packageManager:"pnpm@10.30.0",main:"dist/index.js",scripts:{"audit:prod":"pnpm audit --prod",build:"esbuild index.ts --bundle --platform=node --target=node22 --format=esm --outfile=dist/index.js --minify --charset=utf8 --pure:console.log --pure:console.warn --pure:console.info --pure:console.debug --external:@anthropic-ai/claude-agent-sdk --external:openclaw/plugin-sdk/plugin-entry","check-static-guardrails":"node scripts/check-static-guardrails.mjs","check-plugin-security":"node scripts/check-plugin-security.mjs",test:"node scripts/run-tests.mjs","test:integ:crabbox":"node scripts/run-tests.mjs tests/oca-codex-crabbox-integ.test.ts tests/oca-plugin-workflows-integ.test.ts tests/oca-codex-telegram-proof.test.ts tests/oca-codex-proof-app-server.test.ts tests/oca-codex-proof-workflow.test.ts","test:serial":"node scripts/run-tests.mjs","test:file":"node scripts/run-tests.mjs","smoke:backend":"node scripts/run-tests.mjs tests/codex-harness.test.ts tests/plan-mode-e2e.test.ts tests/session-restore-service.test.ts","smoke:backend-parity":"node scripts/run-tests.mjs tests/backend-contract-smoke.test.ts tests/codex-harness.test.ts tests/harness-registry.test.ts","smoke:codex-worktrees":"node scripts/run-tests.mjs tests/codex-harness.test.ts tests/session-bootstrap.test.ts tests/session-restore-service.test.ts","smoke:codex-live":"OPENCLAW_RUN_LIVE_CODEX_SMOKE=1 node scripts/run-tests.mjs tests/live-codex-app-server-smoke.test.ts","proof:codex-doctor":"node --import tsx scripts/e2e/oca-codex-telegram-proof.ts doctor","proof:codex-local":"node --import tsx scripts/e2e/oca-codex-telegram-proof.ts local-smoke","proof:codex-telegram":"node scripts/e2e/run-oca-codex-telegram-proof.mjs","smoke:codex-release":"OPENCLAW_RUN_LIVE_CODEX_RELEASE_SMOKE=1 node scripts/run-tests.mjs tests/live-codex-app-server-smoke.test.ts","smoke:opencode-live":"OPENCLAW_RUN_LIVE_OPENCODE_SMOKE=1 node scripts/run-tests.mjs tests/live-opencode-server-smoke.test.ts",typecheck:"tsc -p tsconfig.typecheck.json --noEmit","validate:release-metadata":"node scripts/validate-release-metadata.mjs",verify:"pnpm check-static-guardrails && pnpm typecheck && pnpm build && pnpm test"},openclaw:{extensions:["./dist/index.js"],install:{npmSpec:"openclaw-code-agent",defaultChoice:"npm",minHostVersion:">=2026.4.21"},compat:{pluginApi:">=2026.4.21",minGatewayVersion:"2026.4.21"},build:{openclawVersion:"2026.6.11",pluginSdkVersion:"2026.6.11"}},files:["dist/","skills/","openclaw.plugin.json","README.md","LICENSE"],dependencies:{"@anthropic-ai/claude-agent-sdk":"^0.3.142"},devDependencies:{"@types/node":"^26.0.1",esbuild:"^0.28.1",nanoid:"^5.1.7",openclaw:"2026.6.11",tsx:"^4.21.0",typescript:"^6.0.2"},keywords:["openclaw","plugin","claude","claude-code","opencode","coding-agent","codex","ai","anthropic","agent","code-generation","automation","cli","background-process","developer-tools"],repository:{type:"git",url:"git+https://github.com/goldmar/openclaw-code-agent.git"},homepage:"https://github.com/goldmar/openclaw-code-agent#readme",bugs:{url:"https://github.com/goldmar/openclaw-code-agent/issues"},license:"MIT",author:"Mark Goldenstein",publishConfig:{access:"public"},description:"An OpenClaw plugin that orchestrates coding agent sessions as managed background processes. Launch, monitor, and control coding agents (Claude Code, Codex, experimental OpenCode, and more) directly from your AI gateway.",peerDependencies:{openclaw:">=2026.4.21"},overrides:{"basic-ftp":"5.3.1","fast-xml-builder@<1.1.7":"1.1.7","ip-address@<10.1.1":"10.1.1"}};import{execFile as vp}from"node:child_process";import{mkdirSync as wp,readFileSync as Pp,renameSync as bp,writeFileSync as Rp}from"node:fs";import{dirname as Ap,join as Ip}from"node:path";import{promisify as xp}from"node:util";import*as wa from"child_process";import{createHash as jc}from"crypto";var te="code-agent";var Gc=new Set(["1","true","yes","on"]);function yi(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&Gc.has(t))}function we(t){if(!(typeof t!="string"||t.length===0))return jc("sha256").update(t).digest("hex").slice(0,12)}function pa(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=pa(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>we(pa(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 fa(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 ga(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 ki(t){let e=ga(t);return{presentationBlockTypes:fa(t),...Y(e)}}function Si(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:fa(n),...ma("interactive",Y(ga(n))),...ma("telegramChannelData",Y(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function ha(t){let e=et(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:hi(e.messageId),chatId:hi(e.chatId),telegramThreadId:hi(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function hi(t){return typeof t=="string"||typeof t=="number"?t:void 0}function ma(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 U(t,e){if(!yi())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:te,...n})}`}mt();var Sa=5e3,Pa=64,Hc={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},zc={execFile:wa.execFile},nt=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},$t=class{constructor(e=zc.execFile){this.execFile=e}execFile;async send(e,n,r){U("direct_send_started",{...Pe(e),messageTextLength:n.length,...Y(r)});try{await this.sendViaRuntime(e,n,r),U("direct_send_succeeded",{...Pe(e),deliveryPath:"runtime",...Y(r)});return}catch(o){if(!(o instanceof nt))throw U("direct_send_failed",{...Pe(e),deliveryPath:"runtime",...Y(r),error:wi(o)}),o;U("direct_send_runtime_capability_missing",{...Pe(e),deliveryPath:"runtime",...Y(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),U("direct_send_succeeded",{...Pe(e),deliveryPath:"cli-fallback",...Y(r)})}}async sendViaRuntime(e,n,r){let o=tt(),i=ka(),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=${Pi(o)})`);if(!o.channel.outbound)throw new nt(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${Pi(o)})`);if(!s)throw new nt(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${Pi(o)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let d=Xn(r);if(U("runtime_adapter_loaded",{...Pe(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...Y(r),...d?ki(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=Jc(i),a={text:o,presentation:i,interactive:s};U("presentation_render_started",{...Pe(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...ki(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=Zc(l,s,r.channel);if(U("presentation_render_completed",{...Pe(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Si(u)}),!u||typeof u!="object"||!e.sendPayload)throw new Error(`OpenClaw outbound adapter for channel "${r.channel}" cannot preserve interactive presentation`);let m=await e.sendPayload({...d,payload:u});U("presentation_send_payload_completed",{...Pe(r),...Si(u),...ha(m)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let a=Qc(e,n,r);U("direct_send_cli_fallback_started",{...Pe(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...Y(r)}),this.execFile("openclaw",a,{timeout:Sa,killSignal:"SIGKILL"},(d,l,u)=>{if(!d){U("direct_send_cli_fallback_completed",{...Pe(e),deliveryPath:"cli-fallback",...Y(r)}),i();return}let m=u?.trim()?` | stderr: ${u.trim()}`:"";U("direct_send_cli_fallback_failed",{...Pe(e),deliveryPath:"cli-fallback",...Y(r),error:wi(d),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${Sa}ms timeout: ${wi(d)}${m}`))})})}};function Pe(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function Qc(t,e,n){let r=Xn(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 wi(t){return t instanceof Error?t.message:String(t)}function Pi(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function Xn(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:op(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function Jc(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 Yc(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 Zc(t,e,n){if(!e)return t;let r=Yc(t)?t:Xc(t,e);return n!=="telegram"?r:ep(r,e)}function Xc(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function ep(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Et(n.channelData),o=Et(r?.telegram),i=np(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=tp(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function tp(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")<=Pa).map(r=>({text:r.label,callback_data:r.value,...ba(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function np(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")>Pa))&&rp(i))return{...i,...ba(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function rp(t){return Zn(t.callback_data)||Zn(t.url)||Yn(t.web_app)||Yn(t.webApp)||Yn(t.login_url)||Yn(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||Et(t.switch_inline_query_chosen_chat)!==void 0||Et(t.callback_game)!==void 0||t.pay===!0||va(t.copy_text)||va(t.copyText)}function Zn(t){return typeof t=="string"&&t.trim().length>0}function Yn(t){let e=Et(t);return Zn(e?.url)}function va(t){let e=Et(t);return Zn(e?.text)}function ba(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=Hc[e];return n?{style:n}:{}}function Et(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function op(t){return t.startsWith(`${te}:`)?t:`${te}:${t}`}oe();he();var Tp=xp(vp),_i="openclaw-code-agent",Cp=`https://registry.npmjs.org/${encodeURIComponent(_i)}/latest`,Mp="openclaw-code-agent-auto-update.json",Da=1440*60*1e3,_p=7*Da,Wt="plugin:auto-update";function Oa(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Ma(t){return t instanceof Error?t.message:String(t)}function gt(t){return t?.trim().replace(/^v/i,"")||void 0}function _a(t){let n=gt(t)?.match(/^(\d+)\.(\d+)\.(\d+)$/);if(!(!n?.[1]||!n[2]||!n[3]))return[Number(n[1]),Number(n[2]),Number(n[3])]}function $p(t,e){let n=_a(t),r=_a(e);if(!n||!r)return!1;for(let o=0;o<3;o+=1){if(n[o]>r[o])return!0;if(n[o]<r[o])return!1}return!1}function Ep(t){if(!Oa(t))return{};let e={};for(let n of["lastCheckedAt","latestVersion","promptedVersion","lastPromptedAt","dismissedVersion","lastDismissedAt","updateInstalledVersion","restartPromptedVersion","lastError"]){let r=t[n];typeof r=="string"&&r.trim()&&(e[n]=r)}return e}function $a(t){if(!(!t?.provider||!t.target||t.provider==="system"||t.target==="system"))return{channel:t.provider,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function Ea(){if(L.fallbackChannel)return Te(L.fallbackChannel)}async function Dp(){let t=await fetch(Cp,{headers:{accept:"application/json"}});if(!t.ok)throw new Error(`npm registry returned HTTP ${t.status}`);let e=await t.json(),n=Oa(e)&&typeof e.version=="string"?gt(e.version):void 0;return n?{version:n}:void 0}async function Op(t,e){let n=await Tp(t,e,{timeout:12e4,maxBuffer:1048576});return{stdout:n.stdout?.toString()??"",stderr:n.stderr?.toString()??""}}var nr=class{constructor(e){this.options=e;this.statePath=Ip(e.stateDir,Mp),this.notifier=e.notifier??new $t,this.fetchLatestRelease=e.fetchLatestRelease??Dp,this.runCommand=e.runCommand??Op,this.now=e.now??Date.now}options;statePath;notifier;fetchLatestRelease;runCommand;now;checkInFlight;maybeCheckForUpdate(e={}){this.checkInFlight||(this.checkInFlight=this.checkForUpdate(e).catch(n=>{`${Ma(n)}`}).finally(()=>{this.checkInFlight=void 0}))}async waitForIdle(){await this.checkInFlight}async installConfirmed(e,n){let r=gt(e);if(!r)return"Could not determine which OCA version to update to.";await this.runCommand("openclaw",["plugins","update",_i]);let o=this.readState();this.writeState({...o,updateInstalledVersion:r});let i=$a(n?.route??Ea());return i?(await this.sendRestartPrompt(i,r),`OCA update command completed for ${r}. Restart confirmation was sent.`):[`OCA update command completed for ${r}.`,"Restart the Gateway explicitly to load it: openclaw gateway restart"].join(`
55
+ `)}async restartConfirmed(e){let n=gt(e);return await this.runCommand("openclaw",["gateway","restart"]),n?`Gateway restart requested for OCA ${n}.`:"Gateway restart requested."}dismiss(e){return this.postpone(e,"Dismissed")}remindLater(e){return this.postpone(e,"Will remind later about")}postpone(e,n){let r=gt(e),o=this.readState();return this.writeState({...o,...r?{dismissedVersion:r,lastDismissedAt:new Date(this.now()).toISOString()}:{}}),r?`${n} OCA ${r} update reminder.`:`${n} OCA update reminder.`}async checkForUpdate(e){let n=this.readState(),r=n.lastCheckedAt?Date.parse(n.lastCheckedAt):Number.NaN;if(Number.isFinite(r)&&this.now()-r<Da){await this.promptFromState(n,e);return}let o=new Date(this.now()).toISOString(),i={...n,lastCheckedAt:o};delete i.lastError,this.writeState(i);try{let s=await this.fetchLatestRelease(),a=gt(s?.version),d={...this.readState(),latestVersion:a};delete d.lastError,this.writeState(d),await this.promptFromState(d,e)}catch(s){throw this.writeState({...this.readState(),lastError:Ma(s)}),s}}async promptFromState(e,n){let r=gt(e.latestVersion);if(!$p(r,this.options.currentVersion)||!this.shouldPromptForVersion(e,r))return;let o=$a(n.route??Ea());o&&(await this.sendUpdatePrompt(o,r),this.writeState({...this.readState(),latestVersion:r,promptedVersion:r,lastPromptedAt:new Date(this.now()).toISOString()}))}async sendUpdatePrompt(e,n){await this.notifier.send(e,[`OCA update available: ${this.options.currentVersion} -> ${n}.`,"",`Update now will run: openclaw plugins update ${_i}`,"If the update succeeds, OCA will ask separately before restarting the Gateway."].join(`
56
+ `),[[this.options.actionButtonFactory(Wt,"plugin-update-install","Update now",{pluginUpdateVersion:n,route:{provider:e.channel,accountId:e.accountId,target:e.target,threadId:e.threadId,sessionKey:e.sessionKey}}),this.options.actionButtonFactory(Wt,"plugin-update-remind-later","Remind later",{pluginUpdateVersion:n}),this.options.actionButtonFactory(Wt,"plugin-update-dismiss","Dismiss",{pluginUpdateVersion:n})]])}shouldPromptForVersion(e,n){let r=e.promptedVersion===n?e.lastPromptedAt:void 0,o=e.dismissedVersion===n?e.lastDismissedAt:void 0,i=[r,o].map(s=>s?Date.parse(s):Number.NaN).filter(s=>Number.isFinite(s));return i.length===0?!0:this.now()-Math.max(...i)>=_p}async sendRestartPrompt(e,n){await this.notifier.send(e,[`OCA ${n} update command completed.`,"","Restart the Gateway now to load the updated plugin?","This will run: openclaw gateway restart"].join(`
57
+ `),[[this.options.actionButtonFactory(Wt,"plugin-update-restart","Restart Gateway",{pluginUpdateVersion:n}),this.options.actionButtonFactory(Wt,"plugin-update-remind-later","Remind later",{pluginUpdateVersion:n}),this.options.actionButtonFactory(Wt,"plugin-update-dismiss","Dismiss",{pluginUpdateVersion:n})]]),this.writeState({...this.readState(),restartPromptedVersion:n})}readState(){try{return Ep(JSON.parse(Pp(this.statePath,"utf-8")))}catch{return{}}}writeState(e){wp(Ap(this.statePath),{recursive:!0});let n=`${this.statePath}.tmp`;Rp(n,JSON.stringify(e,null,2),"utf-8"),bp(n,this.statePath)}};re();K();function Lp(t){return t.length>80?`${t.slice(0,80)}...`:t}function Fp(t){return t.worktreePath?!t.originalWorkdir||t.originalWorkdir===t.worktreePath?`${t.worktreePath} (worktree)`:`${t.worktreePath} (worktree of ${t.originalWorkdir})`:t.workdir}function Bp(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: ${Fp(t)}`,` Model: ${t.model??"default"}`,` Prompt: "${Lp(t.prompt)}"`];if(t.reasoningEffort&&e.push(` Reasoning effort: ${t.reasoningEffort}`),t.fastMode&&e.push(" Fast mode: enabled"),t.resumeSessionId){let n=t.resumeSessionName?`${t.resumeSessionName} [${t.resumeSessionId}]`:t.resumeSessionId;e.push(` Resume: ${n}${t.forkSession?" (forked)":""}`),!t.forkSession&&t.resumeSessionName&&t.sessionName!==t.resumeSessionName&&e.push(` Follow-up label: ${t.sessionName}`)}else t.forceNewSession&&e.push(" Force new session: true");return 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(`
58
+ `)}function rr(t,e){return Bp({...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,resumeSessionName:e.resumedFromSessionName??t.resumeSessionName})}function or(t){let e=t.resumedFromSessionName||t.sessionName,n=t.resumedFromSessionName&&t.sessionName!==t.resumedFromSessionName?` | Follow-up label: ${t.sessionName}`:"";return`▶️ [${e}] Resumed${n} | ${t.workdirLabel} | ${t.harnessLabel}`}oe();function Lt(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 Pr(t){return"id"in t?t.id:t.sessionId}function In(t){return t.status==="completed"||t.killReason==="done"}function Ym(t){return!In(t)||!F(t)?!1:t.backendRef?.kind==="codex-app-server"||t.backendRef?.kind==="opencode-server"}function Zm(t){return(t.killReason==="shutdown"||t.killReason==="startup-timeout")&&!F(t)}function xn(t){if(t.status==="running")return{kind:"direct",reason:"already_running"};let e=Pr(t);if(In(t)&&!Ym(t))return{kind:"unavailable",reason:"completed",stableSessionId:e};let n=F(t);if(n){let r="harnessName"in t?void 0:t,{resumeSessionId:o,clearedPersistedCodexResume:i}=Lt({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 Zm(t)?{kind:"relaunch",stableSessionId:e}:{kind:"unavailable",reason:"missing_backend_state",stableSessionId:e}}oe();gr();import{existsSync as Sd}from"fs";ee();function hd(t){return t==null?void 0:String(t).trim()||void 0}function Xm(t){return t.trim().replace(/^['"`](.*)['"`]$/s,"$1").trim()}function ef(t){let e=t.split(/\n\s*\n/,1)[0]?.split(`
59
+ `).map(n=>n.trim()).filter(Boolean)??[];if(e.length!==0)for(let n of e){let r=n.match(/^(Workdir|Repo):\s*(.+)$/),o=Xm(r?.[2]??"");if(o.startsWith("/")&&Sd(o))return o}}function yd(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&&hd(t.originThreadId)===hd(e.originThreadId)}function kd(t){return t.slice(0,3).map(e=>` - ${e.name} [${e.ref}] | status=${e.status}${e.lifecycle?` | lifecycle=${e.lifecycle}`:""}`).join(`
60
+ `)}function tf(t,e){let n=[],r=[],o=new Set;for(let i of t.list?.("all")??[]){if(!yd(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||!yd(i,e))continue;let s=G(i)??i.harnessSessionId,a=i.sessionId??F(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 br(t,e,n){let r=t.workdir||ef(t.prompt)||e.workspaceDir||L.defaultWorkdir||process.cwd();if(!Sd(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=t.harness??ue(),i=Dt(o),s=t.model??i,a=Ke(o,s),d=t.model!==void 0,l=er(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&&!Vt(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.6-sol".`};if(a&&l&&l.length>0&&!mr(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=fr(o,a,l),m=tr(e),p=yn(e,m||ft(r)),y=e.sessionKey||void 0,f=Ca(y)??Mi(e);if(!t.resume_session_id&&!t.force_new_session){let k=tf(n,{workdir:r,originSessionKey:y,originChannel:p,originThreadId:f});if(k.resumable.length>0||k.active.length>0){let P=k.resumable.length>0?["Linked resumable session(s) already exist for this thread/workdir:",kd(k.resumable),"","Resume the latest one with:",` agent_respond(session='${k.resumable[0].ref}', message='<next instruction>')`,"Fork from it with:",` agent_launch(prompt='<new task>', resume_session_id='${k.resumable[0].ref}', fork_session=true)`].join(`
61
+ `):"",_=k.active.length>0?[k.resumable.length>0?"Linked active session(s):":"Linked active session(s) already exist for this thread/workdir:",kd(k.active),"","Send a follow-up instead of launching a duplicate:",` agent_respond(session='${k.active[0].ref}', message='<next instruction>')`].join(`
62
+ `):"";return{kind:"blocked",text:["Resume-first protection blocked a fresh launch.","",P,_,["If you intentionally want a brand-new independent session here, call:"," agent_launch(prompt='<new task>', force_new_session=true)"].join(`
58
63
  `)].filter(Boolean).join(`
59
64
 
60
- `)}}}let h=t.resume_session_id,k=h?n.resolve?.(h):void 0,S=h?n.getPersistedSession?.(h):void 0;if(h){let y=n.resolveBackendConversationId?.(h)??n.resolveHarnessSessionId?.(h);if(!y)return{kind:"error",text:`Error: Could not resolve resume_session_id "${h}" to a session ID. Use agent_sessions to list available sessions.`};h=y}let{resumeSessionId:b,clearedPersistedCodexResume:A}=It({requestedResumeSessionId:h,activeSession:k?{harnessSessionId:k.backendConversationId??k.harnessSessionId}:void 0,persistedSession:S?{harness:S.harness,backendRef:S.backendRef}:void 0}),M=t.permission_mode??W.permissionMode,R=t.plan_approval??W.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:u,permissionMode:M,planApproval:R,originChannel:p,originThreadId:m,originSessionKey:f,route:At(e,p,f),resumeSessionId:b,resolvedResumeId:h,clearedPersistedCodexResume:A,reasoningEffort:Je(o),fastMode:Rt(o)}}ee();function Ot(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function $e(t){if(!Number.isFinite(t))return"0s";let e=Math.floor(t/1e3),n=Math.floor(e/60),r=e%60;return n>0?`${n}m${r}s`:`${r}s`}var Jp=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 qa(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!Jp.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var Fa={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function Yp(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 Ka(t){let e=Fa[t.phase]??Fa[t.status]??"❓",n=$e(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} ${Yp(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: ${Ot({harness:t.harness,model:t.model})}`):t.model&&s.push(` 🧰 Harness | model: ${t.model}`);let a=O(t);return a&&s.push(` 🔗 Backend ID: ${a}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
61
- `)}function cr(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?$e(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 Ua(t,e){let n=t.split(`
65
+ `)}}}let c=t.resume_session_id,h=c?n.resolve?.(c):void 0,S=c?n.getPersistedSession?.(c):void 0;if(c){let k=n.resolveBackendConversationId?.(c)??n.resolveHarnessSessionId?.(c);if(!k)return{kind:"error",text:`Error: Could not resolve resume_session_id "${c}" to a session ID. Use agent_sessions to list available sessions.`};c=k}let{resumeSessionId:b,clearedPersistedCodexResume:A}=Lt({requestedResumeSessionId:c,activeSession:h?{harnessSessionId:h.backendConversationId??h.harnessSessionId}:void 0,persistedSession:S?{harness:S.harness,backendRef:S.backendRef}:void 0}),x=t.permission_mode??L.permissionMode,R=t.plan_approval??L.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:u,permissionMode:x,planApproval:R,originChannel:p,originThreadId:f,originSessionKey:y,route:Nt(e,p,y),resumeSessionId:b,resolvedResumeId:c,clearedPersistedCodexResume:A,reasoningEffort:rt(o),fastMode:Ot(o)}}ee();function at(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function Ne(t){if(!Number.isFinite(t))return"0s";let e=Math.floor(t/1e3),n=Math.floor(e/60),r=e%60;return n>0?`${n}m${r}s`:`${r}s`}var nf=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 wd(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!nf.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var vd={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function rf(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 Pd(t){let e=vd[t.phase]??vd[t.status]??"❓",n=Ne(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} ${rf(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: ${at({harness:t.harness,model:t.model})}`):t.model&&s.push(` 🧰 Harness | model: ${t.model}`);let a=F(t);return a&&s.push(` 🔗 Backend ID: ${a}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
66
+ `)}function Rr(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?Ne(n):"n/a"}`];if(t.mostExpensive){let a=t.mostExpensive;s.push("","🏆 Notable session",` ${a.name} [${a.id}]`,` 📝 "${a.prompt}"`)}return s.join(`
67
+ `)}function de(t,e){return e<=0?"":t.length<=e?t:e<=3?".".repeat(e):t.slice(0,e-3)+"..."}function bd(t,e){let n=t.split(`
63
68
  `),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 Va(t,e){let n=t.split(`
69
+ `)}function Rd(t,e){let n=t.split(`
65
70
  `),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 lt,wn,Wt=!1;function ja(t){try{return t?.config?.current?.()}catch{return}}function Nt(t,e){if(t&&typeof t=="object"){lt=t,arguments.length>=2?(wn=e,Wt=!0):Wt||(wn=ja(lt),Wt=!0);return}lt=void 0,wn=void 0,Wt=!1}function Lt(){return lt}function _i(){return lt?.tasks?.managedFlows??lt?.taskFlow}function Ga(){return Wt||(wn=ja(lt),Wt=!0),wn}var Zp="openclaw-code-agent",Xp=160,pr={create(){},progress(){},finalize(){}};function mr(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function Ei(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function em(t){let e=t.prompt.trim().replace(/\s+/g," ");return de(e||t.name,Xp)}function Ha(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 za(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 fr(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 tm(t){return gr(t.lifecycle)}function gr(t){return t==="awaiting_plan_decision"||t==="awaiting_user_input"||t==="awaiting_worktree_decision"||t==="suspended"}function nm(t){if(t.pendingPlanApproval||t.pendingWorktreeDecisionSince)return!0;if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;return e==="suspended"?t.runtimeRecovery.rawResumable===!0||t.resumable===!0:gr(e)}return t.lifecycle==="suspended"?t.resumable===!0:gr(t.lifecycle)}function rm(t){if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;if(gr(e))return e}return t.lifecycle}function $i(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 om(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 hr(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var Di=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:Zp,goal:em(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:$i(e,"created",n),createdAt:e.startedAt,updatedAt:r}),e.taskFlowMirror=this.flow,this.lastProgressKey=this.progressKey(e,n)}catch(o){mr("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=Ha(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=$i(e,"progress",n),i=Date.now(),s=tm(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=hr(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.lastProgressKey=r}catch(o){mr("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=za(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":fr(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...$i(e,"terminal",r),terminalStatus:n,terminalSummary:fr(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:fr(e.status,e.killReason),updatedAt:o,endedAt:o});Ei("finalize",s),this.flow=hr(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.finalized=!0}catch(o){mr("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function im(t){return t==="succeeded"||t==="failed"||t==="cancelled"||t==="lost"}function sm(t){if(!t?.trim())return;let e=_i()?.fromToolContext;if(typeof e!="function")return;let n=e({sessionKey:t});if(!n||typeof n!="object")return;let r=n;if(!(typeof r.setWaiting!="function"||typeof r.finish!="function"||typeof r.fail!="function"))return{setWaiting:r.setWaiting,finish:r.finish,fail:r.fail}}function am(t){return t.originSessionKey??t.route?.sessionKey}function dm(t){return t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"Lost after OCA restart without live process":fr(t.status,t.killReason??"unknown")}function Qa(t){let e=t.taskFlowMirror?{...t.taskFlowMirror}:void 0;if(!e||im(e.status))return;let n=sm(am(t));if(!n)return;let r=Date.now();if(nm(t)){let l=Ha({status:t.status,lifecycle:rm(t)??"suspended"})??"Waiting",u=n.setWaiting({flowId:e.flowId,expectedRevision:e.revision,currentStep:l,stateJson:{phase:"progress",integration:"phase-1-managed-task-flow",sessionId:t.sessionId,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:l,reconciled:!0},waitJson:{reason:l,sessionId:t.sessionId},blockedSummary:l,updatedAt:r});return Ei("reconcile-waiting",u),hr(e,u)}let o=za({status:t.status,killReason:t.killReason??"unknown"})??"failed",i=dm(t),s=t.completedAt??r,a={phase:"terminal",integration:"phase-1-managed-task-flow",sessionId:t.sessionId,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:i,terminalStatus:t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"lost":o,terminalSummary:i,reconciled:!0,runtimeRecovery:t.runtimeRecovery},d=o==="succeeded"?n.finish({flowId:e.flowId,expectedRevision:e.revision,stateJson:a,updatedAt:s,endedAt:s}):n.fail({flowId:e.flowId,expectedRevision:e.revision,stateJson:a,blockedSummary:i,updatedAt:s,endedAt:s});return Ei("reconcile-terminal",d),hr(e,d)}function yr(t){if(!t.sessionKey?.trim())return pr;try{let e=_i()?.fromToolContext;if(typeof e!="function")return pr;let n=e(t);return om(n)?new Di(n):pr}catch(e){return mr("resolve",e),pr}}function lm(t){return t instanceof Error?t.message:String(t)}function Ja(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function um(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function cm(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function pm(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function Ya(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(!um(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=ur(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:h,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?vn(b):void 0;if(A?.kind==="direct")return{content:[{type:"text",text:`Session ${b.name} [${Ja(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} [${Ja(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 M=n.worktree_strategy??W.defaultWorktreeStrategy??"off",R=n.fork_session?void 0:A?.kind==="resume"||A?.kind==="relaunch"?A.stableSessionId:void 0;if(M!=="off"&&pm(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:h,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 y=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:yr(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:cm(v)?v.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??W.permissionMode,planApproval:d,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,clearedPersistedCodexResume:h},y):Un({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??W.permissionMode,planApproval:d,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:h},{id:y.id,name:y.name,model:y.model,reasoningEffort:y.reasoningEffort??Je(i),fastMode:y.fastMode??S,worktreeStrategy:y.worktreeStrategy??n.worktree_strategy??W.defaultWorktreeStrategy??"off",repoIntegrationPolicy:y.repoIntegrationPolicy,repoProvider:y.repoProvider,worktreePath:y.worktreePath,originalWorkdir:y.originalWorkdir})}]}}catch(r){let o=lm(r),i=o.includes("Max sessions")?"":`
71
+ `)}mt();var of="openclaw-code-agent",sf=160,Ar={create(){},progress(){},finalize(){}};function Ir(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function Zi(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function af(t){let e=t.prompt.trim().replace(/\s+/g," ");return de(e||t.name,sf)}function Ad(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 Id(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 xr(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 df(t){return Tr(t.lifecycle)}function Tr(t){return t==="awaiting_plan_decision"||t==="awaiting_user_input"||t==="awaiting_worktree_decision"||t==="suspended"}function lf(t){if(t.pendingPlanApproval||t.pendingWorktreeDecisionSince)return!0;if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;return e==="suspended"?t.runtimeRecovery.rawResumable===!0||t.resumable===!0:Tr(e)}return t.lifecycle==="suspended"?t.resumable===!0:Tr(t.lifecycle)}function uf(t){if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;if(Tr(e))return e}return t.lifecycle}function Yi(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 cf(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 Cr(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:of,goal:af(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:Yi(e,"created",n),createdAt:e.startedAt,updatedAt:r}),e.taskFlowMirror=this.flow,this.lastProgressKey=this.progressKey(e,n)}catch(o){Ir("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=Ad(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=Yi(e,"progress",n),i=Date.now(),s=df(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=Cr(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.lastProgressKey=r}catch(o){Ir("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=Id(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":xr(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...Yi(e,"terminal",r),terminalStatus:n,terminalSummary:xr(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:xr(e.status,e.killReason),updatedAt:o,endedAt:o});Zi("finalize",s),this.flow=Cr(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.finalized=!0}catch(o){Ir("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function pf(t){return t==="succeeded"||t==="failed"||t==="cancelled"||t==="lost"}function mf(t){if(!t?.trim())return;let e=vi()?.fromToolContext;if(typeof e!="function")return;let n=e({sessionKey:t});if(!n||typeof n!="object")return;let r=n;if(!(typeof r.setWaiting!="function"||typeof r.finish!="function"||typeof r.fail!="function"))return{setWaiting:r.setWaiting,finish:r.finish,fail:r.fail}}function ff(t){return t.originSessionKey??t.route?.sessionKey}function gf(t){return t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"Lost after OCA restart without live process":xr(t.status,t.killReason??"unknown")}function xd(t){let e=t.taskFlowMirror?{...t.taskFlowMirror}:void 0;if(!e||pf(e.status))return;let n=mf(ff(t));if(!n)return;let r=Date.now();if(lf(t)){let l=Ad({status:t.status,lifecycle:uf(t)??"suspended"})??"Waiting",u=n.setWaiting({flowId:e.flowId,expectedRevision:e.revision,currentStep:l,stateJson:{phase:"progress",integration:"phase-1-managed-task-flow",sessionId:t.sessionId,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:l,reconciled:!0},waitJson:{reason:l,sessionId:t.sessionId},blockedSummary:l,updatedAt:r});return Zi("reconcile-waiting",u),Cr(e,u)}let o=Id({status:t.status,killReason:t.killReason??"unknown"})??"failed",i=gf(t),s=t.completedAt??r,a={phase:"terminal",integration:"phase-1-managed-task-flow",sessionId:t.sessionId,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:i,terminalStatus:t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"lost":o,terminalSummary:i,reconciled:!0,runtimeRecovery:t.runtimeRecovery},d=o==="succeeded"?n.finish({flowId:e.flowId,expectedRevision:e.revision,stateJson:a,updatedAt:s,endedAt:s}):n.fail({flowId:e.flowId,expectedRevision:e.revision,stateJson:a,blockedSummary:i,updatedAt:s,endedAt:s});return Zi("reconcile-terminal",d),Cr(e,d)}function Mr(t){if(!t.sessionKey?.trim())return Ar;try{let e=vi()?.fromToolContext;if(typeof e!="function")return Ar;let n=e(t);return cf(n)?new Xi(n):Ar}catch(e){return Ir("resolve",e),Ar}}function hf(t){return t instanceof Error?t.message:String(t)}function Td(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function yf(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function kf(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function Sf(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function Cd(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(!yf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=br(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:m,route:p,resumeSessionId:y,resolvedResumeId:f,clearedPersistedCodexResume:c,reasoningEffort:h,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?xn(b):void 0;if(A?.kind==="direct")return{content:[{type:"text",text:`Session ${b.name} [${Td(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} [${Td(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=b&&"resumedFromSessionName"in b?b.resumedFromSessionName:void 0,R=A?.kind==="resume"&&!n.fork_session?x??b?.name:void 0,k=R&&!n.name?R:n.name,P=n.worktree_strategy??L.defaultWorktreeStrategy??"off",_=n.fork_session?void 0:A?.kind==="resume"||A?.kind==="relaunch"?A.stableSessionId:void 0;if(P!=="off"&&Sf(v)&&v.checkRepoPolicyForLaunch(o,n.worktree_strategy).ok===!1)return{content:[{type:"text",text:v.requestRepoPolicyForLaunch({route:p,prompt:n.prompt,workdir:o,name:k,model:s,reasoningEffort:h,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:A?.kind==="resume"?A.resumeSessionId:y,resumedFromSessionName:R,resumeWorktreeFrom:f,sessionIdOverride:_,clearedPersistedCodexResume:c,forkSession:y?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 M=v.spawn({prompt:n.prompt,sessionIdOverride:_,name:k,workdir:o,model:s,reasoningEffort:h,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:A?.kind==="resume"?A.resumeSessionId:y,resumedFromSessionName:R,resumeWorktreeFrom:f,forkSession:y?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:m,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:kf(v)?v.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??L.permissionMode,planApproval:d,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,resumeSessionName:R,forkSession:n.fork_session,clearedPersistedCodexResume:c},M):rr({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??L.permissionMode,planApproval:d,resumeSessionId:n.resume_session_id,resumeSessionName:R,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:c},{id:M.id,name:M.name,model:M.model,reasoningEffort:M.reasoningEffort??rt(i),fastMode:M.fastMode??S,worktreeStrategy:M.worktreeStrategy??n.worktree_strategy??L.defaultWorktreeStrategy??"off",repoIntegrationPolicy:M.repoIntegrationPolicy,repoProvider:M.repoProvider,worktreePath:M.worktreePath,originalWorkdir:M.originalWorkdir})}]}}catch(r){let o=hf(r),i=o.includes("Max sessions")?"":`
67
72
 
68
- Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}re();U();ae();import{existsSync as Ui,readFileSync as Ad}from"fs";import{EventEmitter as Vm}from"events";import{webcrypto as Xa}from"node:crypto";var Za="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var mm=128,et,Bt;function fm(t){if(t<0)throw new RangeError("Wrong ID size");try{!et||et.length<t?(et=Buffer.allocUnsafe(t*mm),Xa.getRandomValues(et),Bt=0):Bt+t>et.length&&(Xa.getRandomValues(et),Bt=0)}catch(e){throw et=void 0,e}Bt+=t}function kr(t=21){fm(t|=0);let e="";for(let n=Bt-t;n<Bt;n++)e+=Za[et[n]&63];return e}Ti();ae();ee();var ed={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function Z(t,e){return Object.hasOwn(t,e)}var td=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function gm(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 pe(t){return{...t,approvalExecutionState:gm(t)}}function Oi(t,e){switch(e.type){case"initialize":return pe({...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"?pe({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?pe({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):pe({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return pe({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return pe({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return pe({...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 pe({...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 pe({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return pe({...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 pe({...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 pe({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return pe({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return pe({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":td.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return pe({...t,deliveryState:e.deliveryState})}}function nd(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=Oi(n,{type:"worktree.decision_requested"}):td.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),pe(n)}var Sr=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 hm}from"crypto";import{appendFileSync as ym}from"fs";import{tmpdir as km}from"os";import{join as Sm}from"path";var rd=2e3,vm=/^[A-Za-z0-9_.-]+$/;function wm(t){return vm.test(t)?t:`hashed+${hm("sha256").update(t,"utf8").digest("hex")}`}function ut(t){return Sm(km(),`openclaw-agent-${wm(t)}.txt`)}function Pm(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 od(t,e,n){Pm(t,n),t.length>rd&&t.splice(0,t.length-rd);try{ym(ut(e),n,"utf-8")}catch{}return t}var vr=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 wr=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 Pr=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 Um=[/\bfailed to authenticate\b/i,/\binvalid bearer token\b/i,/\bapi error:\s*401\b/i,/\b401\s+unauthori[sz]ed\b/i,/\binvalid api key\b/i,/\binvalid authentication\b/i,/\bauthentication failed\b/i,/\bauth(?:orization)? error\b/i];function Ki(t){return t?.trim()?Um.some(e=>e.test(t)):!1}function bd(t){if(!t?.trim())return;let e=t.split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return e.find(n=>Ki(n))??e.at(-1)}var jm=120*1e3;function Er(t){return t instanceof Error?t.message:String(t)}function Gm(t,e){JSON.stringify({component:"Session",event:t,at:new Date().toISOString(),...e})}function Hm(t){return t?{backendRefKind:t.kind,hasBackendConversationId:!!t.conversationId,hasBackendRunId:!!t.runId,hasBackendWorktreeId:!!t.worktreeId,hasBackendWorktreePath:!!t.worktreePath}:{}}var Dr=class extends Vm{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";taskFlowMirror;deliveryState="idle";canUseTool;autoRespondCount=0;timers=new vr;constructor(e,n){super(),this.id=e.sessionIdOverride??kr(8),this.name=n,this.harness=e.harness?yn(e.harness):Oa(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??bt(this.harness.name),this.reasoningEffort=e.reasoningEffort??Je(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??Rt(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??W.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??W.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 wr({appendOutput:r=>od(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 Pr({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??=De(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"),i=r.num_turns===0?[r.result,...this.outputBuffer.slice(-5)].filter(c=>typeof c=="string").join(`
71
- `):"",s=o==="completed"&&Ki(i),a=s?"failed":o,d=s?bd(i)??r.result:r.result;this.result={subtype:a==="interrupted"?"interrupted":a==="completed"?"success":"error",duration_ms:r.duration_ms,total_cost_usd:r.total_cost_usd,num_turns:r.num_turns,result:d,is_error:a==="failed",session_id:r.session_id},this.costUsd=r.total_cost_usd;let l=this.multiTurn&&this.messageStream&&a==="interrupted",u=this.multiTurn&&this.messageStream&&a==="completed";l?(this.resetIdleTimer(),this.turnRuntime.finishInterruptedTurn(this.messageStream?.hasPending()===!0)):u?(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(a==="completed"?"completed":"failed",{...a==="failed"&&d?{error:d}:{}})),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 O(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(!ed[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=pt(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(i=>`- ${i}`).join(`
73
+ Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}re();K();oe();import{existsSync as ds,readFileSync as sl}from"fs";import{EventEmitter as Yf}from"events";import{webcrypto as _d}from"node:crypto";var Md="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var vf=128,dt,Ht;function wf(t){if(t<0)throw new RangeError("Wrong ID size");try{!dt||dt.length<t?(dt=Buffer.allocUnsafe(t*vf),_d.getRandomValues(dt),Ht=0):Ht+t>dt.length&&(_d.getRandomValues(dt),Ht=0)}catch(e){throw dt=void 0,e}Ht+=t}function _r(t=21){wf(t|=0);let e="";for(let n=Ht-t;n<Ht;n++)e+=Md[dt[n]&63];return e}zi();oe();ee();var $d={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function X(t,e){return Object.hasOwn(t,e)}var Ed=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function Pf(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 me(t){return{...t,approvalExecutionState:Pf(t)}}function es(t,e){switch(e.type){case"initialize":return me({...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"?me({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?me({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):me({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return me({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return me({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return me({...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 me({...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 me({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return me({...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 me({...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 me({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return me({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return me({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":Ed.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return me({...t,deliveryState:e.deliveryState})}}function Dd(t,e){let n={...t,...X(e,"lifecycle")?{lifecycle:e.lifecycle}:{},...X(e,"approvalState")?{approvalState:e.approvalState}:{},...X(e,"approvalExecutionState")?{approvalExecutionState:e.approvalExecutionState}:{},...X(e,"worktreeState")?{worktreeState:e.worktreeState}:{},...X(e,"runtimeState")?{runtimeState:e.runtimeState}:{},...X(e,"deliveryState")?{deliveryState:e.deliveryState}:{},...X(e,"requestedPermissionMode")?{requestedPermissionMode:e.requestedPermissionMode}:{},...X(e,"currentPermissionMode")?{currentPermissionMode:e.currentPermissionMode}:{},...X(e,"pendingPlanApproval")?{pendingPlanApproval:e.pendingPlanApproval}:{},...X(e,"planApprovalContext")?{planApprovalContext:e.planApprovalContext}:{},...X(e,"planDecisionVersion")?{planDecisionVersion:e.planDecisionVersion}:{},...X(e,"actionablePlanDecisionVersion")?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...X(e,"canonicalPlanPromptVersion")?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...X(e,"approvalPromptRequiredVersion")?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...X(e,"approvalPromptVersion")?{approvalPromptVersion:e.approvalPromptVersion}:{},...X(e,"approvalPromptStatus")?{approvalPromptStatus:e.approvalPromptStatus}:{},...X(e,"approvalPromptTransport")?{approvalPromptTransport:e.approvalPromptTransport}:{},...X(e,"approvalPromptMessageKind")?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...X(e,"approvalPromptLastAttemptAt")?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...X(e,"approvalPromptDeliveredAt")?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...X(e,"approvalPromptFailedAt")?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{},...X(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"}),X(e,"pendingWorktreeDecisionSince")&&e.pendingWorktreeDecisionSince!==void 0||n.worktreeState==="pending_decision"?n=es(n,{type:"worktree.decision_requested"}):Ed.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),me(n)}var $r=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 bf}from"crypto";import{appendFileSync as Rf}from"fs";import{tmpdir as Af}from"os";import{join as If}from"path";var Od=2e3,xf=/^[A-Za-z0-9_.-]+$/;function Tf(t){return xf.test(t)?t:`hashed+${bf("sha256").update(t,"utf8").digest("hex")}`}function yt(t){return If(Af(),`openclaw-agent-${Tf(t)}.txt`)}function Cf(t,e){if(!e)return;let n=e.split(`
74
+ `),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function Nd(t,e,n){Cf(t,n),t.length>Od&&t.splice(0,t.length-Od);try{Rf(yt(e),n,"utf-8")}catch{}return t}var Er=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 Dr=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?`
75
+ ${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 Or=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}};ve();var Jf=[/\bfailed to authenticate\b/i,/\binvalid bearer token\b/i,/\bapi error:\s*401\b/i,/\b401\s+unauthori[sz]ed\b/i,/\binvalid api key\b/i,/\binvalid authentication\b/i,/\bauthentication failed\b/i,/\bauth(?:orization)? error\b/i];function as(t){return t?.trim()?Jf.some(e=>e.test(t)):!1}function ol(t){if(!t?.trim())return;let e=t.split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return e.find(n=>as(n))??e.at(-1)}var Zf=120*1e3;function Gr(t){return t instanceof Error?t.message:String(t)}function Xf(t,e){JSON.stringify({component:"Session",event:t,at:new Date().toISOString(),...e})}function eg(t){return t?{backendRefKind:t.kind,hasBackendConversationId:!!t.conversationId,hasBackendRunId:!!t.runId,hasBackendWorktreeId:!!t.worktreeId,hasBackendWorktreePath:!!t.worktreePath}:{}}var Hr=class extends Yf{id;name;harnessSessionId;backendRef;harness;harnessHandle;prompt;workdir;model;reasoningEffort;fastMode;systemPrompt;allowedTools;permissionMode;requestedPermissionMode;planApproval;codexApprovalPolicy;currentPermissionMode;pendingModeSwitch;resumeSessionId;resumedFromSessionName;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";taskFlowMirror;deliveryState="idle";canUseTool;autoRespondCount=0;timers=new Er;constructor(e,n){super(),this.id=e.sessionIdOverride??_r(8),this.name=n,this.harness=e.harness?Rn(e.harness):gd(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??Dt(this.harness.name),this.reasoningEffort=e.reasoningEffort??rt(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??Ot(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??L.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??L.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.resumedFromSessionName=e.resumedFromSessionName,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 Dr({appendOutput:r=>Nd(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 Or({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??=Ce(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"),i=r.num_turns===0?[r.result,...this.outputBuffer.slice(-5)].filter(m=>typeof m=="string").join(`
76
+ `):"",s=o==="completed"&&as(i),a=s?"failed":o,d=s?ol(i)??r.result:r.result;this.result={subtype:a==="interrupted"?"interrupted":a==="completed"?"success":"error",duration_ms:r.duration_ms,total_cost_usd:r.total_cost_usd,num_turns:r.num_turns,result:d,is_error:a==="failed",session_id:r.session_id},this.costUsd=r.total_cost_usd;let l=this.multiTurn&&this.messageStream&&a==="interrupted",u=this.multiTurn&&this.messageStream&&a==="completed";l?(this.resetIdleTimer(),this.turnRuntime.finishInterruptedTurn(this.messageStream?.hasPending()===!0)):u?(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(a==="completed"?"completed":"failed",{...a==="failed"&&d?{error:d}:{}})),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 F(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(!$d[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(`
72
77
  `),r=e.length>20?`
73
78
  - ...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(`
74
- `);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 Sr,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:Zs(),canUseTool:this.canUseTool});this.harnessHandle=n,this.logDiagnostic("harness.launch.created",{hasStreamInput:!!n.streamInput,hasInterrupt:!!n.interrupt,hasPermissionModeSwitch:!!n.setPermissionMode}),this.setTimer("startup",jm,()=>{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: ${Er(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${Er(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.]
79
+ `);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 $r,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:Ia(),canUseTool:this.canUseTool});this.harnessHandle=n,this.logDiagnostic("harness.launch.created",{hasStreamInput:!!n.streamInput,hasInterrupt:!!n.interrupt,hasPermissionModeSwitch:!!n.setPermissionMode}),this.setTimer("startup",Zf,()=>{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: ${Gr(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${Gr(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.]
75
80
 
76
81
  ${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.]
77
82
 
78
- ${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}${Er(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=(W.idleTimeoutMinutes??15)*60*1e3;this.setTimer("idle",e,()=>{this._status==="running"&&(this.logDiagnostic("idle_timeout.fire",{idleTimeoutMinutes:W.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}${Er(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=Oi(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=nd(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;Gm(e,{sessionId:this.id,name:this.name,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState,harness:this.harnessName,hasHarnessSessionId:!!this.harnessSessionId,...Hm(this.backendRef),...i})}};var zm=50,Qm=1,Jm=new Set(["starting","running","completed","failed","killed"]),Ym=5,Zm=1440*60*1e3,Or=new Set(["merged","released","dismissed","no_change"]);function Xm(t){let e=Number(t);return!Number.isFinite(e)||e<Qm?zm:Math.floor(e)}function ef(t){return typeof t=="string"&&Jm.has(t)}function tf(t){let e=t.split(`
79
- `);return e.at(-1)===""&&e.pop(),e}function Vi(t){return t.backendRef?.conversationId??t.harnessSessionId}function nf(t,e){return e&&Or.has(e)&&(!t||!Or.has(t))?e:t??e}function rf(t,e){return e&&Or.has(e.state)&&(!t||!Or.has(t.state))?e:t??e}function Id(t,e,n){let r=Ad(t,"utf-8"),o=tf(r);return e.full?o:o.slice(-n)}function of(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=ut(t.id);if(!Ui(r))return null;try{return Id(r,e,n)}catch{return null}}function sf(t){let e=$e(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(`
80
- `)}function xd(t,e){let n=t.name||t.sessionId||Vi(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(`
81
- `)}function af(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function df(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 Rd(t,e){let n=xd(t,df(t)),r=Vi(t),o=r?`
83
+ ${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}${Gr(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=(L.idleTimeoutMinutes??15)*60*1e3;this.setTimer("idle",e,()=>{this._status==="running"&&(this.logDiagnostic("idle_timeout.fire",{idleTimeoutMinutes:L.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}${Gr(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=es(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=Dd(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;Xf(e,{sessionId:this.id,name:this.name,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState,harness:this.harnessName,hasHarnessSessionId:!!this.harnessSessionId,...eg(this.backendRef),...i})}};var tg=50,ng=1,rg=new Set(["starting","running","completed","failed","killed"]),og=5,ig=1440*60*1e3,zr=new Set(["merged","released","dismissed","no_change"]);function sg(t){let e=Number(t);return!Number.isFinite(e)||e<ng?tg:Math.floor(e)}function ag(t){return typeof t=="string"&&rg.has(t)}function dg(t){let e=t.split(`
84
+ `);return e.at(-1)===""&&e.pop(),e}function ls(t){return t.backendRef?.conversationId??t.harnessSessionId}function lg(t,e){return e&&zr.has(e)&&(!t||!zr.has(t))?e:t??e}function ug(t,e){return e&&zr.has(e.state)&&(!t||!zr.has(t.state))?e:t??e}function al(t,e,n){let r=sl(t,"utf-8"),o=dg(r);return e.full?o:o.slice(-n)}function cg(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=yt(t.id);if(!ds(r))return null;try{return al(r,e,n)}catch{return null}}function pg(t){let e=Ne(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(`
85
+ `)}function dl(t,e){let n=t.name||t.sessionId||ls(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(`
86
+ `)}function mg(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function fg(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 il(t,e){let n=dl(t,fg(t)),r=ls(t),o=r?`
82
87
  Backend session: ${r}`:"";return`${n}
83
- (no persisted output available: ${e})${o}`}function lf(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?`
88
+ (no persisted output available: ${e})${o}`}function gg(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?`
84
89
  (no output yet)
85
90
  ${e.join(`
86
91
  `)}`:`
87
- (no output yet)`}function Wr(t,e,n={}){let r=Xm(n.lines),o=t.resolve(e);if(!o){let l=t.getPersistedSession(e);if(l?.outputPath&&Ui(l.outputPath))try{let u=Id(l.outputPath,n,r).join(`
88
- `),c=xd(l,af(l));return u?`${c}
89
- ${u}`:`${c}
90
- (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?Rd(l,`output file is missing at ${l.outputPath}`):l?Rd(l,"no outputPath is stored for this recovered session"):`Error: Session "${e}" not found.`}let i=of(o,n,r),s=i&&i.length>0?i:n.full?o.getOutput():o.getOutput(r),a=sf(o),d=s.length===0?`${a}${lf(o)}`:`${a}
92
+ (no output yet)`}function Qr(t,e,n={}){let r=sg(n.lines),o=t.resolve(e);if(!o){let l=t.getPersistedSession(e);if(l?.outputPath&&ds(l.outputPath))try{let u=al(l.outputPath,n,r).join(`
93
+ `),m=dl(l,mg(l));return u?`${m}
94
+ ${u}`:`${m}
95
+ (output file was empty)`}catch(u){let m=u instanceof Error?u.message:String(u);return`Error: Session "${e}" was cleaned up (expired) and output file could not be read: ${m}`}return l?.outputPath?il(l,`output file is missing at ${l.outputPath}`):l?il(l,"no outputPath is stored for this recovered session"):`Error: Session "${e}" not found.`}let i=cg(o,n,r),s=i&&i.length>0?i:n.full?o.getOutput():o.getOutput(r),a=pg(o),d=s.length===0?`${a}${gg(o)}`:`${a}
91
96
  ${s.join(`
92
- `)}`;if(o.pendingPlanApproval&&o.planFilePath)try{if(Ui(o.planFilePath)){let l=Ad(o.planFilePath,"utf-8"),u="─".repeat(60);return`${d}
97
+ `)}`;if(o.pendingPlanApproval&&o.planFilePath)try{if(ds(o.planFilePath)){let l=sl(o.planFilePath,"utf-8"),u="─".repeat(60);return`${d}
93
98
  ${u}
94
99
  Plan file: ${o.planFilePath}
95
100
  ${u}
96
- ${l}`}}catch{}return d}function Nr(t,e="all",n,r={}){let o=t.listPersistedSessions()??[],s=uf(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()-Zm;s=s.filter(d=>(d.startedAt??0)>=a)}else s=s.slice(0,Ym);return s.length===0?"No sessions found.":s.map(a=>Ka(a)).join(`
101
+ ${l}`}}catch{}return d}function Jr(t,e="all",n,r={}){let o=t.listPersistedSessions()??[],s=hg(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()-ig;s=s.filter(d=>(d.startedAt??0)>=a)}else s=s.slice(0,og);return s.length===0?"No sessions found.":s.map(a=>Pd(a)).join(`
97
102
 
98
- `)}function uf(t,e){let n=new Map;for(let r of e){if(!ef(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=Vi(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:nf(r.worktreeState,o?.worktreeState),worktreeLifecycle:rf(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 cf(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 Td(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=cf(n),o=t?.workspaceDir?at(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:Nr(v,r,o,{full:i})}]}}}}re();U();function Lr(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 pf(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 Cd(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?pf(n)?{content:[{type:"text",text:Lr(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();U();function mf(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Br(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?mf(n)?{content:[{type:"text",text:Wr(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();U();ae();ee();var ff=10;function Gi(t){return t instanceof Error?t.message:String(t)}function gt(t){return j(t)??t.harnessSessionId??"unknown-session"}function gf(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return lr(t)??j(t)??O(t)}function Md(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!O(t)}function hf(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 Rn(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='${gt(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='${gt(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='${gt(t)}', fork_session=true, prompt='<new task>').`:`Use agent_respond(session='${gt(t)}', message='<next instruction>') to continue the running session.`,o=n?` ${n}`:"";return{text:`Resume unavailable for session ${t.name} [${gt(t)}] (${e}).${o} ${r}`,isError:!0}}async function _d(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:lr(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} [${gt(e)}]: ${Gi(r)}`,isError:!0}}}var yf=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
103
+ `)}function hg(t,e){let n=new Map;for(let r of e){if(!ag(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=ls(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:lg(r.worktreeState,o?.worktreeState),worktreeLifecycle:ug(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 yg(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 ll(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=yg(n),o=t?.workspaceDir?ft(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:Jr(v,r,o,{full:i})}]}}}}re();K();function Yr(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 kg(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 ul(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?kg(n)?{content:[{type:"text",text:Yr(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 Sg(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Zr(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?Sg(n)?{content:[{type:"text",text:Qr(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();oe();ee();var vg=10;function cs(t){return t instanceof Error?t.message:String(t)}function Pt(t){return G(t)??t.harnessSessionId??"unknown-session"}function wg(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return Pr(t)??G(t)??F(t)}function cl(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!F(t)}function Pg(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 Mn(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 pl(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:Pr(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)}]: ${cs(r)}`,isError:!0}}}var bg=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
99
104
 
100
- `;function $d(t){let e=t?.replace(/\s+/g," ").trim();if(e)return de(e,240)}function ji(t){if(t.approvalState==="changes_requested"&&!Fr(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 Fr(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function kf(t){return ji(t)?!1:Fr(t)||t.currentPermissionMode==="plan"}function Sf(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 vf(t){return(t.planDecisionVersion??0)+1}function Ed(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:vf(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 Dd(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function Hi(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=Ed(o,"rejected");return n?(Dd(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 zi(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=Ed(o,"changes_requested");n&&Dd(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function wf(t,e,n,r={}){let o=vn(e);if(!(o.kind==="resume"||Md(e)))return;let s=!!(r.approve&&kf(e)),a=s?$d(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?_d(t,e,n):Rn(e,o.reason);let d={prompt:s?yf+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:gf(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 Rn(e,"missing_backend_state",`Backend resume failed: ${Gi(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"}:vn(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?hf(e.message):void 0;if(s==="approve")return Pe(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return zi(t,n?.id??r?.sessionId??e.session);if(s==="reject")return Hi(t,n?.id??r?.sessionId??e.session);if(e.approve){let d=ji(o);if(d)return{text:d,isError:!0}}if(i.kind==="resume"||Md(o)){let d=await wf(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(d)return d}else{if(i.kind==="relaunch")return _d(t,o,e.message);if(i.kind==="unavailable")return Rn(o,i.reason)}if(!n)return Sn(r)?Rn(r,"completed"):{text:`Error: Session ${r.name} [${gt(r)}] is not running (status: ${r.status}). Cannot send a message to a non-running session.`,isError:!0};if(n.status!=="running")return Sn(n)?Rn(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=W.maxAutoResponds??ff;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=ji(n);if(m)return{text:m,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let h=de(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${h}"`,"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(`
101
- `)}}let l=!1;e.interrupt&&(l=await n.interrupt());let u=!!(e.approve&&Fr(n)),c=u?$d(e.approvalRationale):void 0,p="";if(e.approve&&Fr(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=c):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?p=`
105
+ `;function ml(t){let e=t?.replace(/\s+/g," ").trim();if(e)return de(e,240)}function us(t){if(t.approvalState==="changes_requested"&&!Xr(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 Xr(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function Rg(t){return us(t)?!1:Xr(t)||t.currentPermissionMode==="plan"}function Ag(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 Ig(t){return(t.planDecisionVersion??0)+1}function fl(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:Ig(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 gl(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function ps(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=fl(o,"rejected");return n?(gl(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 ms(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=fl(o,"changes_requested");n&&gl(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function xg(t,e,n,r={}){let o=xn(e);if(!(o.kind==="resume"||cl(e)))return;let s=!!(r.approve&&Rg(e)),a=s?ml(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?pl(t,e,n):Mn(e,o.reason);let d={prompt:s?bg+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:wg(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.notifyResumedLaunch(l),{text:`Resume started for session ${l.name} [${l.id}]. Use agent_output to see the response.`})}catch(d){return Mn(e,"missing_backend_state",`Backend resume failed: ${cs(d)}`)}}async function Ae(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"}:xn(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?Pg(e.message):void 0;if(s==="approve")return Ae(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return ms(t,n?.id??r?.sessionId??e.session);if(s==="reject")return ps(t,n?.id??r?.sessionId??e.session);if(e.approve){let d=us(o);if(d)return{text:d,isError:!0}}if(i.kind==="resume"||cl(o)){let d=await xg(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(d)return d}else{if(i.kind==="relaunch")return pl(t,o,e.message);if(i.kind==="unavailable")return Mn(o,i.reason)}if(!n)return In(r)?Mn(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 In(n)?Mn(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=L.maxAutoResponds??vg;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 f=us(n);if(f)return{text:f,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let c=de(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${c}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let f=de(e.message,80);return{text:[`Pending input answered for session ${n.name} [${n.id}].`,` Message: "${f}"`,"Use agent_output to see the response."].join(`
106
+ `)}}let l=!1;e.interrupt&&(l=await n.interrupt());let u=!!(e.approve&&Xr(n)),m=u?ml(e.approvalRationale):void 0,p="";if(e.approve&&Xr(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=m):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?p=`
102
107
  ℹ️ approve=true was set but session is already in bypassPermissions mode.`:e.approve?p=`
103
108
  ⚠️ approve=true was set but session has no pending plan approval.`:(n.pendingPlanApproval||n.approvalState==="changes_requested")&&(p=`
104
- ℹ️ 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&&Sf(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(`
105
- `)}}catch(d){return{text:`Error sending message to session ${n.name} [${n.id}]: ${Gi(d)}`,isError:!0}}}function Pf(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 Od(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(!Pf(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();U();function bf(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Wd(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(!bf(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();U();function Rf(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Nd(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(!Rf(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();U();ae();var Qi=["off","manual","ask","delegate","auto-merge","auto-pr"],qr=new Set(Qi),Af=["pr-required","pr-allowed","never-pr","manual"],Ld=new Set(Af),If=["low","medium","high","xhigh","max"],Bd=new Set(If);function xf(t){return typeof t=="string"&&qr.has(t)}var Tf=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 Cf(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||xf(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=At(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 _f(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 Fd(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(Tf),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 Cf(n)?_f(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}re();U();function qd(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:cr(r,o)}]}}}}re();U();Ft();import{execFileSync as $f}from"child_process";var Yi=[{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."}],Ef=new Map(Yi.map(t=>[t.policy,t]));function An(t){return t?Yi:Yi.filter(e=>e.policy==="never-pr"||e.policy==="manual")}function Kd(t){return Ef.get(t)??{policy:t,label:t,title:t,description:"Custom repo integration policy."}}function Vt(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 Zi(t){let{policy:e,prAvailable:n}=t;return{merge:e!=="pr-required"&&e!=="manual",pr:e!=="never-pr"&&e!=="manual"&&n}}function Ji(t,e){try{return $f("git",e,{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Ud(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 Df(t){return Ud(t)?.startsWith("https://github.com/")?"github":"unsupported"}function In(t){let e=Ji(t,["rev-parse","--show-toplevel"]);if(!e)return;let n=Ji(e,["remote","get-url","origin"])??Ji(e,["remote","get-url","upstream"]),r=Ud(n),o=Df(r);return{key:r?`${e}|${r}`:e,repoRoot:e,remoteUrl:r,provider:o}}function Vd(t){if(t?.remoteUrl)return t.remoteUrl==="https://github.com/goldmar/openclaw-code-agent"?"pr-required":void 0}function Xi(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 es(t){return t.provider==="github"&&we()}function jd(t){let e=t.requestedStrategy,n=Zi(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 ts(t,e,n=t.provider==="github"){let r=An(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(`
106
- `)}function Of(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function xn(t){return t?[`Repo policy: ${t.policy}`,`Repo: ${t.repoRoot}`,`Provider: ${t.provider}`,...t.remoteUrl?[`Remote: ${t.remoteUrl}`]:[],`Updated: ${t.updatedAt}`].join(`
107
- `):"No stored repo policy found."}function Gd(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(`
109
+ ℹ️ 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&&Ag(t,n),u)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let f=de(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${f}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let y=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: "${y}"`,p,"Use agent_output to see the response."].filter(Boolean).join(`
110
+ `)}}catch(d){return{text:`Error sending message to session ${n.name} [${n.id}]: ${cs(d)}`,isError:!0}}}function Tg(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 hl(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(!Tg(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, message, interrupt?, userInitiated?, approve?, approval_rationale? }."}]};let r=await Ae(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 Cg(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function yl(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(!Cg(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 Mg(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function kl(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(!Mg(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();oe();var fs=["off","manual","ask","delegate","auto-merge","auto-pr"],eo=new Set(fs),_g=["pr-required","pr-allowed","never-pr","manual"],Sl=new Set(_g),$g=["low","medium","high","xhigh","max"],vl=new Set($g);function Eg(t){return typeof t=="string"&&eo.has(t)}var Dg=g.Union(fs.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 Og(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||Eg(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 Ng(t,e){let n=Nt(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 Wg(t,e){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=Ng(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 wl(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(Dg),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 Og(n)?Wg(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}re();K();function Pl(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:Rr(r,o)}]}}}}re();K();zt();import{execFileSync as Lg}from"child_process";var hs=[{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."}],Fg=new Map(hs.map(t=>[t.policy,t]));function _n(t){return t?hs:hs.filter(e=>e.policy==="never-pr"||e.policy==="manual")}function bl(t){return Fg.get(t)??{policy:t,label:t,title:t,description:"Custom repo integration policy."}}function Yt(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 ys(t){let{policy:e,prAvailable:n}=t;return{merge:e!=="pr-required"&&e!=="manual",pr:e!=="never-pr"&&e!=="manual"&&n}}function gs(t,e){try{return Lg("git",e,{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Rl(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 Bg(t){return Rl(t)?.startsWith("https://github.com/")?"github":"unsupported"}function $n(t){let e=gs(t,["rev-parse","--show-toplevel"]);if(!e)return;let n=gs(e,["remote","get-url","origin"])??gs(e,["remote","get-url","upstream"]),r=Rl(n),o=Bg(r);return{key:r?`${e}|${r}`:e,repoRoot:e,remoteUrl:r,provider:o}}function Al(t){if(t?.remoteUrl)return t.remoteUrl==="https://github.com/goldmar/openclaw-code-agent"?"pr-required":void 0}function ks(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 Ss(t){return t.provider==="github"&&ge()}function Il(t){let e=t.requestedStrategy,n=ys(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 vs(t,e,n=t.provider==="github"){let r=_n(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(`
111
+ `)}function qg(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function En(t){return t?[`Repo policy: ${t.policy}`,`Repo: ${t.repoRoot}`,`Provider: ${t.provider}`,...t.remoteUrl?[`Remote: ${t.remoteUrl}`]:[],`Updated: ${t.updatedAt}`].join(`
112
+ `):"No stored repo policy found."}function xl(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(`
108
113
  `)}]}}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(`
109
- `)}]}}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(!Of(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=Vt(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:[xn(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(`
110
- `)}]}}return d.kind==="launched"?{content:[{type:"text",text:[xn(a),"",d.text].join(`
111
- `)}]}:d.kind==="ambiguous"?{content:[{type:"text",text:[xn(a),"",`Repo policy saved, but ${d.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
112
- `)}]}:{content:[{type:"text",text:xn(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:xn(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(`
113
- `)}]}}}}re();ae();U();ke();Tn();Mn();import{existsSync as zr}from"fs";function Nf(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Lf(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 Bf(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 Qr(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(!Nf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=Gt(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.`}]};zr(s)||`${s}${a}`;let l=a;if(!zr(a))return{content:[{type:"text",text:`Error: originalWorkdir "${a}" does not exist.`}]};let u=n.base_branch??Ee(l),c=u,p=n.strategy??"merge",f=n.push===!0,m=n.delete_branch!==!1,h=v.resolveRepoPolicy(l);if(h?.policy==="pr-required")return{content:[{type:"text",text:`❌ Merge blocked: repo policy requires a pull request for ${h.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((zr(s)?Pn(l,d,c):void 0)===0&&mt(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${d} has no commits ahead of ${c}.`,`Worktree: ${s}`,"Resume or inspect the session, then commit real task changes or clean temporary files before retrying agent_merge."].join(`
114
- `)}]};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=Ke(l,d,u),M=$r(l,d,c,p,s),R=Kt(M);if(M.success){let y=Lf({mergeResult:M,repoDir:l,baseBranch:c});if(f&&!_r(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.",...y,...R]}),S={content:[{type:"text",text:Oe(L,M)}]};return}let w=!1,T=!1,K=!zr(s);T=K?!0:me(l,s),Cr(l),m&&(w=ye(l,d));let E=Bf({deleteBranchRequested:m,branchDeleted:w,worktreeCleanedUp:T,worktreeAlreadyAbsent:K});if(b){let L=new Date().toISOString();for(let G of Cn({...r,persistedSession:b}))v.updatePersistedSession(G,{...jt({worktreeBaseBranch:u,worktreePrTargetRepo:b.worktreePrTargetRepo,worktreePushRemote:b.worktreePushRemote},{mergedAt:L,updatedAt:L,resolvedAt:L,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let C=ft({kind:"merge",branch:d,base:u,filesChanged:A?.filesChanged,insertions:A?.insertions,deletions:A?.deletions});v.notifyWorktreeOutcome(r.notificationTarget,C,{detailLines:[M.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",f?`Pushed ${c}.`:`Did not push ${c}; push was not requested.`,E.detailLine,...y,...R]});let q=`✅ ${M.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${d} → ${c}.${f?" Pushed.":""}${E.summaryFragment}`;M.stashPopConflict?q+=`
115
- ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${M.stashRef??"stash@{0}"}\` in ${l} to review stashed changes.`:M.stashed&&(q+=`
116
- (Pre-existing changes on ${c} were auto-stashed and restored.)`),q=Oe(q,M),S={content:[{type:"text",text:q}]}}else if(M.rebaseConflict)S={content:[{type:"text",text:Oe(`⚠️ Rebase conflicts — manual resolution required:
117
-
118
- ${M.error}`,M)}]};else if(M.conflictFiles&&M.conflictFiles.length>0){let y=["Resolve merge conflicts in the following files and commit the resolution:","",...M.conflictFiles.map(w=>`- ${w}`),"",`After resolving, commit with message: "Resolve merge conflicts from ${d}"`].join(`
119
- `);try{let w=v.spawn({prompt:y,workdir:l,name:`${n.session}-conflict-resolver`,harness:ue(),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:Oe(`⚠️ Merge conflicts in ${M.conflictFiles.length} file(s) — spawned conflict resolver session: ${w.name}`,M)}]}}catch(w){S={content:[{type:"text",text:Oe(`❌ Merge conflicts detected, but failed to spawn resolver: ${w instanceof Error?w.message:String(w)}`,M)}]}}}else{let y=M.dirtyError?`❌ Merge blocked: ${M.error}`:`❌ Merge failed: ${M.error??"unknown error"}`;S={content:[{type:"text",text:Oe(y,M)}]}}}),S}}}eo();re();U();ee();ke();Mn();function Qf(t){return!!t&&typeof t=="object"}function ol(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(!Qf(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=jr(v);if(r&&(a=a.filter(f=>Gr(f,r)),a.length===0)){let f=Gt(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:h,resolvedLifecycle:k}=Vr(v,f,{baseBranch:n.base_branch});if(!k.cleanupSafe){if(s){let S=k.reasons.length>0?k.reasons.map(Hr).join(", "):ht(k.derivedState);l.push(`${f.name} [kept: ${S}]`)}continue}if(d.push(`${f.name} (${ht(k.derivedState)})`),!i)try{let S=f.workdir;if(!((m??h)&&ce(m??h))&&f.worktreePath&&me(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,M=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??M:m.worktreeMergedAt,worktreeLifecycle:{...m.worktreeLifecycle??k.lifecycle,state:A,updatedAt:M,resolvedAt:m.worktreeLifecycle?.resolvedAt??R??M,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} (${ht(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(`
120
- `)}]}}}}re();U();Mn();function Jf(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 il(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(!Jf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n&&typeof n=="object"?n.session:void 0,o=jr(v);if(r&&(o=o.filter(s=>Gr(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}=Vr(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:${ht(d.lifecycle.state)}`),d.derivedState!==d.lifecycle.state&&i.push(` Derived: ${ht(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(Hr).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
121
- `).trim()}]}}}}re();U();ae();nr();import{existsSync as Yf}from"fs";function Zf(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function to(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||W.defaultWorkdir||process.cwd();if(!Yf(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=Zf(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??ue(),a=t.model??bt(s),d=Fe(s,a),l=Vn(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&&!$t(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&&!er(s,d,l))return{kind:"error",text:`Error: Model "${a}" is not allowed. Permitted models: ${l?.join(", ")}`};let u=tr(s,d,l),c=e.sessionKey||void 0,p=jn(e),f=cn(e,p||at(r)),m=At(e,f,c);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:u,reasoningEffort:Je(s),fastMode:Rt(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 no(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(`
122
- `)}function Xf(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function sl(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(!Q)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!Xf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=to({goal:n.goal,verifierCommands:n.verifier_commands,name:n.name,workdir:n.workdir,model:n.model,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,maxIterations:n.max_iterations,permissionMode:n.permission_mode,harness:n.harness,goalMode:n.goal_mode,completionPromise:n.completion_promise},t);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};try{let o=await Q.launchTask({goal:r.goal,name:r.name,workdir:r.workdir,model:r.model,reasoningEffort:r.reasoningEffort,fastMode:r.fastMode,systemPrompt:r.systemPrompt,allowedTools:r.allowedTools,maxIterations:r.maxIterations,permissionMode:r.permissionMode,loopMode:r.loopMode,completionPromise:r.completionPromise,originChannel:r.originChannel,originThreadId:r.originThreadId,originAgentId:r.originAgentId,originSessionKey:r.originSessionKey,route:r.route,harness:r.harness,verifierCommands:r.verifierCommands});return{content:[{type:"text",text:no(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}re();function ds(t,e){return t.split(`
123
- `).map(n=>`${e}${n}`)}function al(t,e){return t.length<=e?t:`${t.slice(0,e-3).trimEnd()}...`}function eg(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(`
124
- `);return o.length<=n?o:`...${o.slice(-(n-3))}`}function tg(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=>al(o,180))}function ng(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=>al(n,180))}function ro(t){let e=[],n=ng(t.verifierSummary),r=tg(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(`
125
- `)}function ls(t){if(t)return{phase:t.phase,awaitingInput:t.isAwaitingInput??!!t.pendingInputState,latestOutput:eg(t.getOutput(20))}}function us(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(...ds(n," ")),t.lastVerifierSummary&&(o.push(" Last verifier:"),o.push(...ds(t.lastVerifierSummary," "))),e?.latestOutput&&(o.push(" Latest activity:"),o.push(...ds(e.latestOutput," "))),t.waitingForUserReason&&o.push(` Waiting on user: ${t.waitingForUserReason}`),t.failureReason&&o.push(` Failure: ${t.failureReason}`),o.join(`
126
- `)}var be="Error: GoalController not initialized. The code-agent service must be running.";function oo(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 us(i,ls(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 us(i,ls(s))}).join(`
127
-
128
- `)}function io(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 so(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.`}}U();function dl(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(!Q)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:oo(Q,o=>v?.resolve(o),r)}]}}}}re();U();function rg(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function ll(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(!Q)return{content:[{type:"text",text:be}]};if(!rg(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=Q.stopTask(n.task);return{content:[{type:"text",text:io(r,n.task)}]}}}}re();U();function og(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function ul(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(!Q)return{content:[{type:"text",text:be}]};if(!og(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=Q.editTask(n.task,n.goal);return{content:[{type:"text",text:so(r,n.task)}]}}}}U();eo();import{createHash as ig}from"crypto";var te="code-agent";var sg=new Set(["1","true","yes","on"]);function ps(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&sg.has(t))}function Re(t){if(!(typeof t!="string"||t.length===0))return ig("sha256").update(t).digest("hex").slice(0,12)}function cl(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=cl(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>Re(cl(r))):void 0,buttonStyles:n.length>0?n.map(r=>typeof r.style=="string"?r.style:void 0):void 0}}function nt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function ml(t){let e=nt(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(n)return n.map(r=>nt(r)?.type).filter(r=>typeof r=="string"&&r.length>0)}function fl(t){let e=nt(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(!n)return;let r=n.map(o=>{let i=nt(o);return i?.type!=="buttons"||!Array.isArray(i.buttons)?[]:i.buttons}).filter(o=>o.length>0);return r.length>0?r:void 0}function ms(t){let e=fl(t);return{presentationBlockTypes:ml(t),...Y(e)}}function fs(t){let e=nt(t),n=e?.interactive,r=nt(e?.channelData),o=nt(r?.telegram),i=Array.isArray(o?.buttons)?o.buttons:void 0;return{renderedPayloadKeys:e?Object.keys(e).sort():void 0,interactiveBlockTypes:ml(n),...pl("interactive",Y(fl(n))),...pl("telegramChannelData",Y(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function gl(t){let e=nt(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:cs(e.messageId),chatId:cs(e.chatId),telegramThreadId:cs(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function cs(t){return typeof t=="string"||typeof t=="number"?t:void 0}function pl(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 F(t,e){if(!ps())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:te,...n})}`}var gs=new Set,hl="⚠️ Could not submit that answer. The question prompt is still active; try again or reply with the answer.",Dn=new Map;async function vl(t){try{await t}catch(e){let n=e instanceof Error?e.message:String(e);`${n}`}}async function yl(t,e,n){if(!t)return n();for(;;){let o=Dn.get(t)?.operation;if(!o)break;await vl(o)}let r=Promise.resolve().then(n);Dn.set(t,{operation:r,tokenId:e});try{return await r}finally{Dn.get(t)?.operation===r&&Dn.delete(t)}}function ag(t){let e=t.trim().replace(new RegExp(`^${te}:`),"");return e||null}function dg(t){return t.trim().startsWith(`${te}:`)}async function ao(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(kt(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 Ge(t,e=!1){await X(t,{alreadyAcknowledged:e,forceTelegramMarkupEdit:t.channel==="telegram"})}function uo(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 kl(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return ks(uo(t))}function ks(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function co(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function lg(t){if(co(t.kind))return`${t.sessionId}:v${t.planDecisionVersion??"unknown"}`}function ug(t){return t?t.approvalState==="approved"||!t.pendingPlanApproval:!1}function cg(...t){let e;for(let n of t)n!=null&&(e=e==null?n:Math.max(e,n));return e}function pg(t){if(t.actionablePlanDecisionVersion!=null)return t.actionablePlanDecisionVersion;let e=cg(t.approvalPromptRequiredVersion,t.approvalPromptVersion);return e??t.canonicalPlanPromptVersion??t.planDecisionVersion}function hs(t,e){if(!co(t.kind))return;if(!e)return"This plan decision is stale because the session is no longer available.";let n=pg(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 wl(t,...e){return e.find(n=>typeof n=="string"&&t(n))}function lo(...t){return wl(e=>e.trim().length>0,...t)}function Sl(...t){return wl(dg,...t)}function mg(t){let e="callback"in t?Sl(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=Sl(n?.data,n?.callback_data,n?.callbackData);if(r)return r;let o="callback"in t?lo(t.callback?.payload):void 0;if(o)return o;let i=lo(n?.payload);return i||(("callback"in t?lo(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0)??lo(n?.data,n?.callback_data,n?.callbackData)??"")}function On(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,On(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,On(n.cause,e),On(n.response,e),On(n.payload,e)].filter(Boolean).join(" ")}function kt(t){return/message is not modified/i.test(On(t))}function fg(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function yt(t){if(typeof t.clearButtons=="function")try{await t.clearButtons()}catch(e){if(kt(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 yt(n),{textDelivered:!0}}catch(a){if(kt(a))return await yt(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 yt(n),{textDelivered:!1}}catch(a){if(kt(a))return await yt(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 yt(n),{textDelivered:!1}}catch(a){if(kt(a))return await yt(n),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}return await yt(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(kt(s))return{textDelivered:typeof i=="string"};if(fg(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(kt(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 gg(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 N(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}var ys=["plan-approve","plan-request-changes","plan-reject"];function hg(t){switch(t){case"plan-approve":return"Approve";case"plan-request-changes":return"Revise";case"plan-reject":return"Reject";default:return"Continue"}}function yg(t){switch(t){case"plan-approve":return"primary";case"plan-reject":return"danger";default:return"secondary"}}function kg(t,e){let n=t,o=(typeof n?.listActiveActionTokens=="function"?ys.flatMap(a=>n.listActiveActionTokens?.(a)??[]):[e]).filter(a=>co(a.kind)&&a.sessionId===e.sessionId&&(e.planDecisionVersion==null||a.planDecisionVersion==null||a.planDecisionVersion===e.planDecisionVersion)).sort((a,d)=>ys.indexOf(a.kind)-ys.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:hg(a.kind),callbackData:`${te}:${a.id}`,style:yg(a.kind)}));return s.length>0?[s]:void 0}async function Sg(t,e,n,r){if(t.channel!=="telegram"){await N(t,e);return}let o=kg(n,r);await t.respond.reply({text:o?`${e}
129
-
130
- Approval is still pending. Try again below.`:e,...o?{buttons:o}:{}})}function Pl(t="telegram",e={}){let n=e.makeAgentMergeTool??Qr,r=e.makeAgentPrTool??En;return F("callback_handler_registered",{channel:t,namespace:te}),{channel:t,namespace:te,handler:async o=>{let i=await gg(o);if(!o.auth.isAuthorizedSender)return await N(o,"⛔ Unauthorized."),{handled:!0};let s=mg(o),a=ag(s);if(F("callback_received",{channel:o.channel,namespace:te,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:Re(a),isAuthorizedSender:o.auth.isAuthorizedSender}),!a)return await N(o,"⚠️ Unrecognized callback payload."),{handled:!0};if(!v)return await N(o,"⚠️ Code agent service not running."),{handled:!0};let d=v.getActionToken(a);if(F("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 N(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 N(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=hs(d,u);if(F("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 co(d.kind)?await Ge(o,i):await X(o,{alreadyAcknowledged:i}),await N(o,`⚠️ ${p}`),{handled:!0};if(d.kind==="question-answer"){if(d.optionIndex==null)return await X(o,{alreadyAcknowledged:i}),await N(o,"⚠️ Invalid question-answer action."),{handled:!0};if(gs.has(a))return await N(o,"⚠️ That answer is already being submitted. If the question remains active, try again."),{handled:!0};gs.add(a);let h=!1;try{h=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 N(o,hl),{handled:!0}}finally{gs.delete(a)}if(!h)return await N(o,hl),{handled:!0};let k=v.consumeActionToken(a);return F("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 N(o,"✅ Answer submitted."),{handled:!0}):(await X(o,{alreadyAcknowledged:i}),await N(o,"✅ Answer submitted."),{handled:!0})}let f=lg(d);if(f)for(;;){let h=Dn.get(f);if(!h)break;if(h.tokenId===a)return await Ge(o,i),await N(o,"⚠️ This plan decision is already being processed."),{handled:!0};await vl(h.operation);let k=v.getActionToken(a);if(!k)return await Ge(o,i),o.channel!=="telegram"&&await N(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=hs(k,u),F("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 Ge(o,i),await N(o,`⚠️ ${p}`),{handled:!0};d=k}if(d.kind==="plan-approve"){let h=d,k=!1,S=async(M=!1)=>{k||!M&&o.channel!=="telegram"||(await Ge(o,i),k=!0)},b=await yl(f,a,async()=>(await S(),Pe(v,{session:h.sessionId,message:"Approved. Go ahead.",approve:!0,userInitiated:!0})));if(b.isError){let M=v.resolve?.(h.sessionId)??v.getPersistedSession?.(h.sessionId),R=ug(M);if(R){let y=v.consumeActionToken(a);F("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),consumed:!!y,actionKind:y?.kind,sessionId:y?.sessionId??h.sessionId,planDecisionVersion:y?.planDecisionVersion,approvalAppliedAfterError:!0}),await S(!0)}return R?await N(o,`⚠️ ${b.text}`):await Sg(o,`⚠️ ${b.text}`,v,h),{handled:!0}}let A=v.consumeActionToken(a);return F("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),consumed:!!A,actionKind:A?.kind,sessionId:A?.sessionId??h.sessionId,planDecisionVersion:A?.planDecisionVersion}),A?(await S(!0),{handled:!0}):(await S(!0),o.channel!=="telegram"&&await N(o,"⚠️ This action is stale or has already been used."),{handled:!0})}if(d.kind==="plan-reject"||d.kind==="plan-request-changes")return await yl(f,a,async()=>{let h=v.getActionToken(a);if(!h)return await Ge(o,i),o.channel!=="telegram"&&await N(o,"⚠️ This action is stale or has already been used."),{handled:!0};l=h.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),c=u?.name??l;let k=hs(h,u);if(F("callback_plan_validation_completed",{channel:o.channel,namespace:te,tokenHash:Re(a),actionKind:h.kind,sessionId:l,sessionName:c,planDecisionVersion:h.planDecisionVersion,valid:!k,afterPlanDecisionLock:!0}),k)return await Ge(o,i),await N(o,`⚠️ ${k}`),{handled:!0};let S=v.consumeActionToken(a);if(F("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 Ge(o,i),o.channel!=="telegram"&&await N(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(await Ge(o,i),S.kind==="plan-reject"){let b=Hi(v,l);await N(o,`❌ ${b.text}`)}else{let b=zi(v,l);await N(o,`✏️ ${b.text}`)}return{handled:!0}});let m=v.consumeActionToken(a);if(F("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 N(o,"⚠️ This action is stale or has already been used."),{handled:!0};switch(m.kind){case"worktree-merge":{let h=await n().execute("callback",{session:l}),k=uo(h);if(kl(h)){await ao(o,i);break}await N(o,k);break}case"worktree-decide-later":{let h=v.snoozeWorktreeDecision(l,{notifyUser:!1});if(ks(h)){let S=`⏭️ Snoozed 24h for [${c}]`;await ao(o,i),await N(o,S)}else await N(o,h);break}case"worktree-dismiss":{let h=await v.dismissWorktree(l),k=ks(h);k&&await ao(o,i),await N(o,k?"✅ Discarded":h);break}case"worktree-create-pr":case"worktree-update-pr":{let h=await r().execute("callback",{session:l}),k=uo(h);if(kl(h)){await ao(o,i);break}await N(o,k);break}case"worktree-view-pr":{await X(o,{alreadyAcknowledged:i});let h=v.getPersistedSession?.(l),k=d.targetUrl??h?.worktreePrUrl;await N(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 N(o,"⚠️ This action is missing the plan launch context.");break}let h;try{h=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 N(o,`⚠️ Failed to start planning session: ${S}`);break}await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await N(o,`▶️ Planning session started: ${h.name} [${h.id}]`);break}case"plan-offer-dismiss":{await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await N(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!m.repoPolicy||!m.repoPolicyWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await N(o,"⚠️ This action is missing the repo policy context.");break}if(!m.launchPrompt||!m.launchWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await N(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=Vt(m.repoPolicy,S.prAvailable);if(b){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await N(o,`⚠️ ${b}`);break}}}let h=v.setRepoPolicy(m.repoPolicyWorkdir,m.repoPolicy);if(!h){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await N(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 N(o,`⚠️ Repo policy saved, but launch failed: ${b}`);break}await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await N(o,[`✅ Repo policy saved: ${Kd(h.policy).title}.`,"",k].join(`
131
- `));break}case"session-restart":case"session-resume":{await X(o,{alreadyAcknowledged:i});let h=await Pe(v,{session:l,message:"Continue where you left off.",userInitiated:!0});await N(o,h.isError?`⚠️ ${h.text}`:`▶️ ${h.text}`);break}case"view-output":{await X(o,{alreadyAcknowledged:i});let h=await Br().execute("callback",{session:l,lines:50});await N(o,uo(h));break}default:{await X(o,{alreadyAcknowledged:i}),await N(o,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}U();ae();function Qt(t){return bl(t).map(e=>e.value)}function bl(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:vg(n),raw:n,start:r,end:r+n.length}})}function St(t){let[e]=bl(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function vg(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function wg(t){return t instanceof Error?t.message:String(t)}function Pg(t){let e=Qt(t),n,r=e;return e[0]==="--name"&&e[1]&&(n=e[1],r=e.slice(2)),{name:n,prompt:r.join(" ").trim()}}function Rl(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}=Pg(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=ur({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:yr(e)});return{text:v.formatLaunchResult({prompt:o,workdir:i.workdir,harness:i.harness,permissionMode:i.permissionMode??W.permissionMode,planApproval:i.planApproval},s)}}catch(i){let s=wg(i),a=s.includes("Max sessions")?"":`
132
-
133
- Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${a}`}}}})}U();function Al(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:Nr(v,"all",void 0,{full:n})}}})}U();function Il(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:Lr(v,n,"killed")}:{text:"Usage: /agent_kill <name-or-id>"}}})}U();function xl(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>
134
- /agent_respond --interrupt <id-or-name> <message>`};let r=!1,o=n,i=St(o);i?.value==="--interrupt"&&(r=!0,o=i.rest);let s=St(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>"}}})}U();function Tl(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:cr(e,n)}}})}U();function bg(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function Cl(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=St((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(`
114
+ `)}]}}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(!qg(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=Yt(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:[En(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(`
115
+ `)}]}}return d.kind==="launched"?{content:[{type:"text",text:[En(a),"",d.text].join(`
116
+ `)}]}:d.kind==="ambiguous"?{content:[{type:"text",text:[En(a),"",`Repo policy saved, but ${d.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
117
+ `)}]}:{content:[{type:"text",text:En(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:En(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(`
118
+ `)}]}}}}re();oe();K();ve();Dn();Nn();import{existsSync as ao}from"fs";function Kg(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Vg(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 jg(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 lo(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(!Kg(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=Xt(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.`}]};ao(s)||`${s}${a}`;let l=a;if(!ao(a))return{content:[{type:"text",text:`Error: originalWorkdir "${a}" does not exist.`}]};let u=n.base_branch??We(l),m=u,p=n.strategy??"merge",y=n.push===!0,f=n.delete_branch!==!1,c=v.resolveRepoPolicy(l);if(c?.policy==="pr-required")return{content:[{type:"text",text:`❌ Merge blocked: repo policy requires a pull request for ${c.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((ao(s)?Tn(l,d,m):void 0)===0&&vt(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${d} has no commits ahead of ${m}.`,`Worktree: ${s}`,"Resume or inspect the session, then commit real task changes or clean temporary files before retrying agent_merge."].join(`
119
+ `)}]};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=je(l,d,u),x=jr(l,d,m,p,s),R=Jt(x);if(x.success){let k=Vg({mergeResult:x,repoDir:l,baseBranch:m});if(y&&!Vr(l,m)){let D=`⚠️ Merged ${d} → ${m} locally, but failed to push ${m}`;v.notifyWorktreeOutcome(r.notificationTarget,D,{detailLines:[`Branch ${d} was merged into ${m} in the local repository.`,`Pushing ${m} failed; remote state may not include the merge.`,"Cleanup was skipped so the branch/worktree remains available for follow-up.",...k,...R]}),S={content:[{type:"text",text:Le(D,x)}]};return}let P=!1,_=!1,M=!ao(s);_=M?!0:fe(l,s),Ur(l),f&&(P=Se(l,d));let $=jg({deleteBranchRequested:f,branchDeleted:P,worktreeCleanedUp:_,worktreeAlreadyAbsent:M});if(b){let D=new Date().toISOString();for(let V of On({...r,persistedSession:b}))v.updatePersistedSession(V,{...Zt({worktreeBaseBranch:u,worktreePrTargetRepo:b.worktreePrTargetRepo,worktreePushRemote:b.worktreePushRemote},{mergedAt:D,updatedAt:D,resolvedAt:D,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let T=wt({kind:"merge",branch:d,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.",y?`Pushed ${m}.`:`Did not push ${m}; push was not requested.`,$.detailLine,...k,...R]});let B=`✅ ${x.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${d} → ${m}.${y?" Pushed.":""}${$.summaryFragment}`;x.stashPopConflict?B+=`
120
+ ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${x.stashRef??"stash@{0}"}\` in ${l} to review stashed changes.`:x.stashed&&(B+=`
121
+ (Pre-existing changes on ${m} were auto-stashed and restored.)`),B=Le(B,x),S={content:[{type:"text",text:B}]}}else if(x.rebaseConflict)S={content:[{type:"text",text:Le(`⚠️ Rebase conflicts — manual resolution required:
122
+
123
+ ${x.error}`,x)}]};else if(x.conflictFiles&&x.conflictFiles.length>0){let k=["Resolve merge conflicts in the following files and commit the resolution:","",...x.conflictFiles.map(P=>`- ${P}`),"",`After resolving, commit with message: "Resolve merge conflicts from ${d}"`].join(`
124
+ `);try{let P=v.spawn({prompt:k,workdir:l,name:`${n.session}-conflict-resolver`,harness:ue(),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:Le(`⚠️ Merge conflicts in ${x.conflictFiles.length} file(s) — spawned conflict resolver session: ${P.name}`,x)}]}}catch(P){S={content:[{type:"text",text:Le(`❌ Merge conflicts detected, but failed to spawn resolver: ${P instanceof Error?P.message:String(P)}`,x)}]}}}else{let k=x.dirtyError?`❌ Merge blocked: ${x.error}`:`❌ Merge failed: ${x.error??"unknown error"}`;S={content:[{type:"text",text:Le(k,x)}]}}}),S}}}go();re();K();ee();ve();Nn();function rh(t){return!!t&&typeof t=="object"}function jl(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(!rh(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=oo(v);if(r&&(a=a.filter(y=>io(y,r)),a.length===0)){let y=Xt(v,r);if(!y.persistedSession&&!y.activeSession)return{content:[{type:"text",text:`Error: Session "${r}" not found.`}]}}if(n.workdir&&(a=a.filter(y=>y.workdir===n.workdir)),a.length===0)return{content:[{type:"text",text:"No managed worktrees matched the requested scope."}]};let d=[],l=[],u=[],m=[];for(let y of a){let{persistedSession:f,activeSession:c,resolvedLifecycle:h}=ro(v,y,{baseBranch:n.base_branch});if(!h.cleanupSafe){if(s){let S=h.reasons.length>0?h.reasons.map(so).join(", "):bt(h.derivedState);l.push(`${y.name} [kept: ${S}]`)}continue}if(d.push(`${y.name} (${bt(h.derivedState)})`),!i)try{let S=y.workdir;if(!((f??c)&&pe(f??c))&&y.worktreePath&&fe(S,y.worktreePath,{destructive:!1}),y.worktreeBranch&&Se(S,y.worktreeBranch),f){let A=h.derivedState==="merged"||h.derivedState==="released"?h.derivedState:h.lifecycle.state,x=new Date().toISOString(),R=A==="merged"?f.worktreeMergedAt:A==="dismissed"?f.worktreeDismissedAt:void 0;v.updatePersistedSession(y.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeMerged:A==="merged"?!0:f.worktreeMerged,worktreeMergedAt:A==="merged"?f.worktreeMergedAt??x:f.worktreeMergedAt,worktreeLifecycle:{...f.worktreeLifecycle??h.lifecycle,state:A,updatedAt:x,resolvedAt:f.worktreeLifecycle?.resolvedAt??R??x,resolutionSource:f.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??h.lifecycle.baseBranch??f.worktreeBaseBranch,targetRepo:f.worktreePrTargetRepo,pushRemote:f.worktreePushRemote,notes:h.reasons}})}u.push(`${y.name} (${bt(h.derivedState)})`)}catch(S){m.push(`${y.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 (${m.length}): ${m.join(", ")||"(none)"}`)),{content:[{type:"text",text:p.join(`
125
+ `)}]}}}}re();K();Nn();function oh(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 Gl(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(!oh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n&&typeof n=="object"?n.session:void 0,o=oo(v);if(r&&(o=o.filter(s=>io(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}=ro(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:${bt(d.lifecycle.state)}`),d.derivedState!==d.lifecycle.state&&i.push(` Derived: ${bt(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(so).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
126
+ `).trim()}]}}}}re();K();oe();gr();import{existsSync as ih}from"fs";function sh(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function ho(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||L.defaultWorkdir||process.cwd();if(!ih(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=sh(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??ue(),a=t.model??Dt(s),d=Ke(s,a),l=er(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&&!Vt(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.6-sol".`};if(d&&!mr(s,d,l))return{kind:"error",text:`Error: Model "${a}" is not allowed. Permitted models: ${l?.join(", ")}`};let u=fr(s,d,l),m=e.sessionKey||void 0,p=tr(e),y=yn(e,p||ft(r)),f=Nt(e,y,m);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:u,reasoningEffort:rt(s),fastMode:Ot(s),systemPrompt:t.systemPrompt,allowedTools:t.allowedTools,maxIterations:t.maxIterations,permissionMode:t.permissionMode??"bypassPermissions",harness:s,loopMode:i,completionPromise:t.completionPromise,originChannel:y,originThreadId:f?.threadId,originAgentId:e.agentId||void 0,originSessionKey:m,route:f,verifierCommands:o}}function yo(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 /agent_goal_status to follow progress or /agent_goal_stop to terminate the task in chat."].join(`
127
+ `)}function ah(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function Hl(t){return{name:"agent_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(!J)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!ah(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=ho({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 J.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:yo(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}re();function Cs(t,e){return t.split(`
128
+ `).map(n=>`${e}${n}`)}function zl(t,e){return t.length<=e?t:`${t.slice(0,e-3).trimEnd()}...`}function dh(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(`
129
+ `);return o.length<=n?o:`...${o.slice(-(n-3))}`}function lh(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=>zl(o,180))}function uh(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=>zl(n,180))}function ko(t){let e=[],n=uh(t.verifierSummary),r=lh(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(`
130
+ `)}function Ms(t){if(t)return{phase:t.phase,awaitingInput:t.isAwaitingInput??!!t.pendingInputState,latestOutput:dh(t.getOutput(20))}}function _s(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(...Cs(n," ")),t.lastVerifierSummary&&(o.push(" Last verifier:"),o.push(...Cs(t.lastVerifierSummary," "))),e?.latestOutput&&(o.push(" Latest activity:"),o.push(...Cs(e.latestOutput," "))),t.waitingForUserReason&&o.push(` Waiting on user: ${t.waitingForUserReason}`),t.failureReason&&o.push(` Failure: ${t.failureReason}`),o.join(`
131
+ `)}var Ie="Error: GoalController not initialized. The code-agent service must be running.";function So(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 _s(i,Ms(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 _s(i,Ms(s))}).join(`
132
+
133
+ `)}function vo(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 wo(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 Ql(t){return{name:"agent_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(!J)return{content:[{type:"text",text:Ie}]};let r=n&&typeof n=="object"&&typeof n.task=="string"?n.task:void 0;return{content:[{type:"text",text:So(J,o=>v?.resolve(o),r)}]}}}}re();K();function ch(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function Jl(t){return{name:"agent_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(!J)return{content:[{type:"text",text:Ie}]};if(!ch(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=J.stopTask(n.task);return{content:[{type:"text",text:vo(r,n.task)}]}}}}re();K();function ph(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function Yl(t){return{name:"agent_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(!J)return{content:[{type:"text",text:Ie}]};if(!ph(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=J.editTask(n.task,n.goal);return{content:[{type:"text",text:wo(r,n.task)}]}}}}K();go();var $s=new Set,Zl="⚠️ Could not submit that answer. The question prompt is still active; try again or reply with the answer.",Un=new Map;async function nu(t){try{await t}catch(e){let n=e instanceof Error?e.message:String(e);`${n}`}}async function Xl(t,e,n){if(!t)return n();for(;;){let o=Un.get(t)?.operation;if(!o)break;await nu(o)}let r=Promise.resolve().then(n);Un.set(t,{operation:r,tokenId:e});try{return await r}finally{Un.get(t)?.operation===r&&Un.delete(t)}}function mh(t){let e=t.trim().replace(new RegExp(`^${te}:`),"");return e||null}function fh(t){return t.trim().startsWith(`${te}:`)}async function Po(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(At(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 Je(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 eu(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return Os(Ro(t))}function Os(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function Ao(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function gh(t){if(Ao(t.kind))return`${t.sessionId}:v${t.planDecisionVersion??"unknown"}`}function hh(t){return t?t.approvalState==="approved"||!t.pendingPlanApproval:!1}function yh(...t){let e;for(let n of t)n!=null&&(e=e==null?n:Math.max(e,n));return e}function kh(t){if(t.actionablePlanDecisionVersion!=null)return t.actionablePlanDecisionVersion;let e=yh(t.approvalPromptRequiredVersion,t.approvalPromptVersion);return e??t.canonicalPlanPromptVersion??t.planDecisionVersion}function Es(t,e){if(!Ao(t.kind))return;if(!e)return"This plan decision is stale because the session is no longer available.";let n=kh(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 ru(t,...e){return e.find(n=>typeof n=="string"&&t(n))}function bo(...t){return ru(e=>e.trim().length>0,...t)}function tu(...t){return ru(fh,...t)}function Sh(t){let e="callback"in t?tu(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=tu(n?.data,n?.callback_data,n?.callbackData);if(r)return r;let o="callback"in t?bo(t.callback?.payload):void 0;if(o)return o;let i=bo(n?.payload);return i||(("callback"in t?bo(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0)??bo(n?.data,n?.callback_data,n?.callbackData)??"")}function Kn(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,Kn(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,Kn(n.cause,e),Kn(n.response,e),Kn(n.payload,e)].filter(Boolean).join(" ")}function At(t){return/message is not modified/i.test(Kn(t))}function vh(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function Rt(t){if(typeof t.clearButtons=="function")try{await t.clearButtons()}catch(e){if(At(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 Rt(n),{textDelivered:!0}}catch(a){if(At(a))return await Rt(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 Rt(n),{textDelivered:!1}}catch(a){if(At(a))return await Rt(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 Rt(n),{textDelivered:!1}}catch(a){if(At(a))return await Rt(n),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}return await Rt(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(At(s))return{textDelivered:typeof i=="string"};if(vh(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(At(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 wh(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 Ds=["plan-approve","plan-request-changes","plan-reject"];function Ph(t){switch(t){case"plan-approve":return"Approve";case"plan-request-changes":return"Revise";case"plan-reject":return"Reject";default:return"Continue"}}function bh(t){switch(t){case"plan-approve":return"primary";case"plan-reject":return"danger";default:return"secondary"}}function Rh(t,e){let n=t,o=(typeof n?.listActiveActionTokens=="function"?Ds.flatMap(a=>n.listActiveActionTokens?.(a)??[]):[e]).filter(a=>Ao(a.kind)&&a.sessionId===e.sessionId&&(e.planDecisionVersion==null||a.planDecisionVersion==null||a.planDecisionVersion===e.planDecisionVersion)).sort((a,d)=>Ds.indexOf(a.kind)-Ds.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:Ph(a.kind),callbackData:`${te}:${a.id}`,style:bh(a.kind)}));return s.length>0?[s]:void 0}async function Ah(t,e,n,r){if(t.channel!=="telegram"){await O(t,e);return}let o=Rh(n,r);await t.respond.reply({text:o?`${e}
134
+
135
+ Approval is still pending. Try again below.`:e,...o?{buttons:o}:{}})}function ou(t="telegram",e={}){let n=e.makeAgentMergeTool??lo,r=e.makeAgentPrTool??qn;return U("callback_handler_registered",{channel:t,namespace:te}),{channel:t,namespace:te,handler:async o=>{let i=await wh(o);if(!o.auth.isAuthorizedSender)return await O(o,"⛔ Unauthorized."),{handled:!0};let s=Sh(o),a=mh(s);if(U("callback_received",{channel:o.channel,namespace:te,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:we(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(U("callback_token_lookup_completed",{channel:o.channel,namespace:te,tokenHash:we(a),tokenFound:!!d,actionKind:d?.kind,sessionId:d?.sessionId,planDecisionVersion:d?.planDecisionVersion}),!d)return await z(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 z(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),m=u?.name??l,p=Es(d,u);if(U("callback_plan_validation_completed",{channel:o.channel,namespace:te,tokenHash:we(a),actionKind:d.kind,sessionId:l,sessionName:m,planDecisionVersion:d.planDecisionVersion,valid:!p}),p)return Ao(d.kind)?await Je(o,i):await z(o,{alreadyAcknowledged:i}),await O(o,`⚠️ ${p}`),{handled:!0};if(d.kind==="question-answer"){if(d.optionIndex==null)return await z(o,{alreadyAcknowledged:i}),await O(o,"⚠️ Invalid question-answer action."),{handled:!0};if($s.has(a))return await O(o,"⚠️ That answer is already being submitted. If the question remains active, try again."),{handled:!0};$s.add(a);let c=!1;try{c=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,Zl),{handled:!0}}finally{$s.delete(a)}if(!c)return await O(o,Zl),{handled:!0};let h=v.consumeActionToken(a);return U("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:we(a),consumed:!!h,actionKind:h?.kind,sessionId:h?.sessionId,planDecisionVersion:h?.planDecisionVersion}),h?(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 y=gh(d);if(y)for(;;){let c=Un.get(y);if(!c)break;if(c.tokenId===a)return await Je(o,i),await O(o,"⚠️ This plan decision is already being processed."),{handled:!0};await nu(c.operation);let h=v.getActionToken(a);if(!h)return await Je(o,i),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(l=h.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),m=u?.name??l,p=Es(h,u),U("callback_plan_validation_completed",{channel:o.channel,namespace:te,tokenHash:we(a),actionKind:h.kind,sessionId:l,sessionName:m,planDecisionVersion:h.planDecisionVersion,valid:!p,afterPlanDecisionLock:!0}),p)return await Je(o,i),await O(o,`⚠️ ${p}`),{handled:!0};d=h}if(d.kind==="plan-approve"){let c=d,h=!1,S=async(x=!1)=>{h||!x&&o.channel!=="telegram"||(await Je(o,i),h=!0)},b=await Xl(y,a,async()=>(await S(),Ae(v,{session:c.sessionId,message:"Approved. Go ahead.",approve:!0,userInitiated:!0})));if(b.isError){let x=v.resolve?.(c.sessionId)??v.getPersistedSession?.(c.sessionId),R=hh(x);if(R){let k=v.consumeActionToken(a);U("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:we(a),consumed:!!k,actionKind:k?.kind,sessionId:k?.sessionId??c.sessionId,planDecisionVersion:k?.planDecisionVersion,approvalAppliedAfterError:!0}),await S(!0)}return R?await O(o,`⚠️ ${b.text}`):await Ah(o,`⚠️ ${b.text}`,v,c),{handled:!0}}let A=v.consumeActionToken(a);return U("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:we(a),consumed:!!A,actionKind:A?.kind,sessionId:A?.sessionId??c.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 Xl(y,a,async()=>{let c=v.getActionToken(a);if(!c)return await Je(o,i),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};l=c.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),m=u?.name??l;let h=Es(c,u);if(U("callback_plan_validation_completed",{channel:o.channel,namespace:te,tokenHash:we(a),actionKind:c.kind,sessionId:l,sessionName:m,planDecisionVersion:c.planDecisionVersion,valid:!h,afterPlanDecisionLock:!0}),h)return await Je(o,i),await O(o,`⚠️ ${h}`),{handled:!0};let S=v.consumeActionToken(a);if(U("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:we(a),consumed:!!S,actionKind:S?.kind,sessionId:S?.sessionId,planDecisionVersion:S?.planDecisionVersion}),!S)return await Je(o,i),o.channel!=="telegram"&&await O(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(await Je(o,i),S.kind==="plan-reject"){let b=ps(v,l);await O(o,`❌ ${b.text}`)}else{let b=ms(v,l);await O(o,`✏️ ${b.text}`)}return{handled:!0}});let f=v.consumeActionToken(a);if(U("callback_token_consume_completed",{channel:o.channel,namespace:te,tokenHash:we(a),consumed:!!f,actionKind:f?.kind,sessionId:f?.sessionId,planDecisionVersion:f?.planDecisionVersion}),!f)return await z(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(f.kind){case"plugin-update-install":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),!De){await O(o,"⚠️ OCA update service is not running.");break}try{let c=await De.installConfirmed(f.pluginUpdateVersion,{route:f.route});await O(o,`✅ ${c}`)}catch(c){await O(o,`⚠️ OCA update failed: ${c instanceof Error?c.message:String(c)}`)}break}case"plugin-update-restart":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),!De){await O(o,"⚠️ OCA update service is not running.");break}try{let c=await De.restartConfirmed(f.pluginUpdateVersion);await O(o,`▶️ ${c}`)}catch(c){await O(o,`⚠️ Gateway restart failed: ${c instanceof Error?c.message:String(c)}`)}break}case"plugin-update-dismiss":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0});let c=De?De.dismiss(f.pluginUpdateVersion):"Dismissed OCA update reminder.";await O(o,`✅ ${c}`);break}case"plugin-update-remind-later":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0});let c=De?De.remindLater(f.pluginUpdateVersion):"Will remind later about OCA update reminder.";await O(o,`✅ ${c}`);break}case"worktree-merge":{let c=await n().execute("callback",{session:l}),h=Ro(c);if(eu(c)){await Po(o,i);break}await O(o,h);break}case"worktree-decide-later":{let c=v.snoozeWorktreeDecision(l,{notifyUser:!1});if(Os(c)){let S=`⏭️ Snoozed 24h for [${m}]`;await Po(o,i),await O(o,S)}else await O(o,c);break}case"worktree-dismiss":{let c=await v.dismissWorktree(l),h=Os(c);h&&await Po(o,i),await O(o,h?"✅ Discarded":c);break}case"worktree-create-pr":case"worktree-update-pr":{let c=await r().execute("callback",{session:l}),h=Ro(c);if(eu(c)){await Po(o,i);break}await O(o,h);break}case"worktree-view-pr":{await z(o,{alreadyAcknowledged:i});let c=v.getPersistedSession?.(l),h=d.targetUrl??c?.worktreePrUrl;await O(o,h?`PR: ${h}`:"⚠️ PR URL is no longer available.");break}case"plan-offer-start":{if(!f.launchPrompt||!f.launchWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"⚠️ This action is missing the plan launch context.");break}let c;try{c=v.launchPlanOffer({route:f.route,prompt:f.launchPrompt,workdir:f.launchWorkdir,name:f.launchName,worktreeStrategy:f.launchWorktreeStrategy})}catch(h){let S=h instanceof Error?h.message:String(h);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: ${c.name} [${c.id}]`);break}case"plan-offer-dismiss":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!f.repoPolicy||!f.repoPolicyWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,"⚠️ This action is missing the repo policy context.");break}if(!f.launchPrompt||!f.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(f.repoPolicyWorkdir);if(S.identity){let b=Yt(f.repoPolicy,S.prAvailable);if(b){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ ${b}`);break}}}let c=v.setRepoPolicy(f.repoPolicyWorkdir,f.repoPolicy);if(!c){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await O(o,`⚠️ Could not resolve a git repository for ${f.repoPolicyWorkdir}.`);break}v.clearRepoPolicyChoiceTokens(f.sessionId);let h;try{h=v.launchAfterRepoPolicyChoice({route:f.route,prompt:f.launchPrompt,workdir:f.launchWorkdir,name:f.launchName,model:f.launchModel,reasoningEffort:f.launchReasoningEffort,fastMode:f.launchFastMode,systemPrompt:f.launchSystemPrompt,allowedTools:f.launchAllowedTools,resumeSessionId:f.launchResumeSessionId,resumedFromSessionName:f.launchResumedFromSessionName,resumeWorktreeFrom:f.launchResumeWorktreeFrom,sessionIdOverride:f.launchSessionIdOverride,clearedPersistedCodexResume:f.launchClearedPersistedCodexResume,forkSession:f.launchForkSession,forceNewSession:f.launchForceNewSession,permissionMode:f.launchPermissionMode,planApproval:f.launchPlanApproval,harness:f.launchHarness,worktreeStrategy:f.launchWorktreeStrategy,worktreeBaseBranch:f.launchWorktreeBaseBranch,worktreePrTargetRepo:f.launchWorktreePrTargetRepo,originAgentId:f.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: ${bl(c.policy).title}.`,"",h].join(`
136
+ `));break}case"session-restart":case"session-resume":{await z(o,{alreadyAcknowledged:i});let c=await Ae(v,{session:l,message:"Continue where you left off.",userInitiated:!0});await O(o,c.isError?`⚠️ ${c.text}`:`▶️ ${c.text}`);break}case"view-output":{await z(o,{alreadyAcknowledged:i});let c=await Zr().execute("callback",{session:l,lines:50});await O(o,Ro(c));break}default:{await z(o,{alreadyAcknowledged:i}),await O(o,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}K();oe();function nn(t){return iu(t).map(e=>e.value)}function iu(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:Ih(n),raw:n,start:r,end:r+n.length}})}function It(t){let[e]=iu(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function Ih(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function xh(t){return t instanceof Error?t.message:String(t)}function Th(t){let e=nn(t),n,r=e;return e[0]==="--name"&&e[1]&&(n=e[1],r=e.slice(2)),{name:n,prompt:r.join(" ").trim()}}function su(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}=Th(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=br({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??L.permissionMode,planApproval:i.planApproval},s)}}catch(i){let s=xh(i),a=s.includes("Max sessions")?"":`
137
+
138
+ Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${a}`}}}})}K();function au(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:Jr(v,"all",void 0,{full:n})}}})}K();function du(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:Yr(v,n,"killed")}:{text:"Usage: /agent_kill <name-or-id>"}}})}K();function lu(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>
139
+ /agent_respond --interrupt <id-or-name> <message>`};let r=!1,o=n,i=It(o);i?.value==="--interrupt"&&(r=!0,o=i.rest);let s=It(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 Ae(v,{session:a,message:d,interrupt:r,userInitiated:!0})).text}:{text:"Error: Empty message. Usage: /agent_respond <id-or-name> <message>"}}})}K();function uu(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:Rr(e,n)}}})}K();function Ch(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function cu(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=It((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(`
135
140
  `)}}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(`
136
- `)}}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&&bg(r)){if(typeof v.resolveRepoPolicy=="function"){let l=v.resolveRepoPolicy(o);if(l.identity){let u=Vt(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(`
141
+ `)}}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&&Ch(r)){if(typeof v.resolveRepoPolicy=="function"){let l=v.resolveRepoPolicy(o);if(l.identity){let u=Yt(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(`
137
142
  `)};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(`
138
143
  `)}}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(`
139
- `)}}return{text:d}}let i=v.resolveRepoPolicy(o);if(!i.identity)return{text:`No git repository found for ${o}.`};let s=An(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(`
140
- `)}}})}U();var Rg=50;function Ml(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=Qt(n),o="",i=!1,s=Rg;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:Wr(v,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}U();var _l="Usage: /goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function $l(t){t.registerCommand({name:"goal",description:"Launch an explicit goal task (Ralph-style completion loop or verifier-driven loop)",acceptsArgs:!0,requireAuth:!0,handler:async e=>{if(!Q)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:_l};let r=Qt(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:_l};let h=to({goal:m,verifierCommands:p,name:o,workdir:i,model:s,maxIterations:a,permissionMode:d,harness:l,goalMode:u,completionPromise:c},e);if(h.kind!=="resolved")return{text:h.text};try{let k=await Q.launchTask({goal:h.goal,name:h.name,workdir:h.workdir,model:h.model,reasoningEffort:h.reasoningEffort,fastMode:h.fastMode,maxIterations:h.maxIterations,permissionMode:h.permissionMode,harness:h.harness,loopMode:h.loopMode,completionPromise:h.completionPromise,originChannel:h.originChannel,originThreadId:h.originThreadId,originAgentId:h.originAgentId,originSessionKey:h.originSessionKey,route:h.route,verifierCommands:h.verifierCommands});return{text:no(k,h)}}catch(k){return{text:`Error launching goal task: ${k instanceof Error?k.message:String(k)}`}}}})}U();function El(t){t.registerCommand({name:"goal_status",description:"Show one goal task or list all explicit goal tasks. Usage: /goal_status [<task-id-or-name>]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!Q)return{text:be};let n=(e.args??"").trim();return{text:oo(Q,r=>v?.resolve(r),n)}}})}U();function Dl(t){t.registerCommand({name:"goal_stop",description:"Stop a goal task. Usage: /goal_stop <task-id-or-name>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!Q)return{text:be};let n=(e.args??"").trim();if(!n)return{text:"Usage: /goal_stop <task-id-or-name>"};let r=Q.stopTask(n);return{text:io(r,n)}}})}U();var Ol="Usage: /goal_edit <task-id-or-name> <replacement-goal>";function Wl(t){t.registerCommand({name:"goal_edit",description:"Edit a running goal task. Usage: /goal_edit <task-id-or-name> <replacement-goal>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!Q)return{text:be};let n=(e.args??"").trim();if(!n)return{text:Ol};let r=St(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:Ol};let s=Q.editTask(o,i);return{text:so(s,o)}}})}import{execFile as Lg}from"child_process";import{createHash as Yl}from"crypto";import{existsSync as Wn,mkdirSync as Ag,readFileSync as Ig,renameSync as Bl,writeFileSync as xg}from"fs";import{homedir as Tg}from"os";import{dirname as Cg,join as Fl}from"path";var Mg=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function _g(t){let e=t.OPENCLAW_HOME?.trim();return e||Fl(Tg(),".openclaw")}function $g(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||Fl(_g(t),"code-agent-goal-tasks.json")}function ql(t){return t instanceof Error?t.message:String(t)}function Kl(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var Eg=100;function Nl(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function Dg(t){if(!Wn(t))return;let e=Date.now(),n=Nl(t,e);if(!Wn(n))return n;for(let r=1;r<=Eg;r+=1){let o=Nl(t,e,r);if(!Wn(o))return o}}function Ll(t,e){try{let n=Dg(t);return n?(Bl(t,n),`${e}${n}`,!0):(Wn(t),!1)}catch(n){return`${ql(n)}`,!1}}function Og(t){if(!Kl(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 Wg(t){if(!Kl(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"||!Mg.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:Og(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 Ng(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=Wg(n);if(!r)return;e.push(r)}return e}var po=class{path;tasks=new Map;constructor(e=process.env){this.path=$g(e),this.load()}load(){try{if(!Wn(this.path))return;let e=Ig(this.path,"utf8"),n=JSON.parse(e),r=Ng(n);if(!r){Ll(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;Ll(this.path,"corrupt or unreadable")&&this.save()}}save(){try{Ag(Cg(this.path),{recursive:!0});let e=`${this.path}.tmp`;xg(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),Bl(e,this.path)}catch(e){`${this.path}${ql(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 Bg=8,Zl=600*1e3,Fg=4e3,Ss=1200,qg="DONE",Kg=["BASH_ENV","ENV"];function Ug(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 rt(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(`
144
+ `)}}return{text:d}}let i=v.resolveRepoPolicy(o);if(!i.identity)return{text:`No git repository found for ${o}.`};let s=_n(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(`
145
+ `)}}})}K();var Mh=50;function pu(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=nn(n),o="",i=!1,s=Mh;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:Qr(v,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}K();var mu="Usage: /agent_goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function fu(t){t.registerCommand({name:"agent_goal",description:"Launch an explicit goal task (Ralph-style completion loop or verifier-driven loop)",acceptsArgs:!0,requireAuth:!0,handler:async e=>{if(!J)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:mu};let r=nn(n),o,i,s,a,d="bypassPermissions",l,u,m,p=[],y=[];for(let h=0;h<r.length;h++){let S=r[h];if(S==="--name"&&h+1<r.length)o=r[++h];else if(S==="--workdir"&&h+1<r.length)i=r[++h];else if(S==="--model"&&h+1<r.length)s=r[++h];else if(S==="--max-iterations"&&h+1<r.length){let b=parseInt(r[++h],10);!Number.isNaN(b)&&b>0&&(a=b)}else if(S==="--permission-mode"&&h+1<r.length){let b=r[++h];if(b==="default"||b==="plan"||b==="bypassPermissions")d=b;else return{text:`Error: Invalid permission mode "${b}".`}}else if(S==="--harness"&&h+1<r.length)l=r[++h];else if(S==="--mode"&&h+1<r.length){let b=r[++h];if(b==="ralph"||b==="verifier")u=b;else return{text:`Error: Invalid goal mode "${b}". Use ralph or verifier.`}}else if(S==="--completion-promise"&&h+1<r.length)m=r[++h];else if(S==="--verify"&&h+1<r.length){let b=r[++h].trim();if(!b)return{text:"Error: --verify commands must not be empty."};p.push(b)}else y.push(S)}let f=y.join(" ").trim();if(!f)return{text:mu};let c=ho({goal:f,verifierCommands:p,name:o,workdir:i,model:s,maxIterations:a,permissionMode:d,harness:l,goalMode:u,completionPromise:m},e);if(c.kind!=="resolved")return{text:c.text};try{let h=await J.launchTask({goal:c.goal,name:c.name,workdir:c.workdir,model:c.model,reasoningEffort:c.reasoningEffort,fastMode:c.fastMode,maxIterations:c.maxIterations,permissionMode:c.permissionMode,harness:c.harness,loopMode:c.loopMode,completionPromise:c.completionPromise,originChannel:c.originChannel,originThreadId:c.originThreadId,originAgentId:c.originAgentId,originSessionKey:c.originSessionKey,route:c.route,verifierCommands:c.verifierCommands});return{text:yo(h,c)}}catch(h){return{text:`Error launching goal task: ${h instanceof Error?h.message:String(h)}`}}}})}K();function gu(t){t.registerCommand({name:"agent_goal_status",description:"Show one goal task or list all explicit goal tasks. Usage: /agent_goal_status [<task-id-or-name>]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!J)return{text:Ie};let n=(e.args??"").trim();return{text:So(J,r=>v?.resolve(r),n)}}})}K();function hu(t){t.registerCommand({name:"agent_goal_stop",description:"Stop a goal task. Usage: /agent_goal_stop <task-id-or-name>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!J)return{text:Ie};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent_goal_stop <task-id-or-name>"};let r=J.stopTask(n);return{text:vo(r,n)}}})}K();var yu="Usage: /agent_goal_edit <task-id-or-name> <replacement-goal>";function ku(t){t.registerCommand({name:"agent_goal_edit",description:"Edit a running goal task. Usage: /agent_goal_edit <task-id-or-name> <replacement-goal>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!J)return{text:Ie};let n=(e.args??"").trim();if(!n)return{text:yu};let r=It(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:yu};let s=J.editTask(o,i);return{text:wo(s,o)}}})}import{execFile as Vh}from"child_process";import{createHash as Eu}from"crypto";import{existsSync as Vn,mkdirSync as _h,readFileSync as $h,renameSync as wu,writeFileSync as Eh}from"fs";import{homedir as Dh}from"os";import{dirname as Oh,join as Pu}from"path";var Nh=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function Wh(t){let e=t.OPENCLAW_HOME?.trim();return e||Pu(Dh(),".openclaw")}function Lh(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||Pu(Wh(t),"code-agent-goal-tasks.json")}function bu(t){return t instanceof Error?t.message:String(t)}function Ru(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var Fh=100;function Su(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function Bh(t){if(!Vn(t))return;let e=Date.now(),n=Su(t,e);if(!Vn(n))return n;for(let r=1;r<=Fh;r+=1){let o=Su(t,e,r);if(!Vn(o))return o}}function vu(t,e){try{let n=Bh(t);return n?(wu(t,n),`${e}${n}`,!0):(Vn(t),!1)}catch(n){return`${bu(n)}`,!1}}function qh(t){if(!Ru(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 Uh(t){if(!Ru(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"||!Nh.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:qh(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 Kh(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=Uh(n);if(!r)return;e.push(r)}return e}var Io=class{path;tasks=new Map;constructor(e=process.env){this.path=Lh(e),this.load()}load(){try{if(!Vn(this.path))return;let e=$h(this.path,"utf8"),n=JSON.parse(e),r=Kh(n);if(!r){vu(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;vu(this.path,"corrupt or unreadable")&&this.save()}}save(){try{_h(Oh(this.path),{recursive:!0});let e=`${this.path}.tmp`;Eh(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),wu(e,this.path)}catch(e){`${this.path}${bu(e)}`}}upsert(e){this.tasks.set(e.id,e),this.save()}get(e){let n=this.tasks.get(e);return n||[...this.tasks.values()].find(r=>r.name===e)}list(){return[...this.tasks.values()].sort((e,n)=>n.createdAt-e.createdAt)}};he();var jh=8,Du=600*1e3,Gh=4e3,Ns=1200,Hh="DONE",zh=["BASH_ENV","ENV"];function Qh(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"goal-task"}function rn(t,e){return t.length<=e?t:`${t.slice(0,e-3)}...`}function ut(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(`
141
146
  `):n.slice(-e).join(`
142
- `)}function Vg(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(`
143
- `):void 0}function Ul(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Vl(t){let e=t?.trim();return e&&e.length>0?e:qg}function jg(t){return t.route??an(t.originChannel,t.originThreadId,t.originSessionKey)}function vs(t){return t.map((e,n)=>({label:e.label.trim()||`check-${n+1}`,command:e.command.trim(),timeoutMs:e.timeoutMs??Zl})).filter(e=>e.command.length>0)}function Gg(t){return t.loopMode==="verifier"}function Hg(t){return vs(t.verifierCommands).length>0}function jl(t){return Gg(t)&&!Hg(t)}function mo(){return"Verifier-mode goal tasks require at least one verifier command."}function Gl(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${rt(n.output,12)}`).join(`
144
- `);return Yl("sha1").update(e).digest("hex")}function zg(t){return Yl("sha1").update(rt(t,24)).digest("hex")}function Hl(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 Qg(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(`
147
+ `)}function Jh(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(`
148
+ `):void 0}function Au(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Iu(t){let e=t?.trim();return e&&e.length>0?e:Hh}function Yh(t){return t.route??Te(t.originChannel,t.originThreadId,t.originSessionKey)}function Ws(t){return t.map((e,n)=>({label:e.label.trim()||`check-${n+1}`,command:e.command.trim(),timeoutMs:e.timeoutMs??Du})).filter(e=>e.command.length>0)}function Zh(t){return t.loopMode==="verifier"}function Xh(t){return Ws(t.verifierCommands).length>0}function xu(t){return Zh(t)&&!Xh(t)}function xo(){return"Verifier-mode goal tasks require at least one verifier command."}function Tu(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${ut(n.output,12)}`).join(`
149
+ `);return Eu("sha1").update(e).digest("hex")}function ey(t){return Eu("sha1").update(ut(t,24)).digest("hex")}function Cu(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 ty(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(`
145
150
  `);let e=t.verifierCommands.map(n=>`- ${n.label}: ${n.command}`).join(`
146
151
  `);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(`
147
- `)}function zl(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(`
152
+ `)}function Mu(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(`
148
153
  `):["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(`
149
- `)}function Jg(t,e){let n=e.steps.filter(o=>!o.ok).map(o=>[`- ${o.label} failed (exit ${o.exitCode})`,rt(o.output,18)].join(`
154
+ `)}function ny(t,e){let n=e.steps.filter(o=>!o.ok).map(o=>[`- ${o.label} failed (exit ${o.exitCode})`,ut(o.output,18)].join(`
150
155
  `)).join(`
151
156
 
152
157
  `);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(`
153
- `)}function Yg(t,e){let n=rt(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(`
154
- `)}function Zg(t,e){let n=e.steps.filter(r=>!r.ok).map(r=>[`- ${r.label} failed (exit ${r.exitCode})`,rt(r.output,18)].join(`
158
+ `)}function ry(t,e){let n=ut(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(`
159
+ `)}function oy(t,e){let n=e.steps.filter(r=>!r.ok).map(r=>[`- ${r.label} failed (exit ${r.exitCode})`,ut(r.output,18)].join(`
155
160
  `)).join(`
156
161
 
157
162
  `);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(`
158
- `)}function Xg(t,e){let n=e.trim();if(!n)return!1;let r=new RegExp(`(^|\\n)\\s*${Ul(n)}\\s*(\\n|$)`,"i"),o=new RegExp(`<promise>\\s*${Ul(n)}\\s*<\\/promise>`,"i");return r.test(t)||o.test(t)}function Ql(t){return t.steps.map(e=>`${e.ok?"PASS":"FAIL"} ${e.label} (exit ${e.exitCode}, ${Math.round(e.durationMs)}ms)`).join(`
159
- `)}function vt(t){return t instanceof Error?t.message:String(t)}function Jl(t){return t==="succeeded"||t==="failed"||t==="stopped"}function eh(t){return Jt(t.error?.trim()||"Underlying session failed.",Ss)}function th(t=process.env){let e={...t};for(let n of Kg)delete e[n];return e}function nh(t,e){return new Promise(n=>{let r=Date.now();Lg("bash",["-lc",e.command],{cwd:t,timeout:e.timeoutMs??Zl,maxBuffer:1024*1024,env:th()},(o,i,s)=>{let a=Date.now()-r,d=typeof o?.code=="number"?o.code:o?1:0,l=`${i??""}${s?`
160
- ${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!o,exitCode:d,durationMs:a,output:Jt(l||"(no output)",Fg)})})})}var fo=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 po}start(){this.started||(this.started=!0,!this.restorePromise&&(this.restorePromise=this.restoreRecoverableTasks().catch(e=>{`${vt(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=vs(e.verifierCommands);if(n==="verifier"&&r.length===0)throw new Error(mo());let i={id:kr(8),name:Ug(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??Bg,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:Vl(e.completionPromise),verifierCommands:r,repeatedFailureCount:0},s=await this.spawnTaskSession(i,Qg(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
163
+ `)}function iy(t,e){let n=e.trim();if(!n)return!1;let r=new RegExp(`(^|\\n)\\s*${Au(n)}\\s*(\\n|$)`,"i"),o=new RegExp(`<promise>\\s*${Au(n)}\\s*<\\/promise>`,"i");return r.test(t)||o.test(t)}function _u(t){return t.steps.map(e=>`${e.ok?"PASS":"FAIL"} ${e.label} (exit ${e.exitCode}, ${Math.round(e.durationMs)}ms)`).join(`
164
+ `)}function xt(t){return t instanceof Error?t.message:String(t)}function $u(t){return t==="succeeded"||t==="failed"||t==="stopped"}function sy(t){return rn(t.error?.trim()||"Underlying session failed.",Ns)}function ay(t=process.env){let e={...t};for(let n of zh)delete e[n];return e}function dy(t,e){return new Promise(n=>{let r=Date.now();Vh("bash",["-lc",e.command],{cwd:t,timeout:e.timeoutMs??Du,maxBuffer:1024*1024,env:ay()},(o,i,s)=>{let a=Date.now()-r,d=typeof o?.code=="number"?o.code:o?1:0,l=`${i??""}${s?`
165
+ ${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!o,exitCode:d,durationMs:a,output:rn(l||"(no output)",Gh)})})})}var To=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=>{`${xt(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=Ws(e.verifierCommands);if(n==="verifier"&&r.length===0)throw new Error(xo());let i={id:_r(8),name:Qh(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??jh,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:Iu(e.completionPromise),verifierCommands:r,repeatedFailureCount:0},s=await this.spawnTaskSession(i,ty(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
161
166
 
162
167
  Goal:
163
- ${Jt(i.goal,500)}`,"goal-task-started"),i}stopTask(e){let n=this.store.get(e);if(n)return Jl(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(Jl(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
168
+ ${rn(i.goal,500)}`,"goal-task-started"),i}stopTask(e){let n=this.store.get(e);if(n)return $u(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($u(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
164
169
 
165
170
  Goal:
166
- ${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}=It({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:jg(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(`
167
- `));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(jl(e)){this.markTaskFailed(e,mo());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,zl(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: ${vt(r)}`)}}}async runVerifiers(e){let n=vs(e.verifierCommands);if(n.length===0){let s={status:"fail",steps:[{label:"verifier-config",command:"(none configured)",ok:!1,exitCode:1,durationMs:0,output:mo()}],summary:"",fingerprint:""};return s.fingerprint=Gl(s),s.summary=Ql(s),s}let r=[];for(let s of n)r.push(await nh(e.workdir,s));let i={status:r.every(s=>s.ok)?"pass":"fail",steps:r,summary:"",fingerprint:""};return i.fingerprint=Gl(i),i.summary=Ql(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=Vg(o),d=a?`${s}
171
+ ${rn(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}=Lt({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:Yh(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(`
172
+ `));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(xu(e)){this.markTaskFailed(e,xo());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,Mu(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: ${xt(r)}`)}}}async runVerifiers(e){let n=Ws(e.verifierCommands);if(n.length===0){let s={status:"fail",steps:[{label:"verifier-config",command:"(none configured)",ok:!1,exitCode:1,durationMs:0,output:xo()}],summary:"",fingerprint:""};return s.fingerprint=Tu(s),s.summary=_u(s),s}let r=[];for(let s of n)r.push(await dy(e.workdir,s));let i={status:r.every(s=>s.ok)?"pass":"fail",steps:r,summary:"",fingerprint:""};return i.fingerprint=Tu(i),i.summary=_u(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=Jh(o),d=a?`${s}
168
173
 
169
- ${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}${vt(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,Ss),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`❌ [${e.name}] Goal task failed
174
+ ${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}${xt(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=rn(n,Ns),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`❌ [${e.name}] Goal task failed
170
175
 
171
176
  ${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
172
177
 
173
- ${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=Jt(n,Ss),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`⛔ [${e.name}] Goal task stopped
178
+ ${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=rn(n,Ns),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`⛔ [${e.name}] Goal task stopped
174
179
 
175
- ${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(`
176
- `),o=Hl(r);if(!o){this.markTaskFailedWaitingForUser(e,rt(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: ${vt(o)}`)}}async handleTerminalSession(e,n){if(n.status==="failed"){this.markTaskFailed(e,eh(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(`
177
- `);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=Hl(s);if(!a){this.markTaskFailed(e,`Goal task was waiting for user input and cannot continue autonomously: ${rt(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(`
180
+ ${e.failureReason}`,"goal-task-stopped")}async handleRunningSession(e,n){if(n.pendingPlanApproval){let s=await Ae(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(`
181
+ `),o=Cu(r);if(!o){this.markTaskFailedWaitingForUser(e,ut(r,24)||"The session is waiting for user input.");return}let i=await Ae(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: ${xt(o)}`)}}async handleTerminalSession(e,n){if(n.status==="failed"){this.markTaskFailed(e,sy(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(`
182
+ `);if(n.pendingPlanApproval){let a=await Ae(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=Cu(s);if(!a){this.markTaskFailed(e,`Goal task was waiting for user input and cannot continue autonomously: ${ut(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(`
178
183
 
179
- `));return}await this.resumeAfterIdleTimeout(e,n,zl(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(`
180
- `),a=Vl(e.completionPromise);if(Xg(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(`
184
+ `));return}await this.resumeAfterIdleTimeout(e,n,Mu(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(`
185
+ `),a=Iu(e.completionPromise);if(iy(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(`
181
186
  `));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(`
182
- `));return}e.iteration+=1;let f=Zg(e,p),m=ro({output:s,verifierSummary:p.summary,completionPromise:a,completionDetected:!0});try{let h=await this.resumeTaskSession(e,f,n);this.setTaskRunningWithSession(e,h),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,m),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",h.id)}catch(h){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${vt(h)}`)}return}let l=zg(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:",rt(s,20)||"(no output)"].join(`
183
- `));return}e.iteration+=1;let u=Yg(e,s),c=ro({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: ${vt(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(`
184
- `));return}e.iteration+=1;let o=Jg(e,r),i=ro({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: ${vt(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(jl(e)){this.markTaskFailed(e,mo());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 ac}from"crypto";ae();import{existsSync as rh,realpathSync as oh}from"fs";import{resolve as ih}from"path";function Xl(t){if(!t)return;let e=ih(t);try{if(rh(e))return oh.native(e)}catch{}return e}function go(t,e){return!t||!e?!1:Xl(t)===Xl(e)}ee();ae();import{existsSync as sh}from"fs";ee();ke();function eu(t){return t instanceof Error?t.message:String(t)}function ah(t){let e=t.worktreeStrategy??W.defaultWorktreeStrategy;return!!e&&e!=="off"&&Mi(kn({harnessName:t.harness??ue(),backendRef:t.backendRef}))}function dh(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(`
185
- `);return(t??"")+o}function lh(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=xr(r.worktreePath);return r.workdir&&a&&go(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&&dr(kn({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=dr(kn({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(sh(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{Cr(i);let a=Li(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:i,worktreePath:a,worktreeBranchName:r.worktreeBranch}}catch(a){return`${eu(a)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function tu(t,e,n){let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,canCreateManagedWorktreeForResumeWithoutPersistedPath:u,failedResumeWorktreeRestore:c}=lh(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??W.defaultWorktreeStrategy;f&&(t.worktreeStrategy=f);let m=ah(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&&!Wi(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" requires a git worktree, but "${o}" is not a git repository.`);if(k&&Wi(o)){if(!ad(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=Li(o,e),r=i,s=De(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: ${eu(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?dh(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,failedResumeWorktreeRestore:c}}var ho=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return tu(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 yo=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=O(e),o=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(j(o)===e||O(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),this.assignIfDefined(e,"taskFlowMirror",n.taskFlowMirror)}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 uh=new Set(["starting","running"]),ko=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=>O(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?O(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),uh.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};ee();ee();ke();import{existsSync as ch}from"fs";var nu=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),So=class{constructor(e){this.deps=e}deps;async plan(e){let n=j(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=nu.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&nu.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=ce(e);if(d&&!ch(i))return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};let l=e.worktreeBaseBranch??Ee(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=Ke(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),h=jd({requestedStrategy:o,policy:f,prAvailable:m,existingOpenPr:!1});return h.strategy?{kind:"decision",strategy:h.strategy,policy:f,policyReason:h.reason,policyBlocked:h.blocked,allowedActions:h.allowedActions,repoDir:s,worktreePath:i,branchName:a,baseBranch:l,diffSummary:c,sessionRef:n??void 0}:{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}}}};Tn();function ot(t){let e=[];typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)&&e.push(`$${t.costUsd.toFixed(2)}`);let n=ph(t);n!==void 0&&e.push($e(n));let r=Ot({harness:t.harnessName??t.harness,model:t.model});return r&&e.push(...r.split(" | ")),e.length>0?` | ${e.join(" | ")}`:""}function ph(t){if(typeof t.duration=="number"&&Number.isFinite(t.duration)&&t.duration>=0)return t.duration;if(typeof t.createdAt=="number"&&Number.isFinite(t.createdAt)&&typeof t.completedAt=="number"&&Number.isFinite(t.completedAt)&&t.completedAt>=t.createdAt)return t.completedAt-t.createdAt}function mh(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 fh(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function gh(){return/https?:\/\/\S+/gi}function vo(t){let e=mh(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function ws(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 hh(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function yh(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function kh(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function Ps(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 Sh(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 bs(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=hh(),s=a=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...vo(e),"","Output preview:",r,"",...Sh({contract:i,canonicalStatusDelivered:a}),"",...Ps({sessionId:e.id,canonicalStatusDelivered:a,hasOriginRouteBlock:o})].join(`
186
- `);return{userMessage:`✅ [${e.name}] Completed${ot(e)}`,wakeMessageOnNotifySuccess:s(!0),wakeMessageOnNotifyFailed:s(!1),followupContract:i}}function Yt(t){let e=yh(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>ru(i).trim()).filter(i=>i.length>0),o=ru(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(`
187
- `)}function Rs(t){let e=kh(),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(`
188
- `)}function ru(t){return t.replace(fh(),"PR #$1").replace(gh(),"[link omitted]")}function As(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)."]:[];return{userMessage:[`❌ [${e.name}] Failed${ot(e)}`,` ⚠️ ${r}`].join(`
189
- `),wakeMessage:["Coding agent session failed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,n,...vo(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(`
190
- `),buttons:s}}function Is(t){let{session:e,originThreadLine:n,preview:r}=t;return{userMessage:`⏸️ [${e.name}] Turn completed${ot(e)}`,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(`
191
- `)}}function xs(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.",`- First call agent_output(session='${n}', full=true) to inspect the full session output and use it as source material for your decision.`,...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(`
192
- `)}function Ts(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(`
193
- `)}function Cs(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]:[],h=!!i?.trim();return["Coding agent session completed with no worktree changes to merge.",`Name: ${e} | ID: ${n}`,`Worktree outcome: ${r}`,...h?[i]:[],...vo({requestedPermissionMode:s,currentPermissionMode:a,approvalExecutionState:d,approvalState:l,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:p,approvalPromptDeliveredAt:f}),...m,"",...Ps({sessionId:n,canonicalStatusDetail:"The plugin already sent the canonical completion status to the user, including the no-worktree-changes outcome.",hasOriginRouteBlock:h})].join(`
194
- `)}var su=3200,Ms=3e3,vh=2400,wh=120,Ph=5,bh=280,ou=1400,iu="- Additional plan details omitted for brevity.";function au(t){return t.replace(/^#{1,6}\s+/,"").replace(/^[-*+]\s+/,"").replace(/^\d+[.)]\s+/,"").replace(/^`([^`]+)`$/,"$1").trim()}function Rh(t){return t.split(`
195
- `).map(e=>e.trim()).filter(Boolean).map(au).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 Ah(t){return t.split(`
196
- `).map(e=>e.trim()).filter(Boolean).map(au).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 _s(t){let e=Rh(t);return e.length===0?`Review summary:
187
+ `));return}e.iteration+=1;let y=oy(e,p),f=ko({output:s,verifierSummary:p.summary,completionPromise:a,completionDetected:!0});try{let c=await this.resumeTaskSession(e,y,n);this.setTaskRunningWithSession(e,c),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,f),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",c.id)}catch(c){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${xt(c)}`)}return}let l=ey(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:",ut(s,20)||"(no output)"].join(`
188
+ `));return}e.iteration+=1;let u=ry(e,s),m=ko({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,m),this.scheduleTaskEvaluation(e.id,"ralph-continue",p.id)}catch(p){this.markTaskFailed(e,`Failed to continue the Ralph goal task: ${xt(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(`
189
+ `));return}e.iteration+=1;let o=ny(e,r),i=ko({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: ${xt(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(xu(e)){this.markTaskFailed(e,xo());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 Wc}from"crypto";oe();import{existsSync as ly,realpathSync as uy}from"fs";import{resolve as cy}from"path";function Ou(t){if(!t)return;let e=cy(t);try{if(ly(e))return uy.native(e)}catch{}return e}function Co(t,e){return!t||!e?!1:Ou(t)===Ou(e)}ee();oe();import{existsSync as py}from"fs";he();ee();ve();function my(t){if(!(!t.provider||!t.target))return t.accountId?`${t.provider}|${t.accountId}|${t.target}`:`${t.provider}|${t.target}`}function fy(t){return mn(Ee({route:t.route,originChannel:t.originChannel,originThreadId:t.originThreadId,originSessionKey:t.originSessionKey}))}function gy(t,e){if(fy(t))return;let n=[t.resumeSessionId,t.resumeWorktreeFrom].filter(r=>!!r?.trim());for(let r of n){let o=e(r);if(!o)continue;let i=Ee({route:o.route,originChannel:o.originChannel,originThreadId:o.originThreadId,originSessionKey:o.originSessionKey});if(mn(i)){t.route={...i},t.originChannel=o.originChannel??my(i),t.originThreadId=o.originThreadId??i.threadId,t.originSessionKey=o.originSessionKey??i.sessionKey,t.originAgentId??=o.originAgentId;return}}}function Nu(t){return t instanceof Error?t.message:String(t)}function hy(t){let e=t.worktreeStrategy??L.defaultWorktreeStrategy;return!!e&&e!=="off"&&Ji(An({harnessName:t.harness??ue(),backendRef:t.backendRef}))}function yy(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(`
190
+ `);return(t??"")+o}function ky(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&&wr(An({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=wr(An({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(py(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{Ur(i);let a=rs(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:i,worktreePath:a,worktreeBranchName:r.worktreeBranch}}catch(a){return`${Nu(a)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function Wu(t,e,n){gy(t,n);let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,canCreateManagedWorktreeForResumeWithoutPersistedPath:u,failedResumeWorktreeRestore:m}=ky(t,n);a&&(t.resumeSessionId=void 0),d&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,o??=t.workdir;let p=!!(t.resumeSessionId??t.resumeWorktreeFrom),y=t.worktreeStrategy??L.defaultWorktreeStrategy;y&&(t.worktreeStrategy=y);let f=hy(t),h=(!p||!!u)&&!l&&!i&&y&&y!=="off"&&!f;if(m&&y&&y!=="off")throw new Error(`Cannot launch session "${e}": worktree strategy "${y}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);if(f&&!ts(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${y}" requires a git worktree, but "${o}" is not a git repository.`);if(h&&ts(o)){if(!Fd(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=rs(o,e),r=i,s=Ce(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: ${Nu(S)}`)}}else if(h)throw new Error(`Cannot launch session "${e}": worktree strategy "${y}" requires a git worktree, but "${o}" is not a git repository.`);if(p&&i&&(r=i),y&&y!=="off"&&!i)throw new Error(`Cannot launch session "${e}": worktree strategy "${y}" 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?yy(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,failedResumeWorktreeRestore:m}}var Mo=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return Wu(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 _o=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=F(e),o=F(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(G(o)===e||F(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),this.assignIfDefined(e,"taskFlowMirror",n.taskFlowMirror)}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 Sy=new Set(["starting","running"]),$o=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=>F(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?F(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),Sy.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};ee();ee();ve();import{existsSync as vy}from"fs";var Lu=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),Eo=class{constructor(e){this.deps=e}deps;async plan(e){let n=G(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=Lu.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&Lu.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=pe(e);if(d&&!vy(i))return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};let l=e.worktreeBaseBranch??We(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 m=je(s,a,l);if(!m)return`${a}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let p=e.repoIntegrationPolicy?void 0:this.deps.resolveRepoPolicy?.(s),y=e.repoIntegrationPolicy??p?.policy,f=e.repoIntegrationPolicy?this.deps.isPrAvailable(s):p?.prAvailable??this.deps.isPrAvailable(s),c=Il({requestedStrategy:o,policy:y,prAvailable:f,existingOpenPr:!1});return c.strategy?{kind:"decision",strategy:c.strategy,policy:y,policyReason:c.reason,policyBlocked:c.blocked,allowedActions:c.allowedActions,repoDir:s,worktreePath:i,branchName:a,baseBranch:l,diffSummary:m,sessionRef:n??void 0}:{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}}}};Dn();function ct(t){let e=[];typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)&&e.push(`$${t.costUsd.toFixed(2)}`);let n=wy(t);n!==void 0&&e.push(Ne(n));let r=at({harness:t.harnessName??t.harness,model:t.model});return r&&e.push(...r.split(" | ")),e.length>0?` | ${e.join(" | ")}`:""}function wy(t){if(typeof t.duration=="number"&&Number.isFinite(t.duration)&&t.duration>=0)return t.duration;if(typeof t.createdAt=="number"&&Number.isFinite(t.createdAt)&&typeof t.completedAt=="number"&&Number.isFinite(t.completedAt)&&t.completedAt>=t.createdAt)return t.completedAt-t.createdAt}function Py(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 by(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function Ry(){return/https?:\/\/\S+/gi}function Do(t){let e=Py(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function Ls(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 Ay(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function Iy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function xy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function Fs(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 Ty(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 Bs(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=Ay(),s=a=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...Do(e),"","Output preview:",r,"",...Ty({contract:i,canonicalStatusDelivered:a}),"",...Fs({sessionId:e.id,canonicalStatusDelivered:a,hasOriginRouteBlock:o})].join(`
191
+ `);return{userMessage:`✅ [${e.name}] Completed${ct(e)}`,wakeMessageOnNotifySuccess:s(!0),wakeMessageOnNotifyFailed:s(!1),followupContract:i}}function on(t){let e=Iy(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>Fu(i).trim()).filter(i=>i.length>0),o=Fu(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(`
192
+ `)}function qs(t){let e=xy(),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(`
193
+ `)}function Fu(t){return t.replace(by(),"PR #$1").replace(Ry(),"[link omitted]")}function Us(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)."]:[];return{userMessage:[`❌ [${e.name}] Failed${ct(e)}`,` ⚠️ ${r}`].join(`
194
+ `),wakeMessage:["Coding agent session failed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,n,...Do(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(`
195
+ `),buttons:s}}function Ks(t){let{session:e,originThreadLine:n,preview:r}=t;return{userMessage:`⏸️ [${e.name}] Turn completed${ct(e)}`,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(`
196
+ `)}}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:m}=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,"",...m?[`Policy constraint: ${m}`,""]:[],"You own the next step for this worktree.",`- First call agent_output(session='${n}', full=true) to inspect the full session output and use it as source material for your decision.`,...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(`
197
+ `)}function js(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(`
198
+ `)}function Gs(t){let{sessionName:e,sessionId:n,headline:r,cleanupSummary:o,preview:i,originThreadLine:s,requestedPermissionMode:a,currentPermissionMode:d,approvalExecutionState:l,approvalState:u,planApproval:m,approvalPromptStatus:p,approvalPromptMessageKind:y,approvalPromptDeliveredAt:f}=t,c=i.trim()?["","Output preview:",i]:[],h=!!s?.trim();return[r??"Coding agent session completed with no worktree changes to merge.",`Name: ${e} | ID: ${n}`,`Worktree outcome: ${o}`,...h?[s]:[],...Do({requestedPermissionMode:a,currentPermissionMode:d,approvalExecutionState:l,approvalState:u,planApproval:m,approvalPromptStatus:p,approvalPromptMessageKind:y,approvalPromptDeliveredAt:f}),...c,"",...Fs({sessionId:n,canonicalStatusDetail:"The plugin already sent the canonical completion status to the user, including the no-worktree-changes outcome.",hasOriginRouteBlock:h})].join(`
199
+ `)}var Uu=3200,Hs=3e3,Cy=2400,My=120,_y=5,$y=280,Bu=1400,qu="- Additional plan details omitted for brevity.";function Ku(t){return t.replace(/^#{1,6}\s+/,"").replace(/^[-*+]\s+/,"").replace(/^\d+[.)]\s+/,"").replace(/^`([^`]+)`$/,"$1").trim()}function Ey(t){return t.split(`
200
+ `).map(e=>e.trim()).filter(Boolean).map(Ku).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 Dy(t){return t.split(`
201
+ `).map(e=>e.trim()).filter(Boolean).map(Ku).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 zs(t){let e=Ey(t);return e.length===0?`Review summary:
197
202
  - Plan details are available in the full session output.`:["Review summary:",...e.slice(0,6).map(n=>`- ${n}`)].join(`
198
- `)}function Ih(t){let e=[],n=!1;for(let o of t){let i=o.replace(/\s+/g," ").trim();if(!i)continue;let s=de(i,bh);s.length<i.length&&(n=!0);let a=`- ${s}`;if(e.length>=Ph||[...e,a].join(`
199
- `).length>ou){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,iu].join(`
200
- `).length>ou;)r.pop();return[...r,iu]}function $s(t){return Ih(Ah(t)).join(`
201
- `)}function xh(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 Th(t,e){let n=t.split(`
202
- `),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 xh(s,e))r.push(d);continue}let a=o.length>0?`${o}
203
- ${s}`:s;if(a.length>e){i(),o=s;continue}o=a}return i(),r}function du(t){return de(t.trim(),wh)}function lu(t,e){return e?t?`
203
+ `)}function Oy(t){let e=[],n=!1;for(let o of t){let i=o.replace(/\s+/g," ").trim();if(!i)continue;let s=de(i,$y);s.length<i.length&&(n=!0);let a=`- ${s}`;if(e.length>=_y||[...e,a].join(`
204
+ `).length>Bu){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,qu].join(`
205
+ `).length>Bu;)r.pop();return[...r,qu]}function Qs(t){return Oy(Dy(t)).join(`
206
+ `)}function Ny(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 Wy(t,e){let n=t.split(`
207
+ `),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 Ny(s,e))r.push(d);continue}let a=o.length>0?`${o}
208
+ ${s}`:s;if(a.length>e){i(),o=s;continue}o=a}return i(),r}function Vu(t){return de(t.trim(),My)}function ju(t,e){return e?t?`
204
209
 
205
210
  Choose Approve, Revise, or Reject below.`:`
206
211
 
207
212
  Approval is still pending for this plan version.`:`
208
213
 
209
- Continued in next message.`}function Ch(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=`📋 [${e}] Plan v${n??"?"} ready for approval:`,s=`
214
+ Continued in next message.`}function Ly(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=`📋 [${e}] Plan v${n??"?"} ready for approval:`,s=`
210
215
 
211
216
  Full plan (truncated):
212
- `,a=lu(o,!0),d=Math.max(0,Ms-i.length-s.length-a.length);return`${i}${s}${de(r,d)}${a}`}function Mh(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=du(e),s=vh;for(;s>0;){let a=Th(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(`
213
- `),h=lu(o,p===f-1);return`${m}
214
- ${c}${h}`}),l=d.reduce((c,p)=>Math.max(c,p.length),0);if(l<=Ms)return d;let u=l-Ms;s-=Math.max(u,50)}return[Ch({sessionName:i,actionableVersion:n,fullPlanText:r,hasButtons:o})]}function Es(t){let{preview:e,artifact:n}=t,r=n?.markdown?.trim();return r&&r.length<=su?`Full plan:
215
- ${r}`:_s(r||e)}function uu(t){let{sessionName:e,actionableVersion:n,preview:r,artifact:o,hasButtons:i}=t,s=o?.markdown?.trim(),a=du(e);if(s){let l=`📋 [${a}] Plan v${n??"?"} ready for approval:
217
+ `,a=ju(o,!0),d=Math.max(0,Hs-i.length-s.length-a.length);return`${i}${s}${de(r,d)}${a}`}function Fy(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=Vu(e),s=Cy;for(;s>0;){let a=Wy(r,s),d=a.map((m,p)=>{let y=a.length,f=[`📋 [${i}] Plan v${n??"?"} ready for approval (${p+1}/${y}):`,"",p===0?"Full plan:":""].filter(Boolean).join(`
218
+ `),c=ju(o,p===y-1);return`${f}
219
+ ${m}${c}`}),l=d.reduce((m,p)=>Math.max(m,p.length),0);if(l<=Hs)return d;let u=l-Hs;s-=Math.max(u,50)}return[Ly({sessionName:i,actionableVersion:n,fullPlanText:r,hasButtons:o})]}function Js(t){let{preview:e,artifact:n}=t,r=n?.markdown?.trim();return r&&r.length<=Uu?`Full plan:
220
+ ${r}`:zs(r||e)}function Gu(t){let{sessionName:e,actionableVersion:n,preview:r,artifact:o,hasButtons:i}=t,s=o?.markdown?.trim(),a=Vu(e);if(s){let l=`📋 [${a}] Plan v${n??"?"} ready for approval:
216
221
 
217
222
  Full plan:
218
223
  ${s}
219
224
 
220
- ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`;return l.length<=su?{displayMode:"single-full-plan",userMessages:[l],reviewSummary:`Full plan:
221
- ${s}`}:{displayMode:"chunked-full-plan",userMessages:Mh({sessionName:e,actionableVersion:n,fullPlanText:s,hasButtons:i}),reviewSummary:_s(s)}}let d=_s(r);return{displayMode:"summary",userMessages:[`📋 [${a}] Plan v${n??"?"} ready for approval:
225
+ ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`;return l.length<=Uu?{displayMode:"single-full-plan",userMessages:[l],reviewSummary:`Full plan:
226
+ ${s}`}:{displayMode:"chunked-full-plan",userMessages:Fy({sessionName:e,actionableVersion:n,fullPlanText:s,hasButtons:i}),reviewSummary:zs(s)}}let d=zs(r);return{displayMode:"summary",userMessages:[`📋 [${a}] Plan v${n??"?"} ready for approval:
222
227
 
223
228
  ${d}
224
229
 
225
- ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`],reviewSummary:d}}function cu(t){let e=t?.trim();return e||void 0}function _h(t){let e=cu(t.questionText)??"The session is waiting for your reply.",n=cu(t.contextSummary);return n?[`❓ [${t.sessionName}] Question waiting for reply:`,"",e,"",`Why: ${n}`].join(`
230
+ ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`],reviewSummary:d}}function Hu(t){let e=t?.trim();return e||void 0}function By(t){let e=Hu(t.questionText)??"The session is waiting for your reply.",n=Hu(t.contextSummary);return n?[`❓ [${t.sessionName}] Question waiting for reply:`,"",e,"",`Why: ${n}`].join(`
226
231
  `):`❓ [${t.sessionName}] Question waiting for reply:
227
232
 
228
- ${e}`}function $h(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function Nn(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(`
229
- `)}function Ds(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=$h(e,c),f=a??"delegate",m=u&&f==="ask"&&!p?uu({sessionName:e.name,actionableVersion:c,preview:n,artifact:i,hasButtons:!!d}):void 0,h=u?m?.reviewSummary??Es({preview:n,artifact:i}):void 0,k=u?m&&m.userMessages.length===1?m.userMessages[0]:void 0:_h({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!l}),S=u&&m&&m.userMessages.length>1?m.userMessages.map((A,M,R)=>({text:A,buttons:M===R.length-1?d:void 0})):void 0;if(u){let A=f,M="Permission mode: plan → will switch to bypassPermissions on approval";return A==="delegate"?{label:"plan-approval",userMessage:k,userMessages:S,planReviewSummary:h,wakeMessage:["[DELEGATED PLAN APPROVAL] Coding agent session has finished its plan and is requesting approval to implement.",`Name: ${e.name} | ID: ${e.id} | Plan v${c??"?"}`,s,M,"","⚠️ 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(`
230
- `)}:A==="ask"?{label:"plan-approval",userMessage:k,userMessages:S,planReviewSummary:h,wakeMessage:["[USER APPROVAL REQUESTED] Coding agent session has finished its plan. The user has been notified via Telegram and must approve directly.",`Name: ${e.name} | ID: ${e.id} | Plan v${c??"?"}`,s,M,"","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(`
231
- `),buttons:S?void 0:d}:{label:"plan-approval",userMessage:k,planReviewSummary:h,wakeMessage:["[AUTO-APPROVE] Session has a plan ready. Approve it now:",`agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true)`].join(`
232
- `)}}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(`
233
- `),buttons:l}}var wo=3,Os=180,Eh=4e3,pu=32;function mu(){let t=Lt(),e=qh(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 Dh(t,e){let n=Uh(e);if(n.length>0)return n;let r=Oh(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 Oh(t){let e=new Set,n=t.commitMessages.length===1?t.changedFiles:[];return t.commitMessages.map(r=>Wh(r.message,n)).filter(r=>!!r).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,wo)}function Wh(t,e){let n=Nh(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 Ws(`${n}${r}.`,Os)}function Nh(t){let e=Po(bo(t)).replace(/^(?:feat|fix|docs|style|refactor|perf|test|tests|build|ci|chore|revert)(?:\([^)]+\))?!?:\s*/i,"").replace(/\.$/,"").trim();if(!e||Ns(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 fu(t){let e=Lh(t),n=Dh(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=Bh(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 Lh(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:Gh(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=>Po(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:Ws(bo(t.outputPreview??""),Eh)}}function Bh(t){let e=Fh(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>wo)return[];let r=n.map(o=>typeof o=="string"?Po(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>Os)?[]:r.some(Ns)?[]:r}function Fh(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
234
- `).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,wo)}}}function qh(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(`
235
- `)}function Uh(t){let e=new Set;return bo(t??"").replace(/\r\n/g,`
233
+ ${e}`}function qy(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function jn(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(`
234
+ `)}function Ys(t){let{session:e,preview:n,questionText:r,questionContextSummary:o,planArtifact:i,originThreadLine:s,planApprovalMode:a,planApprovalButtons:d,questionButtons:l}=t,u=e.pendingPlanApproval,m=e.actionablePlanDecisionVersion??e.planDecisionVersion,p=qy(e,m),y=a??"delegate",f=u&&y==="ask"&&!p?Gu({sessionName:e.name,actionableVersion:m,preview:n,artifact:i,hasButtons:!!d}):void 0,c=u?f?.reviewSummary??Js({preview:n,artifact:i}):void 0,h=u?f&&f.userMessages.length===1?f.userMessages[0]:void 0:By({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!l}),S=u&&f&&f.userMessages.length>1?f.userMessages.map((A,x,R)=>({text:A,buttons:x===R.length-1?d:void 0})):void 0;if(u){let A=y,x="Permission mode: plan → will switch to bypassPermissions on approval";return A==="delegate"?{label:"plan-approval",userMessage:h,userMessages:S,planReviewSummary:c,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${m??"?"}`,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(`
235
+ `)}:A==="ask"?{label:"plan-approval",userMessage:h,userMessages:S,planReviewSummary:c,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${m??"?"}`,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(`
236
+ `),buttons:S?void 0:d}:{label:"plan-approval",userMessage:h,planReviewSummary:c,wakeMessage:["[AUTO-APPROVE] Session has a plan ready. Approve it now:",`agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true)`].join(`
237
+ `)}}let b=e.multiTurn?"Multi-turn session":"Session";return{label:"waiting",userMessage:h,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(`
238
+ `),buttons:l}}mt();var Oo=3,Zs=180,Uy=4e3,zu=32;function Qu(){let t=tt(),e=Jy(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=Yy(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 Ky(t,e){let n=Zy(e);if(n.length>0)return n;let r=Vy(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 Vy(t){let e=new Set,n=t.commitMessages.length===1?t.changedFiles:[];return t.commitMessages.map(r=>jy(r.message,n)).filter(r=>!!r).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Oo)}function jy(t,e){let n=Gy(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}.`,Zs)}function Gy(t){let e=No(Wo(t)).replace(/^(?:feat|fix|docs|style|refactor|perf|test|tests|build|ci|chore|revert)(?:\([^)]+\))?!?:\s*/i,"").replace(/\.$/,"").trim();if(!e||ea(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 Ju(t){let e=Hy(t),n=Ky(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=zy(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 Hy(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:tk(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=>No(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:Xs(Wo(t.outputPreview??""),Uy)}}function zy(t){let e=Qy(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>Oo)return[];let r=n.map(o=>typeof o=="string"?No(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>Zs)?[]:r.some(ea)?[]:r}function Qy(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
239
+ `).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,Oo)}}}function Jy(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 Yy(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(`
240
+ `)}function Zy(t){let e=new Set;return Wo(t??"").replace(/\r\n/g,`
236
241
  `).split(`
237
- `).map(r=>Po(r)).map(r=>Vh(r)).filter(jh).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,wo)}function Vh(t){return t.replace(/^(?:summary|done|completed|changes|validation|verified)\s*:\s*/i,"").trim()}function jh(t){return t.length<12||t.length>Os||Ns(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 Gh(t){let e=t?.replace(/\r\n/g,`
242
+ `).map(r=>No(r)).map(r=>Xy(r)).filter(ek).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Oo)}function Xy(t){return t.replace(/^(?:summary|done|completed|changes|validation|verified)\s*:\s*/i,"").trim()}function ek(t){return t.length<12||t.length>Zs||ea(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 tk(t){let e=t?.replace(/\r\n/g,`
238
243
  `).split(`
239
- `).map(o=>o.trim()).filter(Boolean).join(" ");if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=bo(n).replace(/\s+/g," ").trim();return r?Ws(r,180):void 0}function Po(t){return t.replace(/^[-*•]\s+/,"").replace(/\s+/g," ").trim()}function Ws(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function bo(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_-]{${pu},}\\b`,"g"),"[redacted token]")}function Ns(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_-]{${pu},}\\b`).test(t)}ke();function Ce(t){return[t.startedAt,t.worktreeBranch??"unknown-branch",t.worktreePath??"unknown-worktree"].join(":")}var Ro=class{constructor(e){this.deps=e;this.actions=new So({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(`
240
- `)}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(`
241
- `),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,Ur(e,n))}markAutoMergeConflictResolving(e,n,r){this.updatePersistedSessionFor(e,Hd(e,n,r,{notes:[`resolver_session:${n}`]}))}markMerged(e){this.updatePersistedSessionFor(e,jt(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:me(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:me(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=ce(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:me(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 fu({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=pt(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(`
242
- `)}),{notificationSent:!0,worktreeRemoved:!1}}handleAutoMergeSuccess(e,n,r,o,i,s){ye(n,r),this.markMerged(e);let a=ft({kind:"merge",branch:r,base:o,filesChanged:i.filesChanged,insertions:i.insertions,deletions:i.deletions}),d=a;s.stashPopConflict?d+=`
244
+ `).map(o=>o.trim()).filter(Boolean).join(" ");if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=Wo(n).replace(/\s+/g," ").trim();return r?Xs(r,180):void 0}function No(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 Wo(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_-]{${zu},}\\b`,"g"),"[redacted token]")}function ea(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_-]{${zu},}\\b`).test(t)}ve();function _e(t){return[t.startedAt,t.worktreeBranch??"unknown-branch",t.worktreePath??"unknown-worktree"].join(":")}var Lo=class{constructor(e){this.deps=e;this.actions=new Eo({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(`
245
+ `)}notifyAutoMergeConflictEscalation(e,n,r,o,i=[]){this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-escalated",idempotencyKey:`worktree-merge-conflict-escalated:${e.id}:${n}:${_e(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(`
246
+ `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,o,{},[[this.deps.makeOpenPrButton(e.id)]])})}updatePersistedSessionFor(e,n){for(let r of ce(e))this.deps.updatePersistedSession(r,n)}markPendingDecision(e,n={}){this.updatePersistedSessionFor(e,no(e,n))}markAutoMergeConflictResolving(e,n,r){this.updatePersistedSessionFor(e,Tl(e,n,r,{notes:[`resolver_session:${n}`]}))}markMerged(e){this.updatePersistedSessionFor(e,Zt(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:fe(n.repoDir,n.worktreePath);return Se(n.repoDir,n.branchName),this.markMerged(e),{notificationSent:!1,worktreeRemoved:r}}if(n.kind==="released"){let r=n.nativeBackendWorktree?!0:fe(n.repoDir,n.worktreePath);return Se(n.repoDir,n.branchName),this.markReleased(e,n.reasons),{notificationSent:!1,worktreeRemoved:r}}return n.policyBlocked?this.shouldUpdateExistingOpenPr(e,n.repoDir,n.branchName,n.baseBranch)?this.handleAutoPrStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,{merge:!1,pr:!0}):(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}:${_e(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.baseBranch)?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=pe(e)){if(this.hasCurrentlyOpenPrForBranch(e,n,o)){let d=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:d,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=this.getDeliveredRemoteOutcome(e),a=i?!0:fe(n,r);return a?(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),remoteOutcome:s}))):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),remoteOutcome:s})),{notificationSent:!0,worktreeRemoved:a}}hasCurrentlyOpenPrForBranch(e,n,r){return this.deps.hasOpenPrForBranch?.(n,r,e.worktreePrTargetRepo)===!0}getDeliveredRemoteOutcome(e){return ce(e).map(r=>this.deps.getPersistedSession?.(r)).find(r=>r?.worktreeRemoteOutcome==="pr-updated"||r?.worktreeRemoteOutcome==="pr-opened")?.worktreeRemoteOutcome}hasRecordedOpenTargetPr(e,n,r){if(!e.worktreePrUrl)return!1;let o=this.getPrStatusForUrl(n,e.worktreePrUrl,e.worktreePrTargetRepo);return o.state==="open"&&(!r||!o.baseRefName||o.baseRefName===r)}shouldUpdateExistingOpenPr(e,n,r,o){return e.worktreeStrategy==="auto-pr"&&(this.hasCurrentlyOpenPrForBranch(e,n,r)||this.hasRecordedOpenTargetPr(e,n,o))}async handleAskStrategy(e,n,r,o,i,s){let a=await Ju({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(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}:${_e(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(`
247
+ `)}),{notificationSent:!0,worktreeRemoved:!1}}handleAutoMergeSuccess(e,n,r,o,i,s){Se(n,r),this.markMerged(e);let a=wt({kind:"merge",branch:r,base:o,filesChanged:i.filesChanged,insertions:i.insertions,deletions:i.deletions}),d=a;s.stashPopConflict?d+=`
243
248
  ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${s.stashRef??"stash@{0}"}\` in ${n} to review stashed changes.`:s.stashed&&(d+=`
244
- (Pre-existing changes on ${o} were auto-stashed and restored.)`),d=Oe(d,s);let l=Kt(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:Yt({sessionId:e.id,sessionName:e.name,outcomeLine:a,originThreadLine:this.deps.originThreadLine(e),detailLines:u,canonicalStatusDelivered:!0}),wakeMessageOnNotifyFailed:Yt({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?Kt(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(`
245
- `)})}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(`
246
- `),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(`
247
- `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i,{},[[this.deps.makeOpenPrButton(e.id)]])})}async handleAutoMergeStrategy(e,n,r,o,i,s,a=j(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=Oe(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)??Ve(e,n,r)}releaseIfRepresentedByTargetPrBranch(e,n,r,o,i){if(pt(r).length>0)return;let s=De(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&&Te(n,o,s)))return;let u=ce(e)?!0:me(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 $y,statSync as Ey,writeFileSync as Dy}from"fs";xe();import{randomUUID as Hh}from"crypto";function zh(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var Ao=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:Hh(),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||!zh(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 Io=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?O(s):void 0)??r}let o=this.getLatestPersistedByName(e);if(o)return O(o)??o.harnessSessionId;let i=this.indexes.backendIdIndex.get(e);if(i){let s=this.indexes.persisted.get(i);return(s?O(s):void 0)??i}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?O(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 Iu,mkdirSync as Py,readFileSync as by,readdirSync as Ry,renameSync as xu,statSync as Tu,unlinkSync as Cu,writeFileSync as Mu}from"fs";import{tmpdir as Ay}from"os";import{dirname as Iy,join as _u}from"path";import{homedir as Qh}from"node:os";import{join as Jh}from"node:path";function gu(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||Qh();return Jh(n,".openclaw")}xe();var xo=7,Yh=new Set(["running","completed","failed","killed"]),Zh=new Set(["queued","running","waiting","blocked","succeeded","failed","cancelled","lost"]);function We(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 le(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function Xh(t){if(!We(t))return;let e=P(t.flowId),n=le(t.revision);if(!e||n===void 0)return;let r=typeof t.status=="string"&&Zh.has(t.status)?t.status:void 0;return{flowId:e,revision:n,...r?{status:r}:{}}}function hu(t){return typeof t=="string"&&Bd.has(t)?t:void 0}function Ls(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function ey(t){return t==="never"||t==="on-request"?"never":void 0}function yu(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function ty(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function ku(t){return typeof t=="string"&&qr.has(t)?t:void 0}function Bs(t){return typeof t=="string"&&Ld.has(t)?t:void 0}function Su(t){return t==="github"||t==="unsupported"?t:void 0}function ny(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function ry(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function vu(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 oy(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function iy(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 sy(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 wu(t){return t==="live"||t==="stopped"?t:void 0}function ay(t){if(!We(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:le(t.rawCompletedAt),rawOutputPath:P(t.rawOutputPath),normalizedStatus:n,normalizedLifecycle:vu(t.normalizedLifecycle),normalizedRuntimeState:wu(t.normalizedRuntimeState)}}function dy(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:le(t.completedAt),rawOutputPath:P(t.outputPath),normalizedStatus:"killed",normalizedLifecycle:"suspended",normalizedRuntimeState:"stopped"}}function ly(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function uy(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function cy(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function py(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function my(t){return t==="in_flight"||t==="delivered"?t:void 0}function fy(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!We(n))return;let r=P(n.key),o=my(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 gy(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!We(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 hy(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 yy(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 Pu(t){if(!We(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 ky(t,e,n){if(We(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 Sy(t){if(!We(t))return;let e=sy(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 vy(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 wy(t){if(typeof t=="string"&&Yh.has(t))return t==="running"?"killed":t}function bu(t){if(!We(t))return;let e=Zt(t.harnessSessionId);if(!e)return;let n=wy(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=Pu(t.route);if(!l)return;let u=st({route:l,originChannel:s,originThreadId:a,originSessionKey:d});if(!u||o&&!i)return;let c=P(t.harness),p=ky(t.backendRef,c,e),f=Sy(t.worktreeLifecycle)??vy(t),m=P(t.completionWakeSucceededAt),h=P(t.completionWakeSkippedAt),k=t.completionWakeSummaryRequired===!0&&!h?!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:hu(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:le(t.createdAt),completedAt:le(t.completedAt),status:n,lifecycle:r?"suspended":vu(t.lifecycle),approvalState:oy(t.approvalState),worktreeState:iy(t.worktreeState),runtimeState:r?"stopped":wu(t.runtimeState),runtimeRecovery:r?dy(t):ay(t.runtimeRecovery),taskFlowMirror:Xh(t.taskFlowMirror),deliveryState:py(t.deliveryState),notificationDedupe:fy(t.notificationDedupe),completionSummaryDedupe:gy(t.completionSummaryDedupe),completionWakeIssuedAt:P(t.completionWakeIssuedAt),completionWakeSucceededAt:m,completionWakeFailedAt:P(t.completionWakeFailedAt),completionWakeSkippedAt:h,completionWakeSkipReason:P(t.completionWakeSkipReason),completionWakeSummaryRequired:k,killReason:ry(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:Ls(t.requestedPermissionMode),currentPermissionMode:Ls(t.currentPermissionMode),approvalExecutionState:hy(t.approvalExecutionState),approvalRationale:P(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:ty(t.planApprovalContext),planDecisionVersion:le(t.planDecisionVersion),actionablePlanDecisionVersion:le(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:le(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:le(t.approvalPromptRequiredVersion),approvalPromptVersion:le(t.approvalPromptVersion),approvalPromptStatus:ly(t.approvalPromptStatus),approvalPromptTransport:uy(t.approvalPromptTransport),approvalPromptMessageKind:cy(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:P(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:P(t.approvalPromptDeliveredAt),approvalPromptFailedAt:P(t.approvalPromptFailedAt),planApproval:yu(t.planApproval),codexApprovalPolicy:ey(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:ku(t.worktreeStrategy),repoIntegrationPolicy:Bs(t.repoIntegrationPolicy),repoIntegrationPolicySource:ny(t.repoIntegrationPolicySource),repoProvider:Su(t.repoProvider),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:P(t.worktreeMergedAt),worktreePrUrl:P(t.worktreePrUrl),worktreePrNumber:le(t.worktreePrNumber),pendingWorktreeDecisionSince:P(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:P(t.lastWorktreeReminderAt),worktreeBaseBranch:P(t.worktreeBaseBranch),worktreePrTargetRepo:P(t.worktreePrTargetRepo),autoMergeParentSessionId:P(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:le(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 Ru(t){if(!We(t))return;let e=P(t.key),n=P(t.repoRoot),r=Bs(t.policy),o=Su(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 Au(t){if(!We(t))return;let e=yy(t.kind),n=Zt(t.id),r=Zt(t.sessionId),o=le(t.createdAt);if(!(!n||!r||!e||o==null))return{id:n,sessionId:r,kind:e,createdAt:o,planDecisionVersion:le(t.planDecisionVersion),expiresAt:le(t.expiresAt),consumedAt:le(t.consumedAt),optionIndex:le(t.optionIndex),pendingInputRequestId:P(t.pendingInputRequestId),pendingInputQuestionId:P(t.pendingInputQuestionId),label:P(t.label),targetUrl:P(t.targetUrl),route:Pu(t.route),launchName:P(t.launchName),launchPrompt:P(t.launchPrompt),launchWorkdir:P(t.launchWorkdir),launchModel:P(t.launchModel),launchReasoningEffort:hu(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:Ls(t.launchPermissionMode),launchPlanApproval:yu(t.launchPlanApproval),launchHarness:P(t.launchHarness),launchWorktreeStrategy:ku(t.launchWorktreeStrategy),launchWorktreeBaseBranch:P(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:P(t.launchWorktreePrTargetRepo),launchOriginAgentId:P(t.launchOriginAgentId),repoPolicy:Bs(t.repoPolicy),repoPolicyWorkdir:P(t.repoPolicyWorkdir)}}function To(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 Ln(t){return!!t&&typeof t=="object"}function Fs(t){return t instanceof Error?t.message:String(t)}function xy(t,e){JSON.stringify({component:"SessionStore",event:t,at:new Date().toISOString(),...e})}function Ty(t){return Ln(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 $u(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(!Iu(s))return s}}function qs(){let t=Ay();return Ry(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>_u(t,e))}function Eu(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||_u(gu(t),"code-agent-sessions.json")}function Du(t,e,n,r=[]){try{Py(Iy(t),{recursive:!0});let o=t+".tmp";Mu(o,JSON.stringify({schemaVersion:xo,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),xu(o,t)}catch(o){`${Fs(o)}`}}function Cy(t,e){try{if(!Iu(t))return!1;let n=$u(t,"legacy");return n?(xu(t,n),`${e}${n}`,!0):!1}catch(n){return`${Fs(n)}`,!1}}var My={archiveLegacySessionIndex:Cy};function _y(t,e){try{if(e.length===0)return;let n=$u(t,"codex-sdk-legacy");if(!n)return;Mu(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${Fs(n)}`}}function Ou(t,e,n=[]){try{let r=new Set(n);for(let o of qs())if(!r.has(o))try{let i=Tu(o).mtimeMs;t-i>e&&Cu(o)}catch{}}catch{}}function Wu(t,e,n=[]){try{let r=new Set(n),o;for(let i of qs())if(!r.has(i))try{let s=Tu(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function Nu(t){try{let e=new Set(t);for(let n of qs())if(!e.has(n))try{Cu(n)}catch{}}catch{}}function Lu(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:a}=t,d=l=>My.archiveLegacySessionIndex(e,l)?(n(),!0):!1;try{let l=by(e,"utf-8"),u=JSON.parse(l);if(Array.isArray(u)){if(!d("legacy array store"))return;a();return}if(!Ln(u)||u.schemaVersion!==xo&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!d(`schema mismatch (expected v${xo})`))return;a();return}let c=(R,y)=>{if(!Object.prototype.hasOwnProperty.call(u,R))return[];let w=u[R];if(Array.isArray(w))return w;d(y)&&a()},p=c("sessions","invalid sessions collection");if(p===void 0)return;let f=[],m=[],h=!1;for(let R of p){if(Ln(R)&&R.harness==="codex"){let w=Ln(R.backendRef)?R.backendRef:void 0;if((typeof w?.kind=="string"?w.kind:void 0)!=="codex-app-server"){f.push(R);continue}}let y=bu(R);if(!y){if(!d("invalid v4 session entry"))return;a();return}Ln(R)&&R.status==="running"&&(h=!0,xy("session.recovered_from_running_persisted_row",{sessionId:typeof R.sessionId=="string"?R.sessionId:void 0,hasHarnessSessionId:typeof R.harnessSessionId=="string"&&R.harnessSessionId.length>0,...Ty(R.backendRef),rawStatus:R.status,rawLifecycle:R.lifecycle,rawRuntimeState:R.runtimeState,normalizedStatus:y.status,normalizedLifecycle:y.lifecycle,normalizedRuntimeState:y.runtimeState,reason:y.runtimeRecovery?.reason})),m.push(y)}f.length>0&&_y(e,f);let k=c("actionTokens","invalid action token collection");if(k===void 0)return;let S=[];for(let R of k){let y=Au(R);if(!y){if(!d("invalid v4 action token"))return;a();return}S.push(y)}let b=c("repoPolicies","invalid repo policy collection");if(b===void 0)return;let A=[],M=!1;for(let R of b){let y=Ru(R);if(!y){M=!0;continue}A.push(y)}for(let R of m)r(R);for(let R of S)o(R);for(let R of A)i(R);(f.length>0||h)&&a(),M&&a(),s()}catch(l){if(l.code==="ENOENT"||!d("corrupt or unreadable"))return;a()}}var Oy=new Set(["completed","failed","killed"]),Ks=1440*60*1e3;function Wy(t){return t instanceof Error?t.message:String(t)}var Ny={statSync:Ey};function Ly(t){try{return Ny.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var Co=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??Eu(n),this.actionTokenStore=new Ao(()=>this.saveIndex(),Ks),this.actionTokens=this.actionTokenStore.tokens,this.queries=new Io({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Lu({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(){Du(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){To(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=Ci(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=O(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=st({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,taskFlowMirror:e.taskFlowMirror,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),costUsd:0,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:ut(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};To(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=st({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let d=ut(e.id);if($y(d))s=d;else{let l=e.getOutput().join(`
248
- `);l.length>0&&(Dy(d,l,"utf-8"),s=d)}}catch(d){`${e.id}${Wy(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,taskFlowMirror:e.taskFlowMirror,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};To(a),this.indexPersistedEntry(a),this.saveIndex()}getExistingNotificationDedupe(e){return this.getPersistedSession(e.id)?.notificationDedupe??(e.harnessSessionId?this.getPersistedSession(e.harnessSessionId)?.notificationDedupe:void 0)??(O(e)?this.getPersistedSession(O(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)Ly(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),Ou(e,Ks,this.getReferencedOutputPaths())}getNextTmpOutputCleanupAt(e){return Wu(e,Ks,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||!Oy.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(){Nu(this.getReferencedOutputPaths())}};var By=new Set(["completed","failed","killed"]),Mo=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),By.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 qu from"child_process";var Bu=5e3,Ku=64,Fy={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},qy={execFile:qu.execFile},it=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},$o=class{constructor(e=qy.execFile){this.execFile=e}execFile;async send(e,n,r){F("direct_send_started",{...Ae(e),messageTextLength:n.length,...Y(r)});try{await this.sendViaRuntime(e,n,r),F("direct_send_succeeded",{...Ae(e),deliveryPath:"runtime",...Y(r)});return}catch(o){if(!(o instanceof it))throw F("direct_send_failed",{...Ae(e),deliveryPath:"runtime",...Y(r),error:Us(o)}),o;F("direct_send_runtime_capability_missing",{...Ae(e),deliveryPath:"runtime",...Y(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),F("direct_send_succeeded",{...Ae(e),deliveryPath:"cli-fallback",...Y(r)})}}async sendViaRuntime(e,n,r){let o=Lt(),i=Ga(),s=o?.channel?.outbound?.loadAdapter;if(!o)throw new it("OpenClaw plugin runtime is unavailable for direct notification delivery");if(i==null)throw new it("OpenClaw runtime config snapshot is unavailable for direct notification delivery");if(!o.channel)throw new it(`OpenClaw plugin runtime channel surface is unavailable for direct notification delivery (runtimeVersion=${Vs(o)})`);if(!o.channel.outbound)throw new it(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${Vs(o)})`);if(!s)throw new it(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${Vs(o)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let d=Do(r);if(F("runtime_adapter_loaded",{...Ae(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...Y(r),...d?ms(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=Uy(i),a={text:o,presentation:i,interactive:s};F("presentation_render_started",{...Ae(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...ms(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=jy(l,s,r.channel);if(F("presentation_render_completed",{...Ae(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...fs(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});F("presentation_send_payload_completed",{...Ae(r),...fs(u),...gl(c)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let a=Ky(e,n,r);F("direct_send_cli_fallback_started",{...Ae(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...Y(r)}),this.execFile("openclaw",a,{timeout:Bu,killSignal:"SIGKILL"},(d,l,u)=>{if(!d){F("direct_send_cli_fallback_completed",{...Ae(e),deliveryPath:"cli-fallback",...Y(r)}),i();return}let c=u?.trim()?` | stderr: ${u.trim()}`:"";F("direct_send_cli_fallback_failed",{...Ae(e),deliveryPath:"cli-fallback",...Y(r),error:Us(d),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${Bu}ms timeout: ${Us(d)}${c}`))})})}};function Ae(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function Ky(t,e,n){let r=Do(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 Us(t){return t instanceof Error?t.message:String(t)}function Vs(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function Do(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:Yy(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function Uy(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 Vy(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 jy(t,e,n){if(!e)return t;let r=Vy(t)?t:Gy(t,e);return n!=="telegram"?r:Hy(r,e)}function Gy(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function Hy(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Xt(n.channelData),o=Xt(r?.telegram),i=Qy(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=zy(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function zy(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")<=Ku).map(r=>({text:r.label,callback_data:r.value,...Uu(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function Qy(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")>Ku))&&Jy(i))return{...i,...Uu(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function Jy(t){return Eo(t.callback_data)||Eo(t.url)||_o(t.web_app)||_o(t.webApp)||_o(t.login_url)||_o(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||Xt(t.switch_inline_query_chosen_chat)!==void 0||Xt(t.callback_game)!==void 0||t.pay===!0||Fu(t.copy_text)||Fu(t.copyText)}function Eo(t){return typeof t=="string"&&t.trim().length>0}function _o(t){let e=Xt(t);return Eo(e?.url)}function Fu(t){let e=Xt(t);return Eo(e?.text)}function Uu(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=Fy[e];return n?{style:n}:{}}function Xt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Yy(t){return t.startsWith(`${te}:`)?t:`${te}:${t}`}import*as Vu from"child_process";var en=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 js=3e4,Zy=2e3,Xy=2e4,ge=4;function Bn(t){return t instanceof Error?t.message:String(t)}function ek(){return new Error(`Dispatch timed out after ${js}ms`)}function tk(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var nk={execFile:Vu.execFile},Oo=class{pendingRetryTimers=new Map;orderedDispatches=new en;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}),nk.execFile("openclaw",e,{timeout:js,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"&&tk(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:`${Bn(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:`${Bn(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:`${Bn(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:Bn(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:Bn(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(ek()))},js);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=Zy*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}}};xe();var Wo=class{resolve(e){let n=Ne(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 rk}from"crypto";var No=class{constructor(e={}){}buildChatSendArgs(e,n,r,o=rk()){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=Do(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 ok(t){let e=ik(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 ik(t){let e=t.trim();if(!e)return"";try{return Gs(JSON.parse(e)).trim()}catch{return e}}function Gs(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>Gs(r)).filter(Boolean).join(`
249
- `);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=Gs(e[r]);if(o.trim())return o}return""}var Lo=class{routes=new Wo;transport;directNotifications;executor=new Oo;constructor(e={}){this.transport=e.transport??new No(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new $o: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);F("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(F("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(F("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){F("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}F("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}F("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){F("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length}),i?.();return}let p=u===0?o:i;F("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?ok: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))},h=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,h,m,n.requireDirectUserNotification===!0,d)}else h();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 ju=36,Gu=2,Hu="...";function sk(t){let e=Array.from(t);return e.length<=ju?t:`${e.slice(0,ju-Hu.length).join("")}${Hu}`}var Bo=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 F("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:sk(s.label),callbackData:d.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=Gu)i.push(o.slice(s,s+Gu));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 F("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=An(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 F("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 uk}from"crypto";var ak="duplicate notification already delivered or in flight",Fo=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:ak}:(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 dk}from"crypto";var lk=1024,Fn="duplicate completion follow-up wake already handled",qo="prior human-visible summary already delivered",Ko=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??lk))}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??Fn}:(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,qo);let c=this.deliveredRecords(i.claimKeys,s,o,qo);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:c}}finish(e,n,r=Fn){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=Fn){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=Fn){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===qo&&o!==qo||(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=Ne(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,O(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 j(e)??O(e)??""}digest(e){return dk("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=Fn){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 ck=2e3,pk=new Set(["1","true","yes","on"]);function mk(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&pk.has(t))||ps()}function fk(t){mk()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
250
- `)}var Uo=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new Ko({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new Fo({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,h=!1,k=()=>{h||(h=!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(h){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=gk(n,e),s=u=>Yt({sessionId:o,sessionName:e.name,outcomeLine:i,originThreadLine:dn(e),detailLines:r.detailLines,canonicalStatusDelivered:u}),a=r.summaryWakeRequired??!0,d={required:a,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},l=r.completionSummaryOwner!=="foreground";if(a&&!l){let u=this.getDeliveryRef(e),c=this.completionSummaries.recordVisibleDelivery(e,d,u?this.getPersistedSession?.(u)?.completionSummaryDedupe:void 0,"worktree-outcome");c.records&&this.applyCompletionSummaryDedupePatch(u,c.records)}this.dispatch(e,{label:"worktree-outcome",userMessage:i,notifyUser:"always",requireDirectUserNotification:!0,completionSummary:{...d,required:a&&l},completionWakeSummaryRequired:a&&l,completionWakeOutcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`,idempotencyKey:`worktree-outcome:${r.completionWakeOutcomeKey??n}`,deferConditionalWakeUntilNextTick:!0,deferConditionalWakeMs:ck,wakeMessageOnNotifySuccess:a&&l?s(!0):void 0,wakeMessageOnNotifyFailed:a&&l?s(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return j(e)??O(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}
249
+ (Pre-existing changes on ${o} were auto-stashed and restored.)`),d=Le(d,s);let l=Jt(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}:${_e(e)}`,userMessage:d,notifyUser:"always",completionSummary:{required:!0,producer:"worktree",outcomeKey:`worktree-merge:${e.id}:${r}:${o}:${_e(e)}`},completionWakeSummaryRequired:!0,completionWakeOutcomeKey:`worktree-merge:${e.id}:${r}:${o}:${_e(e)}`,deferConditionalWakeUntilNextTick:!0,wakeMessageOnNotifySuccess:on({sessionId:e.id,sessionName:e.name,outcomeLine:a,originThreadLine:this.deps.originThreadLine(e),detailLines:u,canonicalStatusDelivered:!0}),wakeMessageOnNotifyFailed:on({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?Jt(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 m=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:m});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(y=>`⚠️ ${y}`)].join(`
250
+ `)})}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}:${_e(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(y=>`⚠️ ${y}`)].join(`
251
+ `),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}:${_e(e)}`,userMessage:[o,"","Auto-merge retry did not complete after conflict resolution.",`Branch \`${n}\` was preserved for manual follow-up in ${r}.`].join(`
252
+ `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i,{},[[this.deps.makeOpenPrButton(e.id)]])})}async handleAutoMergeStrategy(e,n,r,o,i,s,a=G(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=Le(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}:${_e(e)}`,userMessage:u})},()=>{this.deps.dispatchSessionNotification(e,{label:"worktree-merge-queued",idempotencyKey:`worktree-merge-queued:${e.id}:${o}:${_e(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}:${_e(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)??ze(e,n,r)}releaseIfRepresentedByTargetPrBranch(e,n,r,o,i){if(St(r).length>0)return;let s=Ce(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&&Me(n,o,s)))return;let u=pe(e)?!0:fe(n,r);return u?(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0}),Se(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 qk,statSync as Uk,writeFileSync as Kk}from"fs";he();import{randomUUID as nk}from"crypto";function rk(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var Fo=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:nk(),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||!rk(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 Bo=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?F(s):void 0)??r}let o=this.getLatestPersistedByName(e);if(o)return F(o)??o.harnessSessionId;let i=this.indexes.backendIdIndex.get(e);if(i){let s=this.indexes.persisted.get(i);return(s?F(s):void 0)??i}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?F(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 ac,mkdirSync as _k,readFileSync as $k,readdirSync as Ek,renameSync as dc,statSync as lc,unlinkSync as uc,writeFileSync as cc}from"fs";import{tmpdir as Dk}from"os";import{dirname as Ok,join as pc}from"path";import{homedir as ok}from"node:os";import{join as ik}from"node:path";function qo(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||ok();return ik(n,".openclaw")}he();var Uo=7,sk=new Set(["running","completed","failed","killed"]),ak=new Set(["queued","running","waiting","blocked","succeeded","failed","cancelled","lost"]);function Fe(t){return!!t&&typeof t=="object"}function sn(t,e=""){return typeof t=="string"&&t.trim().length>0?t:e}function w(t){return typeof t=="string"&&t.trim().length>0?t:void 0}function le(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function dk(t){if(!Fe(t))return;let e=w(t.flowId),n=le(t.revision);if(!e||n===void 0)return;let r=typeof t.status=="string"&&ak.has(t.status)?t.status:void 0;return{flowId:e,revision:n,...r?{status:r}:{}}}function Yu(t){return typeof t=="string"&&vl.has(t)?t:void 0}function ta(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function lk(t){return t==="never"||t==="on-request"?"never":void 0}function Zu(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function uk(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function Xu(t){return typeof t=="string"&&eo.has(t)?t:void 0}function na(t){return typeof t=="string"&&Sl.has(t)?t:void 0}function ec(t){return t==="github"||t==="unsupported"?t:void 0}function ck(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function pk(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function tc(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 mk(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function fk(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 gk(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 nc(t){return t==="live"||t==="stopped"?t:void 0}function hk(t){if(!Fe(t)||t.reason!=="persisted-running-without-runtime")return;let e=w(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:w(t.rawStatus),rawLifecycle:w(t.rawLifecycle),rawRuntimeState:w(t.rawRuntimeState),rawResumable:typeof t.rawResumable=="boolean"?t.rawResumable:void 0,rawCompletedAt:le(t.rawCompletedAt),rawOutputPath:w(t.rawOutputPath),normalizedStatus:n,normalizedLifecycle:tc(t.normalizedLifecycle),normalizedRuntimeState:nc(t.normalizedRuntimeState)}}function yk(t){return{reason:"persisted-running-without-runtime",recoveredAt:new Date().toISOString(),rawStatus:w(t.status),rawLifecycle:w(t.lifecycle),rawRuntimeState:w(t.runtimeState),rawResumable:typeof t.resumable=="boolean"?t.resumable:void 0,rawCompletedAt:le(t.completedAt),rawOutputPath:w(t.outputPath),normalizedStatus:"killed",normalizedLifecycle:"suspended",normalizedRuntimeState:"stopped"}}function kk(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function Sk(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function vk(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function wk(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function Pk(t){return t==="in_flight"||t==="delivered"?t:void 0}function bk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Fe(n))return;let r=w(n.key),o=Pk(n.status),i=w(n.recordedAt);if(!(!r||!o||!i||!Number.isFinite(Date.parse(i))))return{key:r,status:o,recordedAt:i,label:w(n.label)}}).filter(n=>!!n);return e.length>0?e.slice(-64):void 0}function Rk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Fe(n))return;let r=w(n.key),o=w(n.recordedAt);if(!r||!o||!Number.isFinite(Date.parse(o)))return;let i=Array.isArray(n.linkedKeys)?[...new Set(n.linkedKeys.map(w).filter(s=>!!(s&&s!==r)))]:void 0;return{key:r,linkedKeys:i&&i.length>0?i:void 0,recordedAt:o,label:w(n.label),skipReason:w(n.skipReason)}}).filter(n=>!!n);return e.length>0?e.slice(-1024):void 0}function Ak(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 Ik(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 rc(t){if(!Fe(t))return;let e=w(t.provider),n=w(t.accountId),r=w(t.target),o=w(t.threadId),i=w(t.sessionKey);if(!(!e||!r))return{provider:e,accountId:n,target:r,threadId:o,sessionKey:i}}function xk(t,e,n){if(Fe(t)){let r=w(t.kind),o=w(t.conversationId);if(o&&(r==="claude-code"||r==="codex-app-server"||r==="opencode-server"))return{kind:r,conversationId:o,runId:w(t.runId),worktreeId:w(t.worktreeId),worktreePath:w(t.worktreePath)}}if(e==="claude-code")return{kind:"claude-code",conversationId:n}}function Tk(t){if(!Fe(t))return;let e=gk(t.state),n=w(t.updatedAt);if(!e||!n)return;let r=w(t.resolutionSource);return{state:e,updatedAt:n,resolvedAt:w(t.resolvedAt),resolutionSource:r==="agent_merge"||r==="agent_pr"||r==="strategy_no_change"||r==="lifecycle_resolver"||r==="dismiss"||r==="maintenance"?r:void 0,baseBranch:w(t.baseBranch),targetRepo:w(t.targetRepo),pushRemote:w(t.pushRemote),notes:Array.isArray(t.notes)?t.notes.filter(o=>typeof o=="string"&&o.length>0):void 0}}function Ck(t){let e=new Date(0).toISOString(),n=w(t.worktreeMergedAt)??w(t.worktreeDismissedAt)??w(t.pendingWorktreeDecisionSince)??e;if(t.worktreeMerged===!0||t.worktreeDisposition==="merged")return{state:"merged",updatedAt:n,resolvedAt:w(t.worktreeMergedAt)??n,resolutionSource:"agent_merge",baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.worktreeDisposition==="dismissed")return{state:"dismissed",updatedAt:n,resolvedAt:w(t.worktreeDismissedAt)??n,resolutionSource:"dismiss",baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.worktreeDisposition==="no-change-cleaned")return{state:"no_change",updatedAt:n,resolvedAt:n,resolutionSource:"strategy_no_change",baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.worktreeDisposition==="pr-opened"||t.worktreeState==="pr_open")return{state:"pr_open",updatedAt:n,baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.pendingWorktreeDecisionSince||t.worktreeState==="pending_decision")return{state:"pending_decision",updatedAt:n,baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.worktreeState==="merge_conflict_resolving")return{state:"merge_conflict_resolving",updatedAt:n,baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(w(t.worktreePath)||w(t.worktreeBranch))return{state:"provisioned",updatedAt:n,baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)}}function Mk(t){if(typeof t=="string"&&sk.has(t))return t==="running"?"killed":t}function oc(t){if(!Fe(t))return;let e=sn(t.harnessSessionId);if(!e)return;let n=Mk(t.status);if(!n)return;let r=t.status==="running",o=w(t.worktreePath),i=w(t.worktreeBranch),s=w(t.originChannel),a=typeof t.originThreadId=="string"||typeof t.originThreadId=="number"?t.originThreadId:void 0,d=w(t.originSessionKey),l=rc(t.route);if(!l)return;let u=Ee({route:l,originChannel:s,originThreadId:a,originSessionKey:d});if(!u||o&&!i)return;let m=w(t.harness),p=xk(t.backendRef,m,e),y=Tk(t.worktreeLifecycle)??Ck(t),f=w(t.completionWakeSucceededAt),c=w(t.completionWakeSkippedAt),h=t.completionWakeSummaryRequired===!0&&!c?!0:void 0;return{sessionId:w(t.sessionId),harnessSessionId:e,backendRef:p,name:sn(t.name,e),prompt:sn(t.prompt),workdir:sn(t.workdir,"(unknown)"),model:w(t.model),reasoningEffort:Yu(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:le(t.createdAt),completedAt:le(t.completedAt),status:n,lifecycle:r?"suspended":tc(t.lifecycle),approvalState:mk(t.approvalState),worktreeState:fk(t.worktreeState),runtimeState:r?"stopped":nc(t.runtimeState),runtimeRecovery:r?yk(t):hk(t.runtimeRecovery),taskFlowMirror:dk(t.taskFlowMirror),deliveryState:wk(t.deliveryState),notificationDedupe:bk(t.notificationDedupe),completionSummaryDedupe:Rk(t.completionSummaryDedupe),completionWakeIssuedAt:w(t.completionWakeIssuedAt),completionWakeSucceededAt:f,completionWakeFailedAt:w(t.completionWakeFailedAt),completionWakeSkippedAt:c,completionWakeSkipReason:w(t.completionWakeSkipReason),completionWakeSummaryRequired:h,killReason:pk(t.killReason),costUsd:typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)?t.costUsd:0,originAgentId:w(t.originAgentId),originChannel:s,originThreadId:a,originSessionKey:d,route:u,outputPath:w(t.outputPath),harness:m,resumedFromSessionName:w(t.resumedFromSessionName),goalTaskId:w(t.goalTaskId),requestedPermissionMode:ta(t.requestedPermissionMode),currentPermissionMode:ta(t.currentPermissionMode),approvalExecutionState:Ak(t.approvalExecutionState),approvalRationale:w(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:uk(t.planApprovalContext),planDecisionVersion:le(t.planDecisionVersion),actionablePlanDecisionVersion:le(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:le(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:le(t.approvalPromptRequiredVersion),approvalPromptVersion:le(t.approvalPromptVersion),approvalPromptStatus:kk(t.approvalPromptStatus),approvalPromptTransport:Sk(t.approvalPromptTransport),approvalPromptMessageKind:vk(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:w(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:w(t.approvalPromptDeliveredAt),approvalPromptFailedAt:w(t.approvalPromptFailedAt),planApproval:Zu(t.planApproval),codexApprovalPolicy:lk(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:Xu(t.worktreeStrategy),repoIntegrationPolicy:na(t.repoIntegrationPolicy),repoIntegrationPolicySource:ck(t.repoIntegrationPolicySource),repoProvider:ec(t.repoProvider),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:w(t.worktreeMergedAt),worktreePrUrl:w(t.worktreePrUrl),worktreePrNumber:le(t.worktreePrNumber),pendingWorktreeDecisionSince:w(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:w(t.lastWorktreeReminderAt),worktreeBaseBranch:w(t.worktreeBaseBranch),worktreePrTargetRepo:w(t.worktreePrTargetRepo),autoMergeParentSessionId:w(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:le(t.autoMergeConflictResolutionAttemptCount),autoMergeResolverSessionId:w(t.autoMergeResolverSessionId),worktreePushRemote:w(t.worktreePushRemote),worktreeDecisionSnoozedUntil:w(t.worktreeDecisionSnoozedUntil),worktreeDisposition:t.worktreeDisposition==="active"||t.worktreeDisposition==="pr-opened"||t.worktreeDisposition==="merged"||t.worktreeDisposition==="dismissed"||t.worktreeDisposition==="no-change-cleaned"?t.worktreeDisposition:void 0,worktreeRemoteOutcome:t.worktreeRemoteOutcome==="pr-opened"||t.worktreeRemoteOutcome==="pr-updated"?t.worktreeRemoteOutcome:void 0,worktreeDismissedAt:w(t.worktreeDismissedAt),worktreeLifecycle:y,resumable:r?!0:t.resumable===!0}}function ic(t){if(!Fe(t))return;let e=w(t.key),n=w(t.repoRoot),r=na(t.policy),o=ec(t.provider)??"unsupported",i=w(t.createdAt),s=w(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:w(t.remoteUrl),provider:o,createdAt:i,updatedAt:s,source:a}}function sc(t){if(!Fe(t))return;let e=Ik(t.kind),n=sn(t.id),r=sn(t.sessionId),o=le(t.createdAt);if(!(!n||!r||!e||o==null))return{id:n,sessionId:r,kind:e,createdAt:o,planDecisionVersion:le(t.planDecisionVersion),expiresAt:le(t.expiresAt),consumedAt:le(t.consumedAt),optionIndex:le(t.optionIndex),pendingInputRequestId:w(t.pendingInputRequestId),pendingInputQuestionId:w(t.pendingInputQuestionId),label:w(t.label),targetUrl:w(t.targetUrl),route:rc(t.route),launchName:w(t.launchName),launchPrompt:w(t.launchPrompt),launchWorkdir:w(t.launchWorkdir),launchModel:w(t.launchModel),launchReasoningEffort:Yu(t.launchReasoningEffort),launchFastMode:t.launchFastMode===!0?!0:void 0,launchSystemPrompt:w(t.launchSystemPrompt),launchAllowedTools:Array.isArray(t.launchAllowedTools)?t.launchAllowedTools.filter(i=>typeof i=="string"):void 0,launchResumeSessionId:w(t.launchResumeSessionId),launchResumedFromSessionName:w(t.launchResumedFromSessionName),launchResumeWorktreeFrom:w(t.launchResumeWorktreeFrom),launchSessionIdOverride:w(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:ta(t.launchPermissionMode),launchPlanApproval:Zu(t.launchPlanApproval),launchHarness:w(t.launchHarness),launchWorktreeStrategy:Xu(t.launchWorktreeStrategy),launchWorktreeBaseBranch:w(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:w(t.launchWorktreePrTargetRepo),launchOriginAgentId:w(t.launchOriginAgentId),repoPolicy:na(t.repoPolicy),repoPolicyWorkdir:w(t.repoPolicyWorkdir)}}function Ko(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 Gn(t){return!!t&&typeof t=="object"}function ra(t){return t instanceof Error?t.message:String(t)}function Nk(t,e){JSON.stringify({component:"SessionStore",event:t,at:new Date().toISOString(),...e})}function Wk(t){return Gn(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 mc(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(!ac(s))return s}}function oa(){let t=Dk();return Ek(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>pc(t,e))}function fc(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||pc(qo(t),"code-agent-sessions.json")}function gc(t,e,n,r=[]){try{_k(Ok(t),{recursive:!0});let o=t+".tmp";cc(o,JSON.stringify({schemaVersion:Uo,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),dc(o,t)}catch(o){`${ra(o)}`}}function Lk(t,e){try{if(!ac(t))return!1;let n=mc(t,"legacy");return n?(dc(t,n),`${e}${n}`,!0):!1}catch(n){return`${ra(n)}`,!1}}var Fk={archiveLegacySessionIndex:Lk};function Bk(t,e){try{if(e.length===0)return;let n=mc(t,"codex-sdk-legacy");if(!n)return;cc(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${ra(n)}`}}function hc(t,e,n=[]){try{let r=new Set(n);for(let o of oa())if(!r.has(o))try{let i=lc(o).mtimeMs;t-i>e&&uc(o)}catch{}}catch{}}function yc(t,e,n=[]){try{let r=new Set(n),o;for(let i of oa())if(!r.has(i))try{let s=lc(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function kc(t){try{let e=new Set(t);for(let n of oa())if(!e.has(n))try{uc(n)}catch{}}catch{}}function Sc(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:a}=t,d=l=>Fk.archiveLegacySessionIndex(e,l)?(n(),!0):!1;try{let l=$k(e,"utf-8"),u=JSON.parse(l);if(Array.isArray(u)){if(!d("legacy array store"))return;a();return}if(!Gn(u)||u.schemaVersion!==Uo&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!d(`schema mismatch (expected v${Uo})`))return;a();return}let m=(R,k)=>{if(!Object.prototype.hasOwnProperty.call(u,R))return[];let P=u[R];if(Array.isArray(P))return P;d(k)&&a()},p=m("sessions","invalid sessions collection");if(p===void 0)return;let y=[],f=[],c=!1;for(let R of p){if(Gn(R)&&R.harness==="codex"){let P=Gn(R.backendRef)?R.backendRef:void 0;if((typeof P?.kind=="string"?P.kind:void 0)!=="codex-app-server"){y.push(R);continue}}let k=oc(R);if(!k){if(!d("invalid v4 session entry"))return;a();return}Gn(R)&&R.status==="running"&&(c=!0,Nk("session.recovered_from_running_persisted_row",{sessionId:typeof R.sessionId=="string"?R.sessionId:void 0,hasHarnessSessionId:typeof R.harnessSessionId=="string"&&R.harnessSessionId.length>0,...Wk(R.backendRef),rawStatus:R.status,rawLifecycle:R.lifecycle,rawRuntimeState:R.runtimeState,normalizedStatus:k.status,normalizedLifecycle:k.lifecycle,normalizedRuntimeState:k.runtimeState,reason:k.runtimeRecovery?.reason})),f.push(k)}y.length>0&&Bk(e,y);let h=m("actionTokens","invalid action token collection");if(h===void 0)return;let S=[];for(let R of h){let k=sc(R);if(!k){if(!d("invalid v4 action token"))return;a();return}S.push(k)}let b=m("repoPolicies","invalid repo policy collection");if(b===void 0)return;let A=[],x=!1;for(let R of b){let k=ic(R);if(!k){x=!0;continue}A.push(k)}for(let R of f)r(R);for(let R of S)o(R);for(let R of A)i(R);(y.length>0||c)&&a(),x&&a(),s()}catch(l){if(l.code==="ENOENT"||!d("corrupt or unreadable"))return;a()}}var Vk=new Set(["completed","failed","killed"]),ia=1440*60*1e3;function jk(t){return t instanceof Error?t.message:String(t)}var Gk={statSync:Uk};function Hk(t){try{return Gk.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var Vo=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??fc(n),this.actionTokenStore=new Fo(()=>this.saveIndex(),ia),this.actionTokens=this.actionTokenStore.tokens,this.queries=new Bo({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Sc({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(){gc(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){Ko(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=Qi(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=F(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=Ee({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,taskFlowMirror:e.taskFlowMirror,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),costUsd:0,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:yt(e.id),harness:e.harnessName,resumedFromSessionName:e.resumedFromSessionName,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};Ko(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=Ee({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let d=yt(e.id);if(qk(d))s=d;else{let l=e.getOutput().join(`
253
+ `);l.length>0&&(Kk(d,l,"utf-8"),s=d)}}catch(d){`${e.id}${jk(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,taskFlowMirror:e.taskFlowMirror,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,resumedFromSessionName:e.resumedFromSessionName,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};Ko(a),this.indexPersistedEntry(a),this.saveIndex()}getExistingNotificationDedupe(e){return this.getPersistedSession(e.id)?.notificationDedupe??(e.harnessSessionId?this.getPersistedSession(e.harnessSessionId)?.notificationDedupe:void 0)??(F(e)?this.getPersistedSession(F(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)Hk(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),hc(e,ia,this.getReferencedOutputPaths())}getNextTmpOutputCleanupAt(e){return yc(e,ia,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||!Vk.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(){kc(this.getReferencedOutputPaths())}};var zk=new Set(["completed","failed","killed"]),jo=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),zk.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 vc from"child_process";var an=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 sa=3e4,Qk=2e3,Jk=2e4,ye=4;function Hn(t){return t instanceof Error?t.message:String(t)}function Yk(){return new Error(`Dispatch timed out after ${sa}ms`)}function Zk(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var Xk={execFile:vc.execFile},Go=class{pendingRetryTimers=new Map;orderedDispatches=new an;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:ye}),Xk.execFile("openclaw",e,{timeout:sa,killSignal:"SIGKILL"},(s,a,d)=>{if(this.disposed){r?.();return}let l=Date.now()-i;if(!s){let f=n.successValidator?.(a??"");if(f?.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:ye,elapsedMs:l,error:f.reason,terminal:!0}),n.onFinalFailure?.(),r?.();return}if(f?.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:ye,elapsedMs:l,reason:f.reason}),n.shouldContinue?.()!==!1&&n.onSkipped?.(f.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:ye,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"&&Zk(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:ye,elapsedMs:l,error:`${Hn(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(o>=ye||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:ye,elapsedMs:l,error:`${Hn(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:ye,elapsedMs:l,retryDelayMs:p,error:`${Hn(s)}${u}`});let y={timer:setTimeout(()=>{let f=this.pendingRetryTimers.get(n.sessionId);if(f&&(f.delete(y),f.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executeNow(e,n,r,o+1)},p),onCleared:r};y.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(y)})}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:ye}),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:ye,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>=ye||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:ye,elapsedMs:a,error:Hn(s),terminal:!0,...n.terminalOnFailure===!0&&o<ye?{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:ye,elapsedMs:a,retryDelayMs:d,error:Hn(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(Yk()))},sa);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=Qk*2**n;return Math.min(r,Jk)}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}}};he();var Ho=class{resolve(e){let n=Be(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 eS}from"crypto";var zo=class{constructor(e={}){}buildChatSendArgs(e,n,r,o=eS()){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=Xn(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 tS(t){let e=nS(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 nS(t){let e=t.trim();if(!e)return"";try{return aa(JSON.parse(e)).trim()}catch{return e}}function aa(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>aa(r)).filter(Boolean).join(`
254
+ `);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=aa(e[r]);if(o.trim())return o}return""}var Qo=class{routes=new Ho;transport;directNotifications;executor=new Go;constructor(e={}){this.transport=e.transport??new zo(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new $t: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 m=this.routes.resolve(e),p=a;if(p?.()===!1)return;let y=m?.sessionKey?.trim();if(!y){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(y,n,!0,u),{label:r,sessionId:e.id,target:"chat.send",phase:o,routeSummary:`session:${y}`,messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:`session:${y}`,route:m,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(f=>Array.isArray(f)&&f.length>0),u=this.routes.resolve(e);U("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 m=u?`notify:${u.channel}|${u.accountId??""}|${u.target}|${u.threadId??""}`:`notify:system:${e.id}`;if(!u){if(U("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:m,onSuccess:s,onFinalFailure:i,shouldContinue:d});return}let p=()=>{if(U("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:m,onSuccess:s,onFinalFailure:i,shouldContinue:d})},y={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:m,onSuccess:s,onAmbiguousResult:p,onFinalFailure:p,terminalOnFailure:this.directNotifications?!0:void 0,shouldContinue:d};if(this.directNotifications){U("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),y);return}U("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),y)}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}U("wake_notify_sequence_started",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length,buttonChunkIndexes:d.map((u,m)=>u.buttons?.some(p=>Array.isArray(p)&&p.length>0)?m+1:void 0).filter(u=>typeof u=="number"),requireDirectDelivery:s});let l=u=>{if(a?.()===!1)return;let m=d[u];if(!m){U("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length}),i?.();return}let p=u===0?o:i;U("wake_notify_sequence_chunk_selected",{sessionId:e.id,sessionName:e.name,label:r,chunkIndex:u+1,chunkCount:d.length,messageTextLength:m.text.length,failureHandler:u===0?"all-failed":"sequence-success",...Y(m.buttons)}),this.sendUserNotification(e,m.text,`${r}-part-${u+1}`,m.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?tS:void 0;if(o){let u=n.wakeMessageOnNotifySuccess?.trim(),m=n.wakeMessageOnNotifyFailed?.trim(),p=h=>{h&&d?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,h,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,d,l,r?.onWakeSkipped,n.idempotencyKey))},y=h=>{if(h){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let S=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>p(h),S).unref?.();return}p(h)}},f=()=>{d?.()!==!1&&(r?.onNotifySucceeded?.(),u&&y(u))},c=m?()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),y(m))}:()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,c,f,n.requireDirectUserNotification===!0,d)}else c();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 wc=36,Pc=2,bc="...";function rS(t){let e=Array.from(t);return e.length<=wc?t:`${e.slice(0,wc-bc.length).join("")}${bc}`}var Jo=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":case"plugin-update-install":case"plugin-update-restart":return"success";case"plugin-update-remind-later":return"secondary";case"plan-reject":case"worktree-dismiss":case"plugin-update-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 U("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:rS(s.label),callbackData:d.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=Pc)i.push(o.slice(s,s+Pc));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 U("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=_n(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,launchResumedFromSessionName:e.launchResumedFromSessionName,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 U("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();he();import{createHash as aS}from"crypto";var oS="duplicate notification already delivered or in flight",Yo=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:oS}:(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))}};he();ee();he();import{createHash as iS}from"crypto";var sS=1024,zn="duplicate completion follow-up wake already handled",Zo="prior human-visible summary already delivered",Xo=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??sS))}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??zn}:(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,Zo);let m=this.deliveredRecords(i.claimKeys,s,o,Zo);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:m}}finish(e,n,r=zn){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=zn){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=zn){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===Zo&&o!==Zo||(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"),m=this.isTerminalLike(n,o),p=o.startsWith("worktree-pr:")?this.normalizeWorktreePrOutcome(n.outcomeKey?.trim()):void 0,y=p?.aliases.map(f=>`${this.buildVisibleScope(r,e)}:outcome:${this.digest(f)}`)??[];return{primary:a,explicit:!0,claimKeys:[...l,...d?u:[],...y,a],decisionKeys:[a,...p?.blocksAliases?y:[],...d||m?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=Be(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,F(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 G(e)??F(e)??""}digest(e){return iS("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=zn){let i=new Date().toISOString(),s=this.normalizeRecords(n),a=new Set(e),l=[...s.filter(u=>!a.has(u.key)&&!(u.linkedKeys??[]).some(m=>a.has(m))),...e.map(u=>{let m=e.filter(p=>p!==u);return{key:u,linkedKeys:m.length>0?m:void 0,recordedAt:i,label:r,skipReason:o}})];return l.slice(Math.max(0,l.length-this.maxCompletedKeys))}};var dS=2e3,lS=new Set(["1","true","yes","on"]);function uS(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&lS.has(t))||yi()}function cS(t){uS()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
255
+ `)}function pS(t){let e=t?.trim().split(":")??[];if(e[0]!=="worktree-pr")return;let n=e[1]?.toLowerCase();if(n==="updated"||n==="draft-updated")return"pr-updated";if(n==="opened"||n==="draft-opened")return"pr-opened"}var ei=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new Xo({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new Yo({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 m=this.buildCompletionWakePatch(u),p=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifySuccess?.trim()),y=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifyFailed?.trim()),f=!1,c=!1,h=()=>{c||(c=!0,f||(this.releaseNotificationDedupe(r,i),f=!0),this.completionSummaries.finish(l.key,!1))},S=u.shouldDispatch?()=>{let A=u.shouldDispatch?.()!==!1;return A||h(),A}:void 0,b={onNotifyStarted:()=>{this.applyDeliveryState(r,"notifying"),u.hooks?.onNotifyStarted?.()},onNotifySucceeded:()=>{f=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.applyNotifyDeliveryState(r,p?"wake_pending":"idle",p?m:void 0),p||this.completionSummaries.finish(l.key,!1),u.hooks?.onNotifySucceeded?.()},onNotifyFailed:()=>{this.applyNotifyDeliveryState(r,y?"wake_pending":"failed",y?m:void 0),y||(this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),f=!0),u.hooks?.onNotifyFailed?.()},onWakeStarted:()=>{this.applyPersistedPatchWithCompletionWake(r,"wake_pending",m,{completionWakeIssuedAt:new Date().toISOString(),completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),u.hooks?.onWakeStarted?.()},onWakeSucceeded:()=>{f=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(m),{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(c){u.hooks?.onWakeSkipped?.(A);return}f=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label,A),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(m),{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",m,{completionWakeFailedAt:new Date().toISOString()}),this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),f=!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=pS(r.completionWakeOutcomeKey);o&&i&&this.applyPersistedPatch(o,{worktreeRemoteOutcome:i});let s=mS(n,e),a=m=>on({sessionId:o,sessionName:e.name,outcomeLine:s,originThreadLine:fn(e),detailLines:r.detailLines,canonicalStatusDelivered:m}),d=r.summaryWakeRequired??!0,l={required:d,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},u=r.completionSummaryOwner!=="foreground";if(d&&!u){let m=this.getDeliveryRef(e),p=this.completionSummaries.recordVisibleDelivery(e,l,m?this.getPersistedSession?.(m)?.completionSummaryDedupe:void 0,"worktree-outcome");p.records&&this.applyCompletionSummaryDedupePatch(m,p.records)}this.dispatch(e,{label:"worktree-outcome",userMessage:s,notifyUser:"always",requireDirectUserNotification:!0,completionSummary:{...l,required:d&&u},completionWakeSummaryRequired:d&&u,completionWakeOutcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`,idempotencyKey:`worktree-outcome:${r.completionWakeOutcomeKey??n}`,deferConditionalWakeUntilNextTick:!0,deferConditionalWakeMs:dS,wakeMessageOnNotifySuccess:d&&u?a(!0):void 0,wakeMessageOnNotifyFailed:d&&u?a(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return G(e)??F(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}
251
256
  ${n.join(`
252
257
  ---completion-wake---
253
- `)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=Ne(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=Ne(e.session);fk({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 uk("sha256").update(e).digest("hex").slice(0,16)}};function gk(t,e){let n=ot(e);return n?`${t}${n}`:t}ke();import{existsSync as hk}from"fs";var Vo=class{getCompletionState(e,n,r,o){let i=Pn(e,r,o);if(i===void 0)return"has-commits";if(i===0){let s=Pn(e,o,r);return s===void 0?"has-commits":s>0?Te(e,r,o)?"merged":"base-advanced":mt(n)?"dirty-uncommitted":"no-change"}return mt(n)?"dirty-uncommitted":Tr(e,r,o)?"released":"has-commits"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!hk(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 yk}from"node:crypto";function kk(t){let e=t.pendingInputState,n=e?.activeQuestionIndex??0;return e?.questions?.[n]?.id??(e?.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:void 0)}var jo=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=kk(e),u=e.pendingInputState?.requestId??`legacy:${yk()}`,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(`
254
- `);return new Promise((f,m)=>{let h=this.pendingQuestions.get(e.id);h&&(clearTimeout(h.timeoutHandle),h.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(`
255
- `),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();bn();var Sk=new Set(["merged","released","dismissed","none","cleanup_failed"]),vk=new Set(["merged","released","dismissed","no_change","none","cleanup_failed"]),Go=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??O(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:Ts(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(`
256
- `);this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,userMessage:o,notifyUser:"always",buttons:this.getWorktreeDecisionButtons(j(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=tt(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(s.derivedState)?"resolved":"pending"}isResolvedWorktreeDecision(e){if(this.hasResolvedWorktreeDecisionMarker(e))return!0;let n=tt(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(n.derivedState)}hasResolvedWorktreeDecisionMarker(e){return!!(e.worktreeMerged||e.worktreePrUrl||e.lifecycle==="terminal"||e.worktreeState&&Sk.has(e.worktreeState)||e.worktreeLifecycle?.state&&vk.has(e.worktreeLifecycle.state))}isResolvedDerivedWorktreeState(e){return e==="merged"||e==="released"||e==="no_change"||e==="cleanup_failed"}};ke();ee();xe();function qn(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&wk(t.approvalPromptStatus)}function wk(t){return t==="delivered"||t==="fallback_delivered"}function Kn(t,e){return!t||e==null?!1:!!(t.pendingPlanApproval&&t.approvalState==="pending"&&t.lifecycle==="awaiting_plan_decision"&&(t.actionablePlanDecisionVersion??t.planDecisionVersion)===e)}function tn(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(`
257
- `)}function Ho(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(`
258
- `)}import{existsSync as _k,readFileSync as $k}from"fs";var Pk=4e3,zu=180,bk=300;function Qu(){let t=Lt(),e=Ik(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=xk(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 Ju(t){let e=zo(t.question??""),n=zo(Tk(e,t.context??""));if(!t.provider||!e||!n)return;let r={sessionName:t.sessionName,question:e,context:Ck(n,Pk)};try{let o=await Mk(t.provider.generateQuestionContextSummary(r),t.timeoutMs??bk);return Rk(o)}catch(o){let i=o instanceof Error?o.message:String(o);i!=="question-context-summary timed out"&&`${i}`;return}}function Rk(t){let e=Ak(t),n=typeof e=="string"?e:e&&typeof e=="object"&&typeof e.summary=="string"?e.summary:void 0,r=zo(n??"").replace(/^[-*•]\s+/,"").trim();if(!(!r||r.length>zu)&&!(r.split(/[.!?]+/).filter(o=>o.trim()).length>1))return r}function Ak(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return e}}function Ik(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 xk(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 ${zu} characters.`,"Do not answer the question. Do not invent choices. Do not alter option labels or semantics.","","Evidence:",JSON.stringify(t,null,2)].join(`
259
- `)}function Tk(t,e){return t?e.split(/\r?\n/).filter(n=>zo(n)!==t).join(`
260
- `):e}function zo(t){return t.replace(/\s+/g," ").trim()}function Ck(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function Mk(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 Ek=280;function Dk(t,e){if(t.latestPlanArtifactVersion===e&&t.latestPlanArtifact)return t.latestPlanArtifact;let n=t.planFilePath?.trim();if(!(!n||!_k(n)))try{let r=$k(n,"utf-8").trim();return r?{markdown:r,steps:[]}:void 0}catch{return}}function Ok(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(`
261
- `)}function Wk(t){return t.options.map(e=>({label:e.label,description:e.description?.trim()??""})).filter(e=>e.description&&e.description.length<=Ek)}function Zu(t){let e=t?.activeQuestionIndex??0;return t?.questions?.[e]?.id??(t?.activeQuestionIndex!=null?`q${t.activeQuestionIndex}`:void 0)}function Nk(t,e,n){let r=t.pendingInputState;return!!(r&&r.requestId===e&&Zu(r)===n)}function Lk(t){return[t.startedAt??"unknown-started-at",t.result?.session_id??"unknown-backend-session",t.result?.num_turns??0].join(":")}function Yu(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 Qo=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:Nn({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>Kn(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:tn(e,n,!0),wakeMessageOnNotifyFailed:Ho({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:!!Ne(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=ce(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(a&&!l&&(u=me(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=ce(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:a&&!d&&me(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=qn(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(`
258
+ `)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=Be(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=Be(e.session);cS({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 aS("sha256").update(e).digest("hex").slice(0,16)}};function mS(t,e){let n=ct(e);return n?`${t}${n}`:t}ve();import{existsSync as fS}from"fs";var ti=class{getCompletionState(e,n,r,o){let i=Tn(e,r,o);if(i===void 0)return"has-commits";if(i===0){let s=Tn(e,o,r);return s===void 0?"has-commits":s>0?Me(e,r,o)?"merged":"base-advanced":vt(n)?"dirty-uncommitted":"no-change"}return vt(n)?"dirty-uncommitted":qr(e,r,o)?"released":"has-commits"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!fS(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 gS}from"node:crypto";function hS(t){let e=t.pendingInputState,n=e?.activeQuestionIndex??0;return e?.questions?.[n]?.id??(e?.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:void 0)}var ni=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=hS(e),u=e.pendingInputState?.requestId??`legacy:${gS()}`,m=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((y,f)=>` ${f+1}. ${y.label}`)]:[],"",`Send the question to the user and call agent_respond(session="${e.id}", message="<answer>") with their answer.`].join(`
259
+ `);return new Promise((y,f)=>{let c=this.pendingQuestions.get(e.id);c&&(clearTimeout(c.timeoutHandle),c.reject(new Error(`AskUserQuestion superseded by a newer question for session "${e.name}".`)));let h=setTimeout(()=>{this.pendingQuestions.delete(e.id),f(new Error(`AskUserQuestion timed out after ${6e5/1e3}s for session "${e.name}"`))},6e5);h.unref?.(),this.pendingQuestions.set(e.id,{resolve:y,reject:f,questions:i,timeoutHandle:h,requestId:u,questionId:l}),this.dispatchSessionNotification(e,{label:"ask-user-question",idempotencyKey:`ask-user-question:${e.id}:${u}`,userMessage:d,notifyUser:"always",buttons:m,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(`
260
+ `),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();Cn();var yS=new Set(["merged","released","dismissed","none","cleanup_failed"]),kS=new Set(["merged","released","dismissed","no_change","none","cleanup_failed"]),ri=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 ce(e))this.updatePersistedSession(s,{lastWorktreeReminderAt:new Date(n).toISOString()});return!0}sendReminderNotification(e,n){let r=this.buildRoutingProxy({id:e.sessionId??e.name??F(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:js(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(`
261
+ `);this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,userMessage:o,notifyUser:"always",buttons:this.getWorktreeDecisionButtons(G(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 ce(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=lt(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(s.derivedState)?"resolved":"pending"}isResolvedWorktreeDecision(e){if(this.hasResolvedWorktreeDecisionMarker(e))return!0;let n=lt(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(n.derivedState)}hasResolvedWorktreeDecisionMarker(e){return!!(e.worktreeMerged||e.worktreePrUrl||e.lifecycle==="terminal"||e.worktreeState&&yS.has(e.worktreeState)||e.worktreeLifecycle?.state&&kS.has(e.worktreeLifecycle.state))}isResolvedDerivedWorktreeState(e){return e==="merged"||e==="released"||e==="no_change"||e==="cleanup_failed"}};ve();ee();he();function Qn(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&SS(t.approvalPromptStatus)}function SS(t){return t==="delivered"||t==="fallback_delivered"}function Jn(t,e){return!t||e==null?!1:!!(t.pendingPlanApproval&&t.approvalState==="pending"&&t.lifecycle==="awaiting_plan_decision"&&(t.actionablePlanDecisionVersion??t.planDecisionVersion)===e)}function dn(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(`
262
+ `)}function oi(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(`
263
+ `)}import{existsSync as CS,readFileSync as MS}from"fs";mt();var vS=4e3,Rc=180,wS=300;function Ac(){let t=tt(),e=RS(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=AS(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 Ic(t){let e=ii(t.question??""),n=ii(IS(e,t.context??""));if(!t.provider||!e||!n)return;let r={sessionName:t.sessionName,question:e,context:xS(n,vS)};try{let o=await TS(t.provider.generateQuestionContextSummary(r),t.timeoutMs??wS);return PS(o)}catch(o){let i=o instanceof Error?o.message:String(o);i!=="question-context-summary timed out"&&`${i}`;return}}function PS(t){let e=bS(t),n=typeof e=="string"?e:e&&typeof e=="object"&&typeof e.summary=="string"?e.summary:void 0,r=ii(n??"").replace(/^[-*•]\s+/,"").trim();if(!(!r||r.length>Rc)&&!(r.split(/[.!?]+/).filter(o=>o.trim()).length>1))return r}function bS(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return e}}function RS(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 AS(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 ${Rc} characters.`,"Do not answer the question. Do not invent choices. Do not alter option labels or semantics.","","Evidence:",JSON.stringify(t,null,2)].join(`
264
+ `)}function IS(t,e){return t?e.split(/\r?\n/).filter(n=>ii(n)!==t).join(`
265
+ `):e}function ii(t){return t.replace(/\s+/g," ").trim()}function xS(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function TS(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 _S=280;function $S(t,e){if(t.latestPlanArtifactVersion===e&&t.latestPlanArtifact)return t.latestPlanArtifact;let n=t.planFilePath?.trim();if(!(!n||!CS(n)))try{let r=MS(n,"utf-8").trim();return r?{markdown:r,steps:[]}:void 0}catch{return}}function ES(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(`
266
+ `)}function DS(t){return t.options.map(e=>({label:e.label,description:e.description?.trim()??""})).filter(e=>e.description&&e.description.length<=_S)}function Tc(t){let e=t?.activeQuestionIndex??0;return t?.questions?.[e]?.id??(t?.activeQuestionIndex!=null?`q${t.activeQuestionIndex}`:void 0)}function OS(t,e,n){let r=t.pendingInputState;return!!(r&&r.requestId===e&&Tc(r)===n)}function NS(t){return[t.startedAt??"unknown-started-at",t.result?.session_id??"unknown-backend-session",t.result?.num_turns??0].join(":")}function xc(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 si=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:jn({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>Jn(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:dn(e,n,!0),wakeMessageOnNotifyFailed:oi({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:!!Be(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=pe(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(a&&!l&&(u=fe(a,e.worktreePath)),a&&d&&!l&&u&&Se(a,d),u){for(let m of ce(e))this.deps.updatePersistedSession(m,{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=pe(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:a&&!d&&fe(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=Qn(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(`
262
267
  `),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(`
263
- `)}),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} | ${$e(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(`
264
- `),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} | ${$e(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${ws(e.killReason)} | ${i} | ${$e(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=Zu(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"&&qn(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}))??[],h=!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&&h.length?this.deps.getQuestionButtons(e.id,h,{requestId:e.pendingInputState?.requestId,questionId:r?.id}):void 0,S=Dk(e,l),b=r?Wk(r):[],A=r?Ok({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:b}):c,M=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await Ju({sessionName:e.name,question:A??f,context:p,provider:this.deps.questionContextSummaryProvider}):void 0,R=Ds({session:e,preview:f,questionText:e.pendingPlanApproval?void 0:A,questionContextPreview:p,questionContextSummary:M,planArtifact:S,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:d,planApprovalButtons:k,questionButtons:e.pendingPlanApproval?void 0:k}),y=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:()=>Kn(e,l),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,l,y),wakeMessageOnNotifySuccess:tn(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?()=>Nk(e,o,i):void 0,wakeMessageOnNotifyFailed:R.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=Is({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${Lk(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=bs({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i=Yu(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=As({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}:${Yu(e)}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};ee();ke();import{existsSync as Bk}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=ce(o);!l&&i&&Bk(i)&&me(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:j(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:${j(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:j(r)??O(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${j(r)??O(r)??r.harnessSessionId}:${i}`,userMessage:a,notifyUser:"always"}),a}};var Xu=new Set(["starting","running"]);function ec(t,e){JSON.stringify({component:"SessionRuntimeRegistry",event:t,at:new Date().toISOString(),...e})}function tc(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 Yo=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>Xu.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>Xu.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"){ec("runtime.add",{reason:n,...tc(e),activeCountBefore:this.activeSessionCount()}),this.sessions.set(e.id,e)}remove(e,n="unknown"){let r=this.sessions.get(e);ec("runtime.remove",{reason:n,sessionId:e,existed:!!r,...r?tc(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=Ot({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 Xo=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}`),f=ot({costUsd:n.costUsd,duration:typeof n.completedAt=="number"?n.completedAt-n.startedAt:void 0,harnessName:n.harnessName,model:n.model});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}${f}`:o?r?`ℹ️ [${n.name}] Session completed with no worktree changes to merge — native backend worktree released for backend cleanup${f}`:`ℹ️ [${n.name}] Session completed with no worktree changes to merge — worktree cleaned up${f}`:`⚠️ [${n.name}] Session completed with no worktree changes to merge, but worktree cleanup failed. Worktree still exists at ${i}${f}`,wakeMessage:Cs({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(`
265
- `),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(`
266
- `),wakeMessageOnNotifyFailed:[`🔀 Worktree decision required for session \`${n.name}\``,"",c,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`].join(`
267
- `)}}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:xs({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 nc(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
268
- `):Fk(t);return n?o:o.length>e?rc(t)?Ua(o,e):Va(o,e):o}function Fk(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
269
- `).trim();return n?rc(t)?qk(n)??n:e.slice(-20).join(`
270
- `):""}function rc(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 qk(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(`
271
- `)?n:void 0}xe();ke();ae();import{unlinkSync as Kk}from"fs";var ei=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();bn();ke();var oc=10080*60*1e3,Uk=300*1e3,ic="tmp-output:cleanup",Vk=60*1e3;function jk(t){return t instanceof Error?t.message:String(t)}var ti=class{constructor(e){this.deps=e}deps;scheduler=new ei;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=tt(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+oc,()=>{let d=this.deps.store.getPersistedSession(n);d&&this.reconcileResolvedWorktreeRetention(d,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=tt(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<oc))try{if(!e.worktreePath&&!ce(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let d=ce(e)?!1:me(a,e.worktreePath);if(!ce(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}${jk(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(ic);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(ic,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??O(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(W.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+Vk;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()+Uk))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{Kk(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"}};Tn();var sc=new Set(["completed","failed","killed"]),Gk=new Set(["starting","running"]),Hk=5e3;function zk(t,e){return ac("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 Qk(t){return ac("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 ni=class t{registry;sessions;maxSessions;maxPersistedSessions;lastWaitingEventTimestamps=new Map;lastTurnCompleteMarkers=new Map;lastTerminalWakeMarkers=new Map;mergeQueue=new en;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,this.reconcilePersistedTaskFlowMirrors()}static createServiceBundle(e,n){let r=new Yo,o=r.sessions,i=new Co(n.store),s=new Mo,a=new Lo,d=new Bo(i.actionTokenStore,we),l=new ko(o,i),u=new yo({store:i,sessions:o,resolveSession:y=>l.resolveActive(y)}),c=new Uo(a,(y,w)=>u.applySessionPatch(y,w),{getPersistedSession:y=>i.getPersistedSession(y)}),p=new Vo,f=new ho(y=>i.getPersistedSession(y)),m=new Xo,h=new Ro({shouldRunWorktreeStrategy:y=>e.shouldRunWorktreeStrategy(y),isAlreadyMerged:y=>e.isAlreadyMerged(y),resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),getWorktreeCompletionState:(y,w,T,K)=>e.getWorktreeCompletionState(y,w,T,K),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),dispatchSessionNotification:(y,w)=>e.dispatchSessionNotification(y,w),getOutputPreview:(y,w)=>e.getOutputPreview(y,w),originThreadLine:y=>e.originThreadLine(y),getWorktreeDecisionButtons:y=>e.getWorktreeDecisionButtons(y),getPolicyAwareWorktreeDecisionButtons:(y,w,T)=>e.getWorktreeDecisionButtons(y,w,T),makeOpenPrButton:y=>e.makeActionButton(y,"worktree-create-pr","Open PR"),isPrAvailable:y=>e.resolveRepoPolicy(y).prAvailable,hasOpenPrForBranch:(y,w,T)=>{let K=Ue(y,w,T);return K.exists&&K.state==="open"},getPrStatusForUrl:(y,w,T)=>Ve(y,w,T),resolveRepoPolicy:y=>e.resolveRepoPolicy(y),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:m,enqueueMerge:(y,w,T)=>e.enqueueMerge(y,w,T),mergeBranch:$r,spawnConflictResolver:async({session:y,worktreePath:w,prompt:T})=>e.spawn({prompt:T,workdir:w,name:`${y.name}-conflict-resolver`,harness:y.harnessName||ue(),model:y.model,reasoningEffort:y.reasoningEffort,fastMode:y.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:y.id,route:y.route,originChannel:y.originChannel,originThreadId:y.originThreadId,originAgentId:y.originAgentId,originSessionKey:y.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(y,w)=>{let{makeAgentPrTool:T}=await Promise.resolve().then(()=>(eo(),rl));return{success:(await T().execute("auto-pr",{session:y.id,base_branch:w}))?.meta?.success===!0}}}),k=new jo(e.pendingAskUserQuestions,(y,w)=>e.dispatchSessionNotification(y,w),y=>{e.clearWaitingTimestampsForSession(y)},(y,w,T)=>d.getQuestionButtons(y,w,T)),S=new Go(y=>e.buildRoutingProxy(y),(y,w)=>c.dispatch(y,w),(y,w)=>e.updatePersistedSession(y,w),(y,w)=>e.getPolicyAwareWorktreeDecisionButtons(y,{},void 0,w)),b=new ti({store:i,sessions:o,reminders:S,removeRuntimeSession:(y,w)=>r.remove(y,w),persistSession:(y,w)=>e.persistSession(y,w),clearRuntimeSessionState:y=>{e.clearWaitingTimestampsForSession(y),e.lastTurnCompleteMarkers.delete(y),e.lastTerminalWakeMarkers.delete(y)},resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let A=new Qo({persistSession:y=>e.persistSession(y),clearWaitingTimestamp:y=>{e.clearWaitingTimestampsForSession(y)},handleWorktreeStrategy:y=>e.handleWorktreeStrategy(y),resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),dispatchSessionNotification:(y,w)=>e.dispatchSessionNotification(y,w),notifySession:(y,w,T,K)=>e.notifySession(y,w,T,K),clearRetryTimersForSession:y=>a.clearRetryTimersForSession(y),hasTurnCompleteWakeMarker:y=>e.lastTurnCompleteMarkers.has(y),shouldEmitTurnCompleteWake:y=>e.shouldEmitTurnCompleteWake(y),shouldEmitTerminalWake:y=>e.shouldEmitTerminalWake(y),resolvePlanApprovalMode:y=>e.resolvePlanApprovalMode(y),getPlanApprovalButtons:(y,w)=>d.getPlanApprovalButtons(y,w),getResumeButtons:(y,w)=>d.getResumeButtons(y,w),getQuestionButtons:(y,w,T)=>d.getQuestionButtons(y,w,T),extractLastOutputLine:y=>e.extractLastOutputLine(y),getOutputPreview:(y,w)=>e.getOutputPreview(y,w),originThreadLine:y=>e.originThreadLine(y),debounceWaitingEvent:(y,w)=>e.debounceWaitingEvent(y,w),isAlreadyMerged:y=>e.isAlreadyMerged(y),questionContextSummaryProvider:n.questionContextSummaryProvider??Qu()}),M=new Jo({getPersistedSession:y=>i.getPersistedSession(y),resolveActiveSession:y=>l.resolveActive(y),resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),dispatchNotification:(y,w)=>c.dispatch(y,w),buildRoutingProxy:y=>e.buildRoutingProxy(y)}),R=new Zo({hydrateSpawnedSession:(y,w,T)=>{f.hydrateSpawnedSession(y,w,T)},markRunning:y=>{i.markRunning(y),e.onPersistedSessionChanged(i.getPersistedSession(y.id))},handleTerminal:async y=>e.onSessionTerminal(y),handleTurnEnd:(y,w)=>A.handleTurnEnd(y,w),formatLaunchWorkdirLabel:y=>e.formatLaunchWorkdirLabel(y),notifySession:(y,w,T,K)=>e.notifySession(y,w,T,K)});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:h,worktreeDecisions:M,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||qa(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 Dr({...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(sc.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}sc.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 Un({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??W.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=In(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=Vd(n);if(o){let i=Xi(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:es({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:es({provider:n.provider})}}checkRepoPolicyForLaunch(e,n){let r=n??W.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:ts(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=In(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=In(e);if(r)return this.store.setRepoPolicy(Xi(r,n,"stored"))}resetRepoPolicy(e){let n=In(e);return n?this.store.resetRepoPolicy(n.key):!1}requestRepoPolicyForLaunch(e){let n=e.worktreeStrategy??W.defaultWorktreeStrategy??"off",r=this.resolveRepoPolicy(e.workdir);if(!r.identity)return`Error: ${e.workdir} is not a git repository.`;let o=ts(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=zk(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(`
268
+ `)}),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} | ${Ne(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(`
269
+ `),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} | ${Ne(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${Ls(e.killReason)} | ${i} | ${Ne(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=Tc(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"&&Qn(e,l),m=e.pendingInputState?.promptText?.trim()||void 0,p=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),y=!e.pendingPlanApproval&&m?m:!e.pendingPlanApproval&&p!==void 0?p:this.deps.getOutputPreview(e,e.pendingPlanApproval&&d!=="delegate"?Number.POSITIVE_INFINITY:void 0),f=e.pendingInputState?.options.map(P=>({label:P}))??[],c=!n||n.length===0?f:r&&r.options.length>0&&r.options.length<=6&&!r.options.some(P=>P.isOther)&&!r.multiSelect?r.options:n.length===1&&r&&r.options.length===0?f:[],h=e.pendingPlanApproval&&d==="ask"&&!u?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:l}):!e.pendingPlanApproval&&c.length?this.deps.getQuestionButtons(e.id,c,{requestId:e.pendingInputState?.requestId,questionId:r?.id}):void 0,S=$S(e,l),b=r?DS(r):[],A=r?ES({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:b}):m,x=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await Ic({sessionName:e.name,question:A??y,context:p,provider:this.deps.questionContextSummaryProvider}):void 0,R=Ys({session:e,preview:y,questionText:e.pendingPlanApproval?void 0:A,questionContextPreview:p,questionContextSummary:x,planArtifact:S,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:d,planApprovalButtons:h,questionButtons:e.pendingPlanApproval?void 0:h}),k=R.planReviewSummary??y;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:()=>Jn(e,l),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,l,k),wakeMessageOnNotifySuccess:dn(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?()=>OS(e,o,i):void 0,wakeMessageOnNotifyFailed:R.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=Ks({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${NS(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=Bs({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i=xc(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=Us({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}:${xc(e)}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};ee();ve();import{existsSync as WS}from"fs";var ai=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=pe(o);!l&&i&&WS(i)&&fe(s,i,{destructive:!0}),a&&Se(s,a);for(let m of ce(r??n))this.deps.updatePersistedSession(m,{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:G(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:${G(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 ce(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:G(r)??F(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${G(r)??F(r)??r.harnessSessionId}:${i}`,userMessage:a,notifyUser:"always"}),a}};var Cc=new Set(["starting","running"]);function Mc(t,e){JSON.stringify({component:"SessionRuntimeRegistry",event:t,at:new Date().toISOString(),...e})}function _c(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 di=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>Cc.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>Cc.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"){Mc("runtime.add",{reason:n,..._c(e),activeCountBefore:this.activeSessionCount()}),this.sessions.set(e.id,e)}remove(e,n="unknown"){let r=this.sessions.get(e);Mc("runtime.remove",{reason:n,sessionId:e,existed:!!r,...r?_c(r):{},activeCountBefore:this.activeSessionCount()}),this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var li=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=at({harness:e.harnessName,model:e.model})??"default";return e.resumeSessionId?{text:or({sessionName:e.name,resumedFromSessionName:e.resumedFromSessionName,workdirLabel:n,harnessLabel:r}),label:"resumed-launch",idempotencyKey:`resumed-launch:${e.id}:${e.startedAt}:${e.resumeSessionId}`}:{text:`🚀 [${e.name}] Launched | ${n} | ${r}`,label:"launch"}}};var ui=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,worktreeBranch:s,preview:a,originThreadLine:d,preservedSummary:l,remoteOutcome:u}=e,m=l?"preserved":o?"cleaned":"cleanup-failed",p=[s?.trim()||"unknown-branch",i.trim()||"unknown-worktree",n.startedAt].join(":"),y=l??(o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`),f=ct({costUsd:n.costUsd,duration:typeof n.completedAt=="number"?n.completedAt-n.startedAt:void 0,harnessName:n.harnessName,model:n.model}),c=u==="pr-updated"?"PR updated; no local worktree changes remained to merge":u==="pr-opened"?"PR opened; no local worktree changes remained to merge":"Session completed with no worktree changes to merge",h=u==="pr-updated"?`PR updated; no local worktree changes remained to merge — ${y}`:u==="pr-opened"?`PR opened; no local worktree changes remained to merge — ${y}`:void 0,S=u==="pr-updated"?"PR updated; no local worktree changes remained to merge":u==="pr-opened"?"PR opened; no local worktree changes remained to merge":"Session completed with no worktree changes to merge",b=u==="pr-updated"?"Coding agent session updated a PR; no local worktree changes remained to merge.":u==="pr-opened"?"Coding agent session opened a PR; no local worktree changes remained to merge.":void 0;return{label:l?"worktree-no-changes-preserved":o?"worktree-no-changes":"worktree-no-changes-cleanup-failed",idempotencyKey:`worktree-no-change:${n.id}:${m}:${p}`,userMessage:l?`ℹ️ [${n.name}] ${c} — ${l}${f}`:o?r?`ℹ️ [${n.name}] ${c} — native backend worktree released for backend cleanup${f}`:`ℹ️ [${n.name}] ${c} — worktree cleaned up${f}`:`⚠️ [${n.name}] ${S}, but worktree cleanup failed. Worktree still exists at ${i}${f}`,wakeMessage:Gs({sessionName:n.name,sessionId:n.id,headline:b,cleanupSummary:h??y,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`:"",m=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}\``,"",m,`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(`
270
+ `),notifyUser:"always",buttons:s,wakeMessageOnNotifySuccess:["Worktree decision buttons delivered to the user.",`Session: ${n.name} | ID: ${n.id}`,m,"Wait for their button callback — do NOT act on this worktree yourself."].join(`
271
+ `),wakeMessageOnNotifyFailed:[`🔀 Worktree decision required for session \`${n.name}\``,"",m,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`].join(`
272
+ `)}}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,m=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:m,commitLines:l,moreNote:u,originThreadLine:d,diffSummary:i,allowedActions:a,policyReason:s}),notifyUser:"never"}}};function $c(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
273
+ `):LS(t);return n?o:o.length>e?Ec(t)?bd(o,e):Rd(o,e):o}function LS(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
274
+ `).trim();return n?Ec(t)?FS(n)??n:e.slice(-20).join(`
275
+ `):""}function Ec(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 FS(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(`
276
+ `)?n:void 0}he();ve();oe();import{unlinkSync as BS}from"fs";var ci=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();Cn();ve();var Dc=10080*60*1e3,qS=300*1e3,Oc="tmp-output:cleanup",US=60*1e3;function KS(t){return t instanceof Error?t.message:String(t)}var pi=class{constructor(e){this.deps=e}deps;scheduler=new ci;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=lt(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+Dc,()=>{let d=this.deps.store.getPersistedSession(n);d&&this.reconcileResolvedWorktreeRetention(d,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=lt(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<Dc))try{if(!e.worktreePath&&!pe(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let d=pe(e)?!1:fe(a,e.worktreePath);if(!pe(e)&&!d)return;for(let l of ce(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}${KS(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(Oc);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(Oc,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??F(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(L.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+US;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()+qS))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{BS(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"}};Dn();var Nc=new Set(["completed","failed","killed"]),VS=new Set(["starting","running"]),jS=5e3;function GS(t,e){return Wc("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,resumedFromSessionName:t.resumedFromSessionName,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 HS(t){return Wc("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,resumedFromSessionName:t.launchResumedFromSessionName,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 mi=class t{registry;sessions;maxSessions;maxPersistedSessions;lastWaitingEventTimestamps=new Map;lastTurnCompleteMarkers=new Map;lastTerminalWakeMarkers=new Map;mergeQueue=new an;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,this.reconcilePersistedTaskFlowMirrors()}static createServiceBundle(e,n){let r=new di,o=r.sessions,i=new Vo(n.store),s=new jo,a=new Qo,d=new Jo(i.actionTokenStore,ge),l=new $o(o,i),u=new _o({store:i,sessions:o,resolveSession:k=>l.resolveActive(k)}),m=new ei(a,(k,P)=>u.applySessionPatch(k,P),{getPersistedSession:k=>i.getPersistedSession(k)}),p=new ti,y=new Mo(k=>i.getPersistedSession(k)),f=new ui,c=new Lo({shouldRunWorktreeStrategy:k=>e.shouldRunWorktreeStrategy(k),isAlreadyMerged:k=>e.isAlreadyMerged(k),resolveWorktreeRepoDir:(k,P)=>e.resolveWorktreeRepoDir(k,P),getWorktreeCompletionState:(k,P,_,M)=>e.getWorktreeCompletionState(k,P,_,M),updatePersistedSession:(k,P)=>e.updatePersistedSession(k,P),getPersistedSession:k=>i.getPersistedSession(k),dispatchSessionNotification:(k,P)=>e.dispatchSessionNotification(k,P),getOutputPreview:(k,P)=>e.getOutputPreview(k,P),originThreadLine:k=>e.originThreadLine(k),getWorktreeDecisionButtons:k=>e.getWorktreeDecisionButtons(k),getPolicyAwareWorktreeDecisionButtons:(k,P,_)=>e.getWorktreeDecisionButtons(k,P,_),makeOpenPrButton:k=>e.makeActionButton(k,"worktree-create-pr","Open PR"),isPrAvailable:k=>e.resolveRepoPolicy(k).prAvailable,hasOpenPrForBranch:(k,P,_)=>{let M=He(k,P,_);return M.exists&&M.state==="open"},getPrStatusForUrl:(k,P,_)=>ze(k,P,_),resolveRepoPolicy:k=>e.resolveRepoPolicy(k),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:f,enqueueMerge:(k,P,_)=>e.enqueueMerge(k,P,_),mergeBranch:jr,spawnConflictResolver:async({session:k,worktreePath:P,prompt:_})=>e.spawn({prompt:_,workdir:P,name:`${k.name}-conflict-resolver`,harness:k.harnessName||ue(),model:k.model,reasoningEffort:k.reasoningEffort,fastMode:k.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:k.id,route:k.route,originChannel:k.originChannel,originThreadId:k.originThreadId,originAgentId:k.originAgentId,originSessionKey:k.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(k,P)=>{let{makeAgentPrTool:_}=await Promise.resolve().then(()=>(go(),Vl));return{success:(await _().execute("auto-pr",{session:k.id,base_branch:P}))?.meta?.success===!0}}}),h=new ni(e.pendingAskUserQuestions,(k,P)=>e.dispatchSessionNotification(k,P),k=>{e.clearWaitingTimestampsForSession(k)},(k,P,_)=>d.getQuestionButtons(k,P,_)),S=new ri(k=>e.buildRoutingProxy(k),(k,P)=>m.dispatch(k,P),(k,P)=>e.updatePersistedSession(k,P),(k,P)=>e.getPolicyAwareWorktreeDecisionButtons(k,{},void 0,P)),b=new pi({store:i,sessions:o,reminders:S,removeRuntimeSession:(k,P)=>r.remove(k,P),persistSession:(k,P)=>e.persistSession(k,P),clearRuntimeSessionState:k=>{e.clearWaitingTimestampsForSession(k),e.lastTurnCompleteMarkers.delete(k),e.lastTerminalWakeMarkers.delete(k)},resolveWorktreeRepoDir:(k,P)=>e.resolveWorktreeRepoDir(k,P),updatePersistedSession:(k,P)=>e.updatePersistedSession(k,P),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let A=new si({persistSession:k=>e.persistSession(k),clearWaitingTimestamp:k=>{e.clearWaitingTimestampsForSession(k)},handleWorktreeStrategy:k=>e.handleWorktreeStrategy(k),resolveWorktreeRepoDir:(k,P)=>e.resolveWorktreeRepoDir(k,P),updatePersistedSession:(k,P)=>e.updatePersistedSession(k,P),dispatchSessionNotification:(k,P)=>e.dispatchSessionNotification(k,P),notifySession:(k,P,_,M)=>e.notifySession(k,P,_,M),clearRetryTimersForSession:k=>a.clearRetryTimersForSession(k),hasTurnCompleteWakeMarker:k=>e.lastTurnCompleteMarkers.has(k),shouldEmitTurnCompleteWake:k=>e.shouldEmitTurnCompleteWake(k),shouldEmitTerminalWake:k=>e.shouldEmitTerminalWake(k),resolvePlanApprovalMode:k=>e.resolvePlanApprovalMode(k),getPlanApprovalButtons:(k,P)=>d.getPlanApprovalButtons(k,P),getResumeButtons:(k,P)=>d.getResumeButtons(k,P),getQuestionButtons:(k,P,_)=>d.getQuestionButtons(k,P,_),extractLastOutputLine:k=>e.extractLastOutputLine(k),getOutputPreview:(k,P)=>e.getOutputPreview(k,P),originThreadLine:k=>e.originThreadLine(k),debounceWaitingEvent:(k,P)=>e.debounceWaitingEvent(k,P),isAlreadyMerged:k=>e.isAlreadyMerged(k),questionContextSummaryProvider:n.questionContextSummaryProvider??Ac()}),x=new ai({getPersistedSession:k=>i.getPersistedSession(k),resolveActiveSession:k=>l.resolveActive(k),resolveWorktreeRepoDir:(k,P)=>e.resolveWorktreeRepoDir(k,P),updatePersistedSession:(k,P)=>e.updatePersistedSession(k,P),dispatchNotification:(k,P)=>m.dispatch(k,P),buildRoutingProxy:k=>e.buildRoutingProxy(k)}),R=new li({hydrateSpawnedSession:(k,P,_)=>{y.hydrateSpawnedSession(k,P,_)},markRunning:k=>{i.markRunning(k),e.onPersistedSessionChanged(i.getPersistedSession(k.id))},handleTerminal:async k=>e.onSessionTerminal(k),handleTurnEnd:(k,P)=>A.handleTurnEnd(k,P),formatLaunchWorkdirLabel:k=>e.formatLaunchWorkdirLabel(k),notifySession:(k,P,_,M)=>e.notifySession(k,P,_,M)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:a,interactions:d,notifications:m,worktrees:p,questions:h,lifecycle:A,restore:y,stateSync:u,references:l,worktreeStrategy:c,worktreeDecisions:x,runtimeBootstrap:R,worktreeMessages:f,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 y=this.registry.get(e.sessionIdOverride);if(y?.status==="starting"||y?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${y.status}.`);y&&this.registry.remove(y.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||wd(e.prompt),i=this.uniqueName(o);i!==o&&`${o}${i}`;let s=this.checkRepoPolicyForLaunch(e.workdir,e.worktreeStrategy);if(!s.ok){let y=s;throw new Error(y.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);if(!e.route?.provider||!e.route.target)throw new Error(`Cannot launch session "${i}": missing explicit route metadata.`);let d=e.harness??"claude-code",l=this,u,m=d==="claude-code"&&!e.canUseTool?async(y,f)=>{if(!u)throw new Error("canUseTool called before session ID was set");return l.handleAskUserQuestion(u,f)}:e.canUseTool,p=new Hr({...e,workdir:a.actualWorkdir,systemPrompt:a.effectiveSystemPrompt,canUseTool:m},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(Nc.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}Nc.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 rr({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??L.permissionMode,planApproval:e.planApproval,resumeSessionId:e.resumeSessionId,resumeSessionName:e.resumeSessionName,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=$n(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"&&ge(),record:r};let o=Al(n);if(o){let i=ks(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:Ss({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:Ss({provider:n.provider})}}checkRepoPolicyForLaunch(e,n){let r=n??L.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:vs(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=$n(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=$n(e);if(r)return this.store.setRepoPolicy(ks(r,n,"stored"))}resetRepoPolicy(e){let n=$n(e);return n?this.store.resetRepoPolicy(n.key):!1}requestRepoPolicyForLaunch(e){let n=e.worktreeStrategy??L.defaultWorktreeStrategy??"off",r=this.resolveRepoPolicy(e.workdir);if(!r.identity)return`Error: ${e.workdir} is not a git repository.`;let o=vs(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,launchResumedFromSessionName:e.resumedFromSessionName,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=GS(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(`
272
277
  `),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(`
273
- `),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??ue(),o=e.permissionMode??W.permissionMode,i=e.planApproval??W.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=Qk(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 Kn(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:Nn({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:tn(e,n,!0),wakeMessageOnNotifyFailed:Ho({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?Zi({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=$s(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=j(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(qn(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(`
274
- `);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:tn({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=j(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??Ee(p),m=Ke(p,c,f);if(!m)return`Error: Could not compute worktree diff summary for session "${e}".`;let h=this.getPolicyAwareWorktreeDecisionButtons(l,{allowDelegate:!0},o,i);if(!h||h.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:h})),[`Canonical worktree decision prompt sent for session ${s.name} [${l}].`,"Wait for the user's Merge, Open PR, Later, or Discard response.","Do not send a separate plain-text worktree decision message."].join(" ")}buildRoutingProxy(e){return{id:j(e)??O(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||!go(e,n))||!n?e:xr(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,Ur({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(`
275
- `),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()}reconcilePersistedTaskFlowMirrors(){let e=!1;for(let n of this.store.listPersistedSessions()){let r=Qa(n);r&&(n.taskFlowMirror=r,e=!0)}e&&this.store.saveIndex()}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(`
276
- `),d=l=>Rs({sessionId:o,sessionName:e.sessionName,taskName:e.name,summary:n,originThreadLine:dn(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:ue(),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<Hk?!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 dn(e)}extractLastOutputLine(e){return e.getOutput(3).filter(o=>o.trim()).pop()?.trim()||void 0}getOutputPreview(e,n=1e3){return nc(e,n)}resolvePlanApprovalMode(e){return e.planApproval??W.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())Gk.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()}};U();ae();import{definePluginEntry as dc}from"openclaw/plugin-sdk/plugin-entry";function eS(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??W.worktreeDir;if(s)i.add(s);else for(let d of t.listPersistedSessions())if(d.workdir)try{let l=Xk("git",["rev-parse","--show-toplevel"],{cwd:d.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();l&&i.add(lc(l,".worktrees"))}catch{}if(i.size===0)return;let a=0;for(let d of i)try{let l=Jk(d);for(let u of l){if(!u.startsWith("openclaw-worktree-"))continue;let c=lc(d,u);try{let p=Yk(c);if(!p.isDirectory()||p.mtimeMs>r||o.has(c))continue;Zk(c,{recursive:!0,force:!0}),a++}catch(p){`${c}${p instanceof Error?p.message:String(p)}`}}}catch{}a>0&&`${a}${e}`}function tS(t){let e=null,n=null,r=!1,o=!1,i=t.registerTool;Nt(t.runtime);let s=c=>{if(r){c&&!o&&(Nt(t.runtime,c.config),o=!0);return}let p=t.pluginConfig??{};Xs(p),c?(Nt(t.runtime,c.config),o=!0):(Nt(t.runtime),o=!1),e=new ni(W.maxSessions,W.maxPersistedSessions,{worktreeSummaryProvider:mu()}),n=new fo(e),si(e),ai(n),n.start(),eS(e),e.bootstrapMaintenanceSchedules(),r=!0},a=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=!1,o=!1,Nt(void 0),ai(null),si(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=Pl(c);t.registerInteractiveHandler({...p,handler:async f=>(s(),p.handler(f))})};d(c=>Ya(c),{optional:!1,name:"agent_launch"}),d(c=>Td(c),{optional:!1,name:"agent_sessions"}),d(c=>Cd(c),{optional:!1,name:"agent_kill"}),d(c=>Br(c),{optional:!1,name:"agent_output"}),d(c=>Od(c),{optional:!1,name:"agent_respond"}),d(c=>Wd(c),{optional:!1,name:"agent_request_plan_approval"}),d(c=>Nd(c),{optional:!1,name:"agent_request_worktree_decision"}),d(c=>Fd(c),{optional:!1,name:"agent_send_plan_offer"}),d(c=>qd(c),{optional:!1,name:"agent_stats"}),d(c=>Gd(c),{optional:!1,name:"agent_repo_policy"}),d(c=>Qr(c),{optional:!1,name:"agent_merge"}),d(c=>En(c),{optional:!1,name:"agent_pr"}),d(c=>ol(c),{optional:!1,name:"agent_worktree_cleanup"}),d(c=>il(c),{optional:!1,name:"agent_worktree_status"}),d(c=>sl(c),{optional:!1,name:"goal_launch"}),d(c=>dl(c),{optional:!1,name:"goal_status"}),d(c=>ll(c),{optional:!1,name:"goal_stop"}),d(c=>ul(c),{optional:!1,name:"goal_edit"}),u("telegram"),u("discord"),Rl(l),Al(l),Il(l),xl(l),Tl(l),Cl(l),Ml(l),$l(l),El(l),Dl(l),Wl(l),t.registerService({id:"openclaw-code-agent",start:s,stop:a})}var ZT=dc({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:tS});export{ZT as default,tS as register};
278
+ `),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??ue(),o=e.permissionMode??L.permissionMode,i=e.planApproval??L.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,resumedFromSessionName:e.resumedFromSessionName,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,resumeSessionName:e.resumedFromSessionName,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(m=>m.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 m=HS(u);a.has(m)||a.set(m,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,resumedFromSessionName:d.launchResumedFromSessionName,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)}makePluginActionButton(e,n,r,o={}){return this.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 Jn(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:jn({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:dn(e,n,!0),wakeMessageOnNotifyFailed:oi({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,m=d?.prAvailable??!!(l&&l!=="never-pr"&&l!=="manual"),p=u?ys({policy:u,prAvailable:m}):{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=Qs(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=G(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(Qn(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}),m=[`📋 [${a.name}] Plan v${l??"?"} needs your decision:`,"","Why this was escalated:","",o,"","Choose Approve, Revise, or Reject below."].join(`
279
+ `);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:m,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:dn({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=G(o??i??{id:e})??e,u=o?.worktreePath??i?.worktreePath,m=o?.worktreeBranch??i?.worktreeBranch,p=this.resolveWorktreeRepoDir(o?.originalWorkdir??i?.workdir,u);if(!u)return`Error: Session "${e}" has no managed worktree path.`;if(!m)return`Error: Session "${e}" has no managed worktree branch.`;if(!p)return`Error: Session "${e}" has no resolvable repository root for worktree ${u}.`;let y=o?.worktreeBaseBranch??i?.worktreeBaseBranch??We(p),f=je(p,m,y);if(!f)return`Error: Could not compute worktree diff summary for session "${e}".`;let c=this.getPolicyAwareWorktreeDecisionButtons(l,{allowDelegate:!0},o,i);if(!c||c.length===0)return`Error: Could not create worktree decision buttons for session "${e}".`;let h=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:m,baseBranch:y,diffSummary:f,summaryLines:h,buttons:c})),[`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:G(e)??F(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,no({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(`
280
+ `),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()}reconcilePersistedTaskFlowMirrors(){let e=!1;for(let n of this.store.listPersistedSessions()){let r=xd(n);r&&(n.taskFlowMirror=r,e=!0)}e&&this.store.saveIndex()}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"})}notifyResumedLaunch(e){if(!e.resumeSessionId)return;let n=this.formatLaunchWorkdirLabel(e),r=at({harness:e.harnessName,model:e.model})??"default";this.notifySession(e,or({sessionName:e.name,resumedFromSessionName:e.resumedFromSessionName,workdirLabel:n,harnessLabel:r}),"resumed-launch",`resumed-launch:${e.id}:${e.startedAt}:${e.resumeSessionId}`)}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(`
281
+ `),d=l=>qs({sessionId:o,sessionName:e.sessionName,taskName:e.name,summary:n,originThreadLine:fn(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:ue(),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<jS?!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 fn(e)}extractLastOutputLine(e){return e.getOutput(3).filter(o=>o.trim()).pop()?.trim()||void 0}getOutputPreview(e,n=1e3){return $c(e,n)}resolvePlanApprovalMode(e){return e.planApproval??L.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())VS.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();mt();oe();he();import{definePluginEntry as Lc}from"openclaw/plugin-sdk/plugin-entry";function ZS(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??L.worktreeDir;if(s)i.add(s);else for(let d of t.listPersistedSessions())if(d.workdir)try{let l=YS("git",["rev-parse","--show-toplevel"],{cwd:d.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();l&&i.add(da(l,".worktrees"))}catch{}if(i.size===0)return;let a=0;for(let d of i)try{let l=zS(d);for(let u of l){if(!u.startsWith("openclaw-worktree-"))continue;let m=da(d,u);try{let p=QS(m);if(!p.isDirectory()||p.mtimeMs>r||o.has(m))continue;JS(m,{recursive:!0,force:!0}),a++}catch(p){`${m}${p instanceof Error?p.message:String(p)}`}}}catch{}a>0&&`${a}${e}`}function XS(t){if(!t||typeof t!="object")return;let e=t,n=e.channel?.trim().toLowerCase();if(!n)return;let r=n==="telegram"?e.callback?.chatId??e.parentConversationId??e.conversationId:e.parentConversationId??e.conversationId??e.callback?.chatId;if(r)return Te(e.accountId?`${n}|${e.accountId}|${r}`:`${n}|${r}`,e.threadId,e.sessionKey)}function ev(t){let e=null,n=null,r=null,o=!1,i=!1,s=t.registerTool;_t(t.runtime);let a=()=>da(qo(process.env),"plugin-state","openclaw-code-agent"),d=c=>{let h=c.deliveryContext;return h?.channel&&h.to?Te(h.accountId?`${h.channel}|${h.accountId}|${h.to}`:`${h.channel}|${h.to}`,h.threadId,c.sessionKey):Te(c.messageChannel,void 0,c.sessionKey)},l=c=>{r?.maybeCheckForUpdate({route:c})},u=c=>{if(o){c&&!i&&(_t(t.runtime,c.config),i=!0);return}let h=t.pluginConfig??{};xa(h),c?(_t(t.runtime,c.config),i=!0):(_t(t.runtime),i=!1),e=new mi(L.maxSessions,L.maxPersistedSessions,{worktreeSummaryProvider:Qu()}),n=new To(e),r=new nr({stateDir:c?.stateDir??a(),currentVersion:t.version??ca.version??"0.0.0",actionButtonFactory:(S,b,A,x)=>e.makePluginActionButton(S,b,A,x)}),Ei(e),Di(n),Oi(r),n.start(),ZS(e),e.bootstrapMaintenanceSchedules(),o=!0,l()},m=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=null,o=!1,i=!1,_t(void 0),Di(null),Ei(null),Oi(null)},p=(c,h)=>{s(S=>(u(),l(d(S)),c(S)),h)},y={...t,registerCommand(c){t.registerCommand({...c,handler:h=>(u(),l(d(h)),c.handler(h))})}},f=c=>{let h=ou(c);t.registerInteractiveHandler({...h,handler:async S=>(u(),l(XS(S)),h.handler(S))})};p(c=>Cd(c),{optional:!1,name:"agent_launch"}),p(c=>ll(c),{optional:!1,name:"agent_sessions"}),p(c=>ul(c),{optional:!1,name:"agent_kill"}),p(c=>Zr(c),{optional:!1,name:"agent_output"}),p(c=>hl(c),{optional:!1,name:"agent_respond"}),p(c=>yl(c),{optional:!1,name:"agent_request_plan_approval"}),p(c=>kl(c),{optional:!1,name:"agent_request_worktree_decision"}),p(c=>wl(c),{optional:!1,name:"agent_send_plan_offer"}),p(c=>Pl(c),{optional:!1,name:"agent_stats"}),p(c=>xl(c),{optional:!1,name:"agent_repo_policy"}),p(c=>lo(c),{optional:!1,name:"agent_merge"}),p(c=>qn(c),{optional:!1,name:"agent_pr"}),p(c=>jl(c),{optional:!1,name:"agent_worktree_cleanup"}),p(c=>Gl(c),{optional:!1,name:"agent_worktree_status"}),p(c=>Hl(c),{optional:!1,name:"agent_goal_launch"}),p(c=>Ql(c),{optional:!1,name:"agent_goal_status"}),p(c=>Jl(c),{optional:!1,name:"agent_goal_stop"}),p(c=>Yl(c),{optional:!1,name:"agent_goal_edit"}),f("telegram"),f("discord"),su(y),au(y),du(y),lu(y),uu(y),cu(y),pu(y),fu(y),gu(y),hu(y),ku(y),t.registerService({id:"openclaw-code-agent",start:u,stop:m})}var fM=Lc({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:ev});export{fM as default,ev as register,XS as routeFromInteractiveContext};