openclaw-code-agent 4.7.1 → 4.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,45 +1,45 @@
1
- var zc=Object.defineProperty;var J=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var Qc=(t,e)=>{for(var n in e)zc(t,n,{get:e[n],enumerable:!0})};function Ra(t){try{return t?.config?.current?.()}catch{return}}function Et(t,e){if(t&&typeof t=="object"){mt=t,arguments.length>=2?(pn=e,$t=!0):$t||(pn=Ra(mt),$t=!0);return}mt=void 0,pn=void 0,$t=!1}function tt(){return mt}function Ri(){return mt?.tasks?.managedFlows??mt?.taskFlow}function Aa(){return $t||(pn=Ra(mt),$t=!0),pn}var mt,pn,$t,ft=J(()=>{$t=!1});function _a(t){let e=t.chatId.trim(),n=t.topicId.trim();return!/^-?\d+$/.test(e)||!/^\d+$/.test(n)?null:`${e}:topic:${n}`}function pp(t){let e=t.conversationId.trim(),n=e.match(/^(-?\d+):topic:(\d+)$/i);if(n?.[1]&&n[2]){let i=_a({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=_a({chatId:r,topicId:e});return o?{chatId:r,topicId:e,canonicalConversationId:o}:null}function mp(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 fp(t,e){if(!/^\d+$/.test(t))return t;let n=mp(e);return n?`${n}:${t}`:`channel:${t}`}function gp(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 hp(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 yp(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||!cp.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 kp(t,e=pp){try{return e({conversationId:t})}catch{return null}}function xi(t){return{provider:"system",target:"system",sessionKey:t?.trim()||void 0}}function Ti(t,e){return{...t,threadId:e??t.threadId}}function vp(t,e,n){return t==="telegram"&&n?.provider==="telegram"&&!!n.target&&e!==n.target}function wp(t){let e=t?.trim();if(!e)return;let n=yp(e);if(!n)return;let{provider:r,kind:o,rawId:i}=n,s=hp(i),a=null;if(r==="telegram")try{a=Sp.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 Ci(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 _e(t,e,n){let r=wp(n),o=e!=null?String(e):void 0,i=t?.trim();if(!i||i.toLowerCase()==="unknown")return r?Ti(r,o):xi(n);let s=i.split("|").map(m=>m.trim());if(s.length<2)return r?Ti(r,o):xi(n);let[a,d,l]=s,u=s.length>=3?l:d,f=s.length>=3?d:void 0,p=a?.toLowerCase();if(!p||!u)return r?Ti(r,o):xi(n);let k=p==="discord"?fp(u,n):u;return vp(p,k,r)?{provider:p,accountId:f,target:r.target,threadId:o??r.threadId,sessionKey:n?.trim()||void 0}:{provider:p,accountId:f,target:k,threadId:o??(r?.provider===p?r.threadId:void 0),sessionKey:n?.trim()||void 0}}function De(t){return _e(gp(t.route)??t.originChannel,t.route?.threadId??t.originThreadId,t.route?.sessionKey??t.originSessionKey)??t.route}function Ue(t){let e=De(t);return mn(e)?e:void 0}function Pp(t){return Object.fromEntries(Object.entries(t).filter(e=>!!e[1]))}function fn(t){let e=De(t);if(!mn(e))return"";let n=Pp({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 cp,Sp,ye=J(()=>{cp=new Set(["telegram","discord","slack","system","mattermost","feishu","line","whatsapp","signal","matrix","googlechat","bluebubbles","imessage","msteams"]);Sp={safeParseTelegramTopicConversation:kp}});import{readFileSync as bp}from"fs";import{homedir as Rp}from"os";import{join as Ap}from"path";function Ea(){if(gn!==void 0)return gn;try{let t=bp(Ap(Rp(),".claude.json"),"utf-8");gn=JSON.parse(t).mcpServers??{}}catch{gn={}}return gn}function Da(t){let e=t.defaultHarness??$a,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});D={maxSessions:t.maxSessions??20,defaultWorkdir:t.defaultWorkdir,idleTimeoutMinutes:t.idleTimeoutMinutes??15,sessionGcAgeMinutes:t.sessionGcAgeMinutes??1440,maxPersistedSessions:t.maxPersistedSessions??1e4,fallbackChannel:t.fallbackChannel,agentChannels:t.agentChannels,maxAutoResponds:t.maxAutoResponds??10,permissionMode:t.permissionMode??"plan",planApproval:t.planApproval??"delegate",defaultHarness:e,harnesses:n,allowedModels:t.allowedModels,defaultWorktreeStrategy:t.defaultWorktreeStrategy??"delegate",worktreeDir:t.worktreeDir}}function me(){return D.defaultHarness??$a}function $i(t){let e=hn[t],n=D.harnesses[t];return{...e,...n,allowedModels:n?.allowedModels??e?.allowedModels}}function Nt(t){return $i(t).defaultModel}function tr(t){return D.harnesses[t]?.allowedModels??D.allowedModels}function rt(t){return $i(t).reasoningEffort}function Wt(t){return t==="codex"?$i(t).fastMode:void 0}function Te(t){return t==null?void 0:String(t).trim()||void 0}function Ei(t){return{channel:Te(t?.deliveryContext?.channel),to:Te(t?.deliveryContext?.to),accountId:Te(t?.deliveryContext?.accountId),threadId:Te(t?.deliveryContext?.threadId)}}function Oa(t,e,n){if(!(!t||!e))return n?`${t}|${n}|${e}`:`${t}|${e}`}function Mi(t){return Te(t?.requesterSenderId??t?.senderId)}function _i(t){return(Te(t.deliveryContext?.channel)??t.messageChannel??t.channel)?.toLowerCase()!=="telegram"?!1:!!(Ci(t.sessionKey)||Te(t.messageThreadId)||Te(t.deliveryContext?.threadId))}function nr(t){let e=Ei(t),n=Oa(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=Te(t.chatId);if(r.length===1&&o)return`${r[0]}|${o}`;let i=Mi(t);if(r.length===1&&i&&!_i(t))return`${r[0]}|${i}`}if(t.workspaceDir){let r=gt(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=Ei(t),r=Oa(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=Te(t.chatId);if(d)return`${a}|${d}`;let l=Mi(t);if(l&&!_i(t))return`${a}|${l}`}let o=Te(t?.channel),i=Te(t?.chatId);if(o&&i)return`${o}|${i}`;let s=Mi(t);return o&&s&&!_i(t)?`${o}|${s}`:t?.id&&/^-?\d+$/.test(String(t.id))?`telegram|${t.id}`:D.fallbackChannel??"unknown"}function Di(t){return Ei(t).threadId??t?.messageThreadId??void 0}function Lt(t,e,n){return _e(yn(t,e),Di(t),n??t?.sessionKey)}function gt(t){let e=D.agentChannels;if(!e)return;let n=i=>i.replace(/\/+$/,""),r=n(t),o=Object.entries(e).sort((i,s)=>s[0].length-i[0].length);for(let[i,s]of o)if(r===n(i)||r.startsWith(n(i)+"/"))return s}function Na(t){return Ci(t)}var gn,$a,hn,D,ae=J(()=>{ye();$a="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:{}};D={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 Up(t){return{...t,[Ni]:!0}}function Kp(t){return{const:t,type:typeof t}}var Ni,g,se=J(()=>{Ni=Symbol("optionalSchema");g={Object(t,e){let n=Object.entries(t).filter(([,o])=>!o[Ni]).map(([o])=>o),r=Object.fromEntries(Object.entries(t).map(([o,i])=>{let{[Ni]: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:Kp,Union(t,e){return kn({anyOf:t},e)},Optional:Up}});function Wi(t){v=t}function Li(t){Z=t}function Bi(t){Oe=t}var v,Z,Oe,V=J(()=>{v=null,Z=null,Oe=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 Ka(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 Va(t){if(typeof t=="string"){let s=t.trim();return s?{label:s,value:s,recommended:Ka(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:Ka(n,e)}}function sr(t){let e=j(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(Va).filter(r=>!!r):[]}function qt(t){let e=j(t);return(Array.isArray(e?.questions)?e.questions:[]).map((r,o)=>Hp(r,o)).filter(r=>!!r)}function Hp(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(Va).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 ja(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 ar(t){if(t.length===0)return;let e=t.flatMap((n,r)=>[...r>0?[""]:[],...ja(n,r,t.length)]);return t.length>1&&e.push("","Reply with answers by question, for example: Q1: ..., Q2: ..."),e.join(`
1
+ var zc=Object.defineProperty;var J=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var Qc=(t,e)=>{for(var n in e)zc(t,n,{get:e[n],enumerable:!0})};function Ia(t){try{return t?.config?.current?.()}catch{return}}function Et(t,e){if(t&&typeof t=="object"){mt=t,arguments.length>=2?(pn=e,$t=!0):$t||(pn=Ia(mt),$t=!0);return}mt=void 0,pn=void 0,$t=!1}function tt(){return mt}function Ri(){return mt?.tasks?.managedFlows??mt?.taskFlow}function xa(){return $t||(pn=Ia(mt),$t=!0),pn}var mt,pn,$t,ft=J(()=>{$t=!1});function Ea(t){let e=t.chatId.trim(),n=t.topicId.trim();return!/^-?\d+$/.test(e)||!/^\d+$/.test(n)?null:`${e}:topic:${n}`}function pp(t){let e=t.conversationId.trim(),n=e.match(/^(-?\d+):topic:(\d+)$/i);if(n?.[1]&&n[2]){let i=Ea({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=Ea({chatId:r,topicId:e});return o?{chatId:r,topicId:e,canonicalConversationId:o}:null}function mp(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 fp(t,e){if(!/^\d+$/.test(t))return t;let n=mp(e);return n?`${n}:${t}`:`channel:${t}`}function gp(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 hp(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 yp(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||!cp.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 kp(t,e=pp){try{return e({conversationId:t})}catch{return null}}function xi(t){return{provider:"system",target:"system",sessionKey:t?.trim()||void 0}}function Ti(t,e){return{...t,threadId:e??t.threadId}}function vp(t,e,n){return t==="telegram"&&n?.provider==="telegram"&&!!n.target&&e!==n.target}function wp(t){let e=t?.trim();if(!e)return;let n=yp(e);if(!n)return;let{provider:r,kind:o,rawId:i}=n,s=hp(i),a=null;if(r==="telegram")try{a=Sp.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 Ci(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 _e(t,e,n){let r=wp(n),o=e!=null?String(e):void 0,i=t?.trim();if(!i||i.toLowerCase()==="unknown")return r?Ti(r,o):xi(n);let s=i.split("|").map(m=>m.trim());if(s.length<2)return r?Ti(r,o):xi(n);let[a,d,l]=s,u=s.length>=3?l:d,f=s.length>=3?d:void 0,p=a?.toLowerCase();if(!p||!u)return r?Ti(r,o):xi(n);let k=p==="discord"?fp(u,n):u;return vp(p,k,r)?{provider:p,accountId:f,target:r.target,threadId:o??r.threadId,sessionKey:n?.trim()||void 0}:{provider:p,accountId:f,target:k,threadId:o??(r?.provider===p?r.threadId:void 0),sessionKey:n?.trim()||void 0}}function De(t){return _e(gp(t.route)??t.originChannel,t.route?.threadId??t.originThreadId,t.route?.sessionKey??t.originSessionKey)??t.route}function Ue(t){let e=De(t);return mn(e)?e:void 0}function Pp(t){return Object.fromEntries(Object.entries(t).filter(e=>!!e[1]))}function fn(t){let e=De(t);if(!mn(e))return"";let n=Pp({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 cp,Sp,ye=J(()=>{cp=new Set(["telegram","discord","slack","system","mattermost","feishu","line","whatsapp","signal","matrix","googlechat","bluebubbles","imessage","msteams"]);Sp={safeParseTelegramTopicConversation:kp}});import{readFileSync as bp}from"fs";import{homedir as Rp}from"os";import{join as Ap}from"path";function Oa(){if(gn!==void 0)return gn;try{let t=bp(Ap(Rp(),".claude.json"),"utf-8");gn=JSON.parse(t).mcpServers??{}}catch{gn={}}return gn}function Na(t){let e=t.defaultHarness??Da,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});D={maxSessions:t.maxSessions??20,defaultWorkdir:t.defaultWorkdir,idleTimeoutMinutes:t.idleTimeoutMinutes??15,sessionGcAgeMinutes:t.sessionGcAgeMinutes??1440,maxPersistedSessions:t.maxPersistedSessions??1e4,fallbackChannel:t.fallbackChannel,agentChannels:t.agentChannels,maxAutoResponds:t.maxAutoResponds??10,permissionMode:t.permissionMode??"plan",planApproval:t.planApproval??"delegate",defaultHarness:e,harnesses:n,allowedModels:t.allowedModels,defaultWorktreeStrategy:t.defaultWorktreeStrategy??"delegate",worktreeDir:t.worktreeDir}}function me(){return D.defaultHarness??Da}function $i(t){let e=hn[t],n=D.harnesses[t];return{...e,...n,allowedModels:n?.allowedModels??e?.allowedModels}}function Nt(t){return $i(t).defaultModel}function tr(t){return D.harnesses[t]?.allowedModels??D.allowedModels}function rt(t){return $i(t).reasoningEffort}function Wt(t){return t==="codex"?$i(t).fastMode:void 0}function Te(t){return t==null?void 0:String(t).trim()||void 0}function Ei(t){return{channel:Te(t?.deliveryContext?.channel),to:Te(t?.deliveryContext?.to),accountId:Te(t?.deliveryContext?.accountId),threadId:Te(t?.deliveryContext?.threadId)}}function Wa(t,e,n){if(!(!t||!e))return n?`${t}|${n}|${e}`:`${t}|${e}`}function Mi(t){return Te(t?.requesterSenderId??t?.senderId)}function _i(t){return(Te(t.deliveryContext?.channel)??t.messageChannel??t.channel)?.toLowerCase()!=="telegram"?!1:!!(Ci(t.sessionKey)||Te(t.messageThreadId)||Te(t.deliveryContext?.threadId))}function nr(t){let e=Ei(t),n=Wa(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=Te(t.chatId);if(r.length===1&&o)return`${r[0]}|${o}`;let i=Mi(t);if(r.length===1&&i&&!_i(t))return`${r[0]}|${i}`}if(t.workspaceDir){let r=gt(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=Ei(t),r=Wa(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=Te(t.chatId);if(d)return`${a}|${d}`;let l=Mi(t);if(l&&!_i(t))return`${a}|${l}`}let o=Te(t?.channel),i=Te(t?.chatId);if(o&&i)return`${o}|${i}`;let s=Mi(t);return o&&s&&!_i(t)?`${o}|${s}`:t?.id&&/^-?\d+$/.test(String(t.id))?`telegram|${t.id}`:D.fallbackChannel??"unknown"}function Di(t){return Ei(t).threadId??t?.messageThreadId??void 0}function Lt(t,e,n){return _e(yn(t,e),Di(t),n??t?.sessionKey)}function gt(t){let e=D.agentChannels;if(!e)return;let n=i=>i.replace(/\/+$/,""),r=n(t),o=Object.entries(e).sort((i,s)=>s[0].length-i[0].length);for(let[i,s]of o)if(r===n(i)||r.startsWith(n(i)+"/"))return s}function La(t){return Ci(t)}var gn,Da,hn,D,ae=J(()=>{ye();Da="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:{}};D={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 Kp(t){return{...t,[Li]:!0}}function Vp(t){return{const:t,type:typeof t}}var Li,g,se=J(()=>{Li=Symbol("optionalSchema");g={Object(t,e){let n=Object.entries(t).filter(([,o])=>!o[Li]).map(([o])=>o),r=Object.fromEntries(Object.entries(t).map(([o,i])=>{let{[Li]: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:Vp,Union(t,e){return kn({anyOf:t},e)},Optional:Kp}});function Bi(t){v=t}function Fi(t){Z=t}function qi(t){Oe=t}var v,Z,Oe,V=J(()=>{v=null,Z=null,Oe=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 Ka(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 Va(t){if(typeof t=="string"){let s=t.trim();return s?{label:s,value:s,recommended:Ka(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:Ka(n,e)}}function sr(t){let e=j(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(Va).filter(r=>!!r):[]}function qt(t){let e=j(t);return(Array.isArray(e?.questions)?e.questions:[]).map((r,o)=>zp(r,o)).filter(r=>!!r)}function zp(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(Va).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 ja(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 ar(t){if(t.length===0)return;let e=t.flatMap((n,r)=>[...r>0?[""]:[],...ja(n,r,t.length)]);return t.length>1&&e.push("","Reply with answers by question, for example: Q1: ..., Q2: ..."),e.join(`
3
3
  `)}function Ke(t,e,n){return ja(t,e,n).join(`
4
- `)}var Sn=J(()=>{});function Ut(t){return{type:"backend_ref",ref:t}}function Kt(t){return{type:"run_started",...t?{runId:t}:{}}}function yt(t){return{type:"text_delta",text:t}}function dr(t,e){return{type:"tool_call",name:t,input:e}}function Ne(t){return{type:"pending_input",state:t}}function it(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function lr(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function Vt(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function Ve(t){return{type:"run_completed",data:t}}var ot,ur=J(()=>{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 pr from"@anthropic-ai/claude-agent-sdk";function zp(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 Qp(t,e,n){let r=qt(n),o=r.length>0?0:void 0,i=o!=null?r[o]:void 0,s=i?.options.map(d=>d.label)??[],a=i?Ke(i,o,r.length):ar(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 cr,Ga=J(()=>{Sn();ur();cr=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(m,c)=>{if(m!=="AskUserQuestion")return{behavior:"allow"};let y=Qp(a,++s,c);n.enqueue(Ne(y));try{let S=await d(m,c);return n.enqueue(it(y.requestId)),S}catch(S){throw n.enqueue(it(y.requestId)),S}}}:{}};e.resumeSessionId&&(l.resume=e.resumeSessionId,l.forkSession=e.forkSession??!1);let u=e.prompt,f=this.deps.query??pr.query,p=this.deps.startup??pr.startup,k=(async()=>{if(typeof p!="function")return f({prompt:u,options:l});let m=await p({options:l});try{return m.query(u)}catch(c){throw await m.close?.(),c}})();return(async()=>{try{let m=await k;for await(let c of m){let y=c;if(y.type==="system"&&y.subtype==="init"){a=y.session_id??a,n.enqueue(Ut({kind:"claude-code",conversationId:a}));continue}if(y.type==="system"&&y.subtype==="status"&&y.permissionMode){n.enqueue(Vt(y.permissionMode));continue}if(y.type==="assistant"){r||(r=!0,n.enqueue(Kt()));for(let S of y.message?.content??[]){if(S.type==="text"){o+=o?`
6
- ${S.text}`:S.text,n.enqueue(yt(S.text));continue}S.type==="tool_use"&&((S.name==="ExitPlanMode"||S.name==="set_permission_mode")&&(i=!0),S.name!=="AskUserQuestion"&&n.enqueue(dr(S.name,S.input)))}continue}if(y.type==="result"){let S=o.trim();if(S&&(e.permissionMode==="plan"||i)){let b={explanation:void 0,steps:[],markdown:S};n.enqueue(lr(b,!0))}n.enqueue(Ve({success:y.subtype==="success",duration_ms:y.duration_ms??0,total_cost_usd:y.total_cost_usd??0,num_turns:y.num_turns??0,result:zp(y),session_id:y.session_id??a})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(m=>{n.enqueue(Ve({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 c=await k;typeof c.setPermissionMode=="function"&&await c.setPermissionMode(m)},async streamInput(m){let c=await k;typeof c.streamInput=="function"&&await c.streamInput(m)},async interrupt(){let m=await k;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 Jp}from"node:child_process";import Yp from"node:readline";function Ha(t){return t instanceof Error?t.message:String(t)}function jt(t,e){JSON.stringify({component:"CodexAppServerRpc",event:t,at:new Date().toISOString(),...e})}function Zp(t,e){return{commandKind:t==="codex"?"codex":"custom",appServerSubcommand:!0,configuredArgCount:e.length}}function Xp(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function em(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:Ha(r)}})}}}function Fi(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 mr,za=J(()=>{mr=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=Jp(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(jt("process.spawn",{...Zp(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,Yp.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=>{jt("process.error",{pid:e.pid,error:Ha(r)})}),e.on("close",(r,o)=>{jt("process.close",{pid:e.pid,code:r,signal:o,pendingRequests:this.pending.size,recentStderr:Fi(this.stderrTail.trim())}),this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){jt("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),jt("request.timeout",{id:o,method:e,timeoutMs:d,pid:this.process?.pid,recentStderr:Fi(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=Xp(e);n&&await em(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){this.pending.size>0&&jt("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: ${Fi(r)}`:"";return`codex app server timeout after ${n}ms: ${e}${o}`}}});function Qa(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 Ja=J(()=>{});function je(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 tm(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>je("codex",r)?.toLowerCase()===n)}function fr(t,e,n){return t==="codex"?tm(e,n):Qa(e,n)}function Gt(t,e){return t!=="codex"||!e?!0:!e.includes("/")}function gr(t,e,n){if(t!=="codex"||!e||!n||n.length===0)return e;let r=e.toLowerCase(),o=n.find(i=>je("codex",i)?.toLowerCase()===r);return je("codex",o)??e}var hr=J(()=>{Ja()});function nm(t){return t instanceof Error?t.message:String(t)}function Ya(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 yr(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=yr(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=yr(i,e,n+1);if(s)return s}}function wn(t){return{threadId:vn(t).threadId,cwd:yr(t,["cwd","workdir","directory"])}}function Za(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function Xa(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 kr(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 rm(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 ed(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:st(e),itemId:kr(e)}:n==="item/completed"?{mode:"snapshot",text:rm(e),itemId:kr(e)}:{mode:"ignore",text:""}}function td(t){return{itemId:kr(t),delta:st(t)}}function nd(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 rd(t){let e=j(t);if(!e)return{};let n=j(e.item)??e;return H(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:kr(n),text:H(n,["text"],{trim:!1})??st(n)}}function od(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 id(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 om(t,e){let n=nm(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 sm(t){return im.has(t.trim().toLowerCase())}function am(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(sm(n)&&!am(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,!om(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function sd(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 ad(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 dm(t){return[{type:"text",text:t}]}function lm(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 dd(t){let e={threadId:t.threadId,input:dm(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=lm(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function ld(t){return[{threadId:t.threadId,turnId:t.turnId}]}function um(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 ud(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=qt(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let a=o?sr(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),k=(l?Ke(l,d??0,s.length):ar(s))??(o?yr(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,m=o?p.map(c=>({kind:"approval",label:c,decision:um(c),responseDecision:c})):p.map(c=>({kind:"option",label:c,value:c}));return{requestId:e,kind:o?"approval":"question",promptText:k,options:p,...s.length>0?{questions:s}:{},...d!=null?{activeQuestionIndex:d}:{},actions:m,allowsFreeText:!0}}function cd(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function qi(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var im,pd=J(()=>{Sn();im=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function hm(t){let e=t?.trim();return e&&gm.test(e)?e:void 0}function ym(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return Ui;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:Ui}function bn(t){return t instanceof Error?t.message:String(t)}function Ce(t,e){JSON.stringify({component:"CodexHarness",event:t,at:new Date().toISOString(),...e})}function km(t){return{commandKind:t.command==="codex"?"codex":"custom",configuredArgCount:t.args.length,requestTimeoutMs:t.requestTimeoutMs}}function Ge(t){return{hasThreadId:!!t.threadId,hasTurnId:!!t.turnId,hasBackendWorktreePath:!!t.backendWorktreePath,hasBackendWorktreeId:!!t.backendWorktreeId}}function Sm(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 fd(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:Ke(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}function vm(t){if(t===void 0)return md;let e=Ya(t);return e.length>0?e:md}var cm,Ui,md,pm,mm,fm,gm,Sr,gd=J(()=>{za();ur();Sn();hr();pd();cm="1.0",Ui=12e4,md=["--listen","stdio://"],pm="OPENCLAW_CODEX_APP_SERVER_COMMAND",mm="OPENCLAW_CODEX_APP_SERVER_ARGS",fm="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS",gm=/^(?: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}$/;Sr=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[pm]?.trim()||"codex",args:vm(process.env[mm]),requestTimeoutMs:ym(process.env[fm])},r=this.deps.createClient?.(n)??new mr(n.command,n.args,n.requestTimeoutMs),o=new ot,i=hm(e.resumeSessionId);e.resumeSessionId;let s,a=e.backendRef?.worktreePath,d=e.backendRef?.worktreeId,l=e.permissionMode??"default",u=je(this.name,e.model);if(!Gt(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 f,p=0,k="",m=[],c,y=new Map,S=new Set,b=W=>{let I=W?.trim();if(!I)return;let R=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&I!==R&&Za(I)&&(a=I,d=Xa(I))},x=()=>{i&&o.enqueue(Ut({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...d?{worktreeId:d}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async(W,I)=>{let R=W.trim().toLowerCase(),_=vn(I),F=wn(I);if(_.threadId&&i&&_.threadId!==i)return;if(_.threadId&&(i=_.threadId),_.runId&&(s=_.runId),b(F.cwd),(_.threadId||_.runId||F.cwd)&&x(),R==="serverrequest/resolved"){f&&(o.enqueue(it(f.requestId)),f=void 0);return}if(R==="turn/plan/updated"){let B=nd(I);k=B.explanation??k,B.steps.length>0&&(m=B.steps);return}if(R==="item/plan/delta"){let B=td(I);if(B.itemId&&B.delta){let Q=y.get(B.itemId)??"";y.set(B.itemId,`${Q}${B.delta}`)}return}if(R==="item/completed"){let B=rd(I);if(B.text?.trim()){let Q={explanation:k||void 0,steps:m,markdown:B.text.trim()};o.enqueue(lr(Q,!0));return}}let N=ed(R,I);if(N.mode==="delta"&&N.text){N.itemId&&S.add(N.itemId),o.enqueue(yt(N.text));return}N.mode==="snapshot"&&N.text&&(!N.itemId||!S.has(N.itemId))&&o.enqueue(yt(N.text)),(R==="turn/completed"||R==="turn/failed"||R==="turn/cancelled")&&c&&(c.method=W,c.params=I,c.resolve())}),r.setRequestHandler(async(W,I)=>{if(!cd(W))return{};let R=vn(I),_=wn(I);if(R.threadId&&i&&R.threadId!==i)return{};R.threadId&&(i=R.threadId),R.runId&&(s=R.runId),b(_.cwd),(R.threadId||R.runId||_.cwd)&&x();let F=R.requestId??`${i??"codex"}-${Date.now().toString(36)}`,N;try{N=ud(W,F,I)}catch(ln){let un=bn(ln);return`${un}`,{error:un}}let B=W.trim().toLowerCase(),Q=N.options,Y=N.actions??[],pt=await new Promise(ln=>{f={requestId:F,methodLower:B,state:N,options:Q,actions:Y,answers:{...N.answers??{}},resolveResponse:ln},o.enqueue(Ne(N))});return f=void 0,o.enqueue(it(F)),pt});let T=async()=>{Ce("client.initialize.start",{...km(n),hasResumeSessionId:!!e.resumeSessionId}),await r.connect(),await r.request("initialize",{protocolVersion:cm,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},n.requestTimeoutMs),await r.notify("initialized",{}),Ce("client.initialize.done",{hasResumeSessionId:!!e.resumeSessionId})},A=async()=>{let W=qi(l,e.codexApprovalPolicy);if(i){Ce("thread.resume.start",Ge({threadId:i}));let _=await Pn({client:r,methods:["thread/resume"],payloads:ad({threadId:i,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),F=wn(_);i=F.threadId??i,b(F.cwd),x(),Ce("thread.resume.done",{...Ge({threadId:i,backendWorktreePath:a,backendWorktreeId:d})});return}Ce("thread.start.start",{hasCwd:!!e.cwd});let I=await Pn({client:r,methods:["thread/start","thread/new"],payloads:sd({cwd:e.cwd,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),R=wn(I);if(i=R.threadId,!i)throw new Error("Codex App Server did not return a thread id.");b(R.cwd),x(),Ce("thread.start.done",{...Ge({threadId:i,backendWorktreePath:a,backendWorktreeId:d})})},h=async W=>{await A(),Ce("turn.start",{...Ge({threadId:i}),runCounter:p+1,promptChars:W.length,permissionMode:l}),o.enqueue(Kt()),p+=1,k="",m=[],y.clear(),S.clear();let I="",R,_,F=new Promise(N=>{_=N});c={resolve:_};try{let N=qi(l,e.codexApprovalPolicy),B=await Pn({client:r,methods:["turn/start"],payloads:dd({threadId:i,prompt:W,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:l,approvalPolicy:N.approvalPolicy,sandbox:N.sandbox}),timeoutMs:n.requestTimeoutMs}),Q=vn(B);Q.runId&&(s=Q.runId,x()),await F,I=c?.method??"turn/failed",R=c?.params;let Y=od(I,R);Ce("turn.terminal",{...Ge({threadId:i,turnId:s}),terminalMethod:I,outcome:Y}),o.enqueue(Ve({success:Y==="completed",outcome:Y,duration_ms:0,total_cost_usd:0,num_turns:p,result:id(I,R),session_id:i}))}catch(N){Ce("turn.error",{...Ge({threadId:i,turnId:s}),error:bn(N)}),o.enqueue(Ve({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:bn(N),session_id:i??""}))}finally{c=void 0}},w=async W=>{let I=f;if(!I)return!1;let R=W.trim();if(I.methodLower.includes("requestapproval"))return I.resolveResponse({decision:R||"decline"}),!0;let _=I.state.questions??[];if(_.length>0){if(!R)return!1;let F=I.state.activeQuestionIndex??0,N=_[F];if(!N)return!1;I.answers={...I.answers,[N.id]:{answers:[R]}};let B=F+1;if(B<_.length)return I.state=fd(I.state,B,I.answers),I.options=I.state.options,o.enqueue(Ne(I.state)),!0;I.resolveResponse({answers:I.answers})}else I.resolveResponse({text:R});return!0},L=async(W,I={})=>{let R=f;if(!R||I.requestId&&I.requestId!==R.state.requestId)return!1;let _=R.actions[W];if(_?.kind==="approval")return R.resolveResponse({decision:_.responseDecision,..._.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:_.proposedExecpolicyAmendment}:{}}),!0;let F=R.state.questions??[],N=R.state.activeQuestionIndex??0,B=F.length>0?F[N]:void 0;if(I.questionId&&I.questionId!==B?.id)return!1;let Q=B?.options[W];if(B&&Q){R.answers={...R.answers,[B.id]:{answers:[Q.value??Q.label]}};let pt=N+1;return pt<F.length?(R.state=fd(R.state,pt,R.answers),R.options=R.state.options,o.enqueue(Ne(R.state)),!0):(R.resolveResponse({answers:R.answers}),!0)}let Y=R.options[W];return Y?(R.methodLower.includes("requestapproval")?R.resolveResponse({decision:Y}):R.resolveResponse({option:Y,index:W}),!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 T();for await(let W of K){let I=Sm(W).trim();!I||await w(I)||await h(I)}}catch(W){Ce("session.error",{...Ge({threadId:i,turnId:s}),error:bn(W)}),o.enqueue(Ve({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:bn(W),session_id:i??e.resumeSessionId??""}))}finally{Ce("client.close.start",Ge({threadId:i,turnId:s})),await r.close().catch(()=>{}),Ce("client.close.done",Ge({threadId:i,turnId:s})),o.close()}})(),{messages:o.messages(),async setPermissionMode(W){l=W,o.enqueue(Vt(W))},async submitPendingInputOption(W,I){return L(W,I)},async submitPendingInputText(W){return w(W)},async interrupt(){!i||!s||await Pn({client:r,methods:["turn/interrupt"],payloads:ld({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as wm}from"node:child_process";import{constants as Pm,accessSync as bm}from"node:fs";import{createServer as Rm}from"node:net";import{delimiter as Am,dirname as Ki,join as kd,sep as Im}from"node:path";function zt(t){return t instanceof Error?t.message:String(t)}function _m(t){try{return bm(t,Pm.X_OK),!0}catch{return!1}}function $m(t){return t.includes("/")||Im==="\\"&&t.includes("\\")}function Em(t){let e=(t??"").split(Am).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(kd(Ki(Ki(Ki(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function Dm(t,e=process.env.PATH){if($m(t))return t;for(let n of Em(e)){let r=kd(n,t);if(_m(r))return r}return t}function de(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Om(t){if(typeof t=="string")return t;if(!de(t))return String(t);if(typeof t.text=="string")return t.text;let e=de(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function Sd(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 Nm(t){let e=Sd(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function hd(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return Mm.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 Wm(){return new Promise((t,e)=>{let n=Rm();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 vd(t){await new Promise(e=>setTimeout(e,t))}async function vr(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 Ht(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 Lm(t){return t.headers.get("content-type")?.toLowerCase()??""}function Gi(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function Bm(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function Fm(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=Gi(r),s=Bm(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 qm(t,e,n){let r=Sd(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function Um(t,e){if(!de(t))return!1;if(!(e in t))return!0;let n=t[e];return de(n)&&n.type==="idle"}function Km(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function Vm(t){return new Promise((e,n)=>{yd=yd.then(()=>t().then(e,n)).catch(()=>{})})}async function jm(t){return Vm(async()=>{let e=await Wm(),n=process.env[xm]?.trim()||"opencode",r=Dm(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??Qi,1e4),a=t.startupTimeoutMs??Tm,d=wm(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),l=`http://127.0.0.1:${e}`,u="",f="",p,k=(S,b)=>{let x=S+String(b);return x.length>8e3?x.slice(-8e3):x};d.stdout.on("data",S=>{u=k(u,S)}),d.stderr.on("data",S=>{f=k(f,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??""}.`,c=()=>{let S=[u.trim(),f.trim()].filter(Boolean).join(`
4
+ `)}var Sn=J(()=>{});function Ut(t){return{type:"backend_ref",ref:t}}function Kt(t){return{type:"run_started",...t?{runId:t}:{}}}function yt(t){return{type:"text_delta",text:t}}function dr(t,e){return{type:"tool_call",name:t,input:e}}function Ne(t){return{type:"pending_input",state:t}}function it(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function lr(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function Vt(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function Ve(t){return{type:"run_completed",data:t}}var ot,ur=J(()=>{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 pr from"@anthropic-ai/claude-agent-sdk";function Qp(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 Jp(t,e,n){let r=qt(n),o=r.length>0?0:void 0,i=o!=null?r[o]:void 0,s=i?.options.map(d=>d.label)??[],a=i?Ke(i,o,r.length):ar(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 cr,Ga=J(()=>{Sn();ur();cr=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(m,c)=>{if(m!=="AskUserQuestion")return{behavior:"allow"};let y=Jp(a,++s,c);n.enqueue(Ne(y));try{let S=await d(m,c);return n.enqueue(it(y.requestId)),S}catch(S){throw n.enqueue(it(y.requestId)),S}}}:{}};e.resumeSessionId&&(l.resume=e.resumeSessionId,l.forkSession=e.forkSession??!1);let u=e.prompt,f=this.deps.query??pr.query,p=this.deps.startup??pr.startup,k=(async()=>{if(typeof p!="function")return f({prompt:u,options:l});let m=await p({options:l});try{return m.query(u)}catch(c){throw await m.close?.(),c}})();return(async()=>{try{let m=await k;for await(let c of m){let y=c;if(y.type==="system"&&y.subtype==="init"){a=y.session_id??a,n.enqueue(Ut({kind:"claude-code",conversationId:a}));continue}if(y.type==="system"&&y.subtype==="status"&&y.permissionMode){n.enqueue(Vt(y.permissionMode));continue}if(y.type==="assistant"){r||(r=!0,n.enqueue(Kt()));for(let S of y.message?.content??[]){if(S.type==="text"){o+=o?`
6
+ ${S.text}`:S.text,n.enqueue(yt(S.text));continue}S.type==="tool_use"&&((S.name==="ExitPlanMode"||S.name==="set_permission_mode")&&(i=!0),S.name!=="AskUserQuestion"&&n.enqueue(dr(S.name,S.input)))}continue}if(y.type==="result"){let S=o.trim();if(S&&(e.permissionMode==="plan"||i)){let b={explanation:void 0,steps:[],markdown:S};n.enqueue(lr(b,!0))}n.enqueue(Ve({success:y.subtype==="success",duration_ms:y.duration_ms??0,total_cost_usd:y.total_cost_usd??0,num_turns:y.num_turns??0,result:Qp(y),session_id:y.session_id??a})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(m=>{n.enqueue(Ve({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 c=await k;typeof c.setPermissionMode=="function"&&await c.setPermissionMode(m)},async streamInput(m){let c=await k;typeof c.streamInput=="function"&&await c.streamInput(m)},async interrupt(){let m=await k;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 Yp}from"node:child_process";import Zp from"node:readline";function Ha(t){return t instanceof Error?t.message:String(t)}function jt(t,e){JSON.stringify({component:"CodexAppServerRpc",event:t,at:new Date().toISOString(),...e})}function Xp(t,e){return{commandKind:t==="codex"?"codex":"custom",appServerSubcommand:!0,configuredArgCount:e.length}}function em(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function tm(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:Ha(r)}})}}}function Ui(t){return t.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s/?#@]+@/gi,"$1[redacted credential]@").replace(/\b(authorization\s*[:=]\s*)[^\r\n,;}]+/gi,"$1[redacted credential]").replace(/\b(Bearer\s+)[^\s]+/gi,"$1[redacted credential]").replace(/(["'][A-Za-z0-9_.-]*(?:api[_-]?key|token|secret|password|authorization)[A-Za-z0-9_.-]*["']\s*:\s*["'])[^"']+(["'])/gi,"$1[redacted credential]$2").replace(/\b([A-Za-z0-9_.-]*(?:api[_-]?key|token|secret|password|authorization)[A-Za-z0-9_.-]*\s*[:=]\s*)[^\s,}]+/gi,"$1[redacted credential]").replace(/\b(?:sk-[A-Za-z0-9_-]{8,}|gh[opsru]_[A-Za-z0-9_]{8,}|[A-Za-z0-9_-]{32,})\b/g,"[redacted token]").replace(/(?:\/Users|\/home)\/[^\s]+/g,"[redacted path]").replace(/\s+/g," ").slice(-1e3)}var mr,za=J(()=>{mr=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=Yp(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(jt("process.spawn",{...Xp(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,Zp.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=>{jt("process.error",{pid:e.pid,error:Ha(r)})}),e.on("close",(r,o)=>{jt("process.close",{pid:e.pid,code:r,signal:o,pendingRequests:this.pending.size,recentStderr:Ui(this.stderrTail.trim())}),this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){jt("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),jt("request.timeout",{id:o,method:e,timeoutMs:d,pid:this.process?.pid,recentStderr:Ui(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=em(e);n&&await tm(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){this.pending.size>0&&jt("pending.flush",{pendingRequests:this.pending.size,error:e.message,pid:this.process?.pid});for(let[n,r]of this.pending)clearTimeout(r.timer),r.reject(e),this.pending.delete(n)}buildTimeoutErrorMessage(e,n){let r=this.stderrTail.trim(),o=r?`; recent stderr: ${Ui(r)}`:"";return`codex app server timeout after ${n}ms: ${e}${o}`}}});function Qa(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 Ja=J(()=>{});function je(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 nm(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>je("codex",r)?.toLowerCase()===n)}function fr(t,e,n){return t==="codex"?nm(e,n):Qa(e,n)}function Gt(t,e){return t!=="codex"||!e?!0:!e.includes("/")}function gr(t,e,n){if(t!=="codex"||!e||!n||n.length===0)return e;let r=e.toLowerCase(),o=n.find(i=>je("codex",i)?.toLowerCase()===r);return je("codex",o)??e}var hr=J(()=>{Ja()});function rm(t){return t instanceof Error?t.message:String(t)}function Ya(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 yr(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=yr(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=yr(i,e,n+1);if(s)return s}}function wn(t){return{threadId:vn(t).threadId,cwd:yr(t,["cwd","workdir","directory"])}}function Za(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function Xa(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 kr(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 om(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 ed(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:st(e),itemId:kr(e)}:n==="item/completed"?{mode:"snapshot",text:om(e),itemId:kr(e)}:{mode:"ignore",text:""}}function td(t){return{itemId:kr(t),delta:st(t)}}function nd(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 rd(t){let e=j(t);if(!e)return{};let n=j(e.item)??e;return H(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:kr(n),text:H(n,["text"],{trim:!1})??st(n)}}function od(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 id(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 im(t,e){let n=rm(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 am(t){return sm.has(t.trim().toLowerCase())}function dm(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(am(n)&&!dm(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,!im(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function sd(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 ad(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 lm(t){return[{type:"text",text:t}]}function um(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 dd(t){let e={threadId:t.threadId,input:lm(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=um(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function ld(t){return[{threadId:t.threadId,turnId:t.turnId}]}function cm(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 ud(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=qt(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let a=o?sr(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),k=(l?Ke(l,d??0,s.length):ar(s))??(o?yr(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,m=o?p.map(c=>({kind:"approval",label:c,decision:cm(c),responseDecision:c})):p.map(c=>({kind:"option",label:c,value:c}));return{requestId:e,kind:o?"approval":"question",promptText:k,options:p,...s.length>0?{questions:s}:{},...d!=null?{activeQuestionIndex:d}:{},actions:m,allowsFreeText:!0}}function cd(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function Ki(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var sm,pd=J(()=>{Sn();sm=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function ym(t){let e=t?.trim();return e&&hm.test(e)?e:void 0}function km(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return Vi;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:Vi}function bn(t){return t instanceof Error?t.message:String(t)}function Ce(t,e){JSON.stringify({component:"CodexHarness",event:t,at:new Date().toISOString(),...e})}function Sm(t){return{commandKind:t.command==="codex"?"codex":"custom",configuredArgCount:t.args.length,requestTimeoutMs:t.requestTimeoutMs}}function Ge(t){return{hasThreadId:!!t.threadId,hasTurnId:!!t.turnId,hasBackendWorktreePath:!!t.backendWorktreePath,hasBackendWorktreeId:!!t.backendWorktreeId}}function vm(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 fd(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:Ke(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}function wm(t){if(t===void 0)return md;let e=Ya(t);return e.length>0?e:md}var pm,Vi,md,mm,fm,gm,hm,Sr,gd=J(()=>{za();ur();Sn();hr();pd();pm="1.0",Vi=12e4,md=["--listen","stdio://"],mm="OPENCLAW_CODEX_APP_SERVER_COMMAND",fm="OPENCLAW_CODEX_APP_SERVER_ARGS",gm="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS",hm=/^(?: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}$/;Sr=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[mm]?.trim()||"codex",args:wm(process.env[fm]),requestTimeoutMs:km(process.env[gm])},r=this.deps.createClient?.(n)??new mr(n.command,n.args,n.requestTimeoutMs),o=new ot,i=ym(e.resumeSessionId);e.resumeSessionId;let s,a=e.backendRef?.worktreePath,d=e.backendRef?.worktreeId,l=e.permissionMode??"default",u=je(this.name,e.model);if(!Gt(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 f,p=0,k="",m=[],c,y=new Map,S=new Set,b=W=>{let I=W?.trim();if(!I)return;let R=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&I!==R&&Za(I)&&(a=I,d=Xa(I))},x=()=>{i&&o.enqueue(Ut({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...d?{worktreeId:d}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async(W,I)=>{let R=W.trim().toLowerCase(),_=vn(I),F=wn(I);if(_.threadId&&i&&_.threadId!==i)return;if(_.threadId&&(i=_.threadId),_.runId&&(s=_.runId),b(F.cwd),(_.threadId||_.runId||F.cwd)&&x(),R==="serverrequest/resolved"){f&&(o.enqueue(it(f.requestId)),f=void 0);return}if(R==="turn/plan/updated"){let B=nd(I);k=B.explanation??k,B.steps.length>0&&(m=B.steps);return}if(R==="item/plan/delta"){let B=td(I);if(B.itemId&&B.delta){let Q=y.get(B.itemId)??"";y.set(B.itemId,`${Q}${B.delta}`)}return}if(R==="item/completed"){let B=rd(I);if(B.text?.trim()){let Q={explanation:k||void 0,steps:m,markdown:B.text.trim()};o.enqueue(lr(Q,!0));return}}let N=ed(R,I);if(N.mode==="delta"&&N.text){N.itemId&&S.add(N.itemId),o.enqueue(yt(N.text));return}N.mode==="snapshot"&&N.text&&(!N.itemId||!S.has(N.itemId))&&o.enqueue(yt(N.text)),(R==="turn/completed"||R==="turn/failed"||R==="turn/cancelled")&&c&&(c.method=W,c.params=I,c.resolve())}),r.setRequestHandler(async(W,I)=>{if(!cd(W))return{};let R=vn(I),_=wn(I);if(R.threadId&&i&&R.threadId!==i)return{};R.threadId&&(i=R.threadId),R.runId&&(s=R.runId),b(_.cwd),(R.threadId||R.runId||_.cwd)&&x();let F=R.requestId??`${i??"codex"}-${Date.now().toString(36)}`,N;try{N=ud(W,F,I)}catch(ln){let un=bn(ln);return`${un}`,{error:un}}let B=W.trim().toLowerCase(),Q=N.options,Y=N.actions??[],pt=await new Promise(ln=>{f={requestId:F,methodLower:B,state:N,options:Q,actions:Y,answers:{...N.answers??{}},resolveResponse:ln},o.enqueue(Ne(N))});return f=void 0,o.enqueue(it(F)),pt});let T=async()=>{Ce("client.initialize.start",{...Sm(n),hasResumeSessionId:!!e.resumeSessionId}),await r.connect(),await r.request("initialize",{protocolVersion:pm,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},n.requestTimeoutMs),await r.notify("initialized",{}),Ce("client.initialize.done",{hasResumeSessionId:!!e.resumeSessionId})},A=async()=>{let W=Ki(l,e.codexApprovalPolicy);if(i){Ce("thread.resume.start",Ge({threadId:i}));let _=await Pn({client:r,methods:["thread/resume"],payloads:ad({threadId:i,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),F=wn(_);i=F.threadId??i,b(F.cwd),x(),Ce("thread.resume.done",{...Ge({threadId:i,backendWorktreePath:a,backendWorktreeId:d})});return}Ce("thread.start.start",{hasCwd:!!e.cwd});let I=await Pn({client:r,methods:["thread/start","thread/new"],payloads:sd({cwd:e.cwd,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),R=wn(I);if(i=R.threadId,!i)throw new Error("Codex App Server did not return a thread id.");b(R.cwd),x(),Ce("thread.start.done",{...Ge({threadId:i,backendWorktreePath:a,backendWorktreeId:d})})},h=async W=>{await A(),Ce("turn.start",{...Ge({threadId:i}),runCounter:p+1,promptChars:W.length,permissionMode:l}),o.enqueue(Kt()),p+=1,k="",m=[],y.clear(),S.clear();let I="",R,_,F=new Promise(N=>{_=N});c={resolve:_};try{let N=Ki(l,e.codexApprovalPolicy),B=await Pn({client:r,methods:["turn/start"],payloads:dd({threadId:i,prompt:W,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:l,approvalPolicy:N.approvalPolicy,sandbox:N.sandbox}),timeoutMs:n.requestTimeoutMs}),Q=vn(B);Q.runId&&(s=Q.runId,x()),await F,I=c?.method??"turn/failed",R=c?.params;let Y=od(I,R);Ce("turn.terminal",{...Ge({threadId:i,turnId:s}),terminalMethod:I,outcome:Y}),o.enqueue(Ve({success:Y==="completed",outcome:Y,duration_ms:0,total_cost_usd:0,num_turns:p,result:id(I,R),session_id:i}))}catch(N){Ce("turn.error",{...Ge({threadId:i,turnId:s}),error:bn(N)}),o.enqueue(Ve({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:bn(N),session_id:i??""}))}finally{c=void 0}},w=async W=>{let I=f;if(!I)return!1;let R=W.trim();if(I.methodLower.includes("requestapproval"))return I.resolveResponse({decision:R||"decline"}),!0;let _=I.state.questions??[];if(_.length>0){if(!R)return!1;let F=I.state.activeQuestionIndex??0,N=_[F];if(!N)return!1;I.answers={...I.answers,[N.id]:{answers:[R]}};let B=F+1;if(B<_.length)return I.state=fd(I.state,B,I.answers),I.options=I.state.options,o.enqueue(Ne(I.state)),!0;I.resolveResponse({answers:I.answers})}else I.resolveResponse({text:R});return!0},L=async(W,I={})=>{let R=f;if(!R||I.requestId&&I.requestId!==R.state.requestId)return!1;let _=R.actions[W];if(_?.kind==="approval")return R.resolveResponse({decision:_.responseDecision,..._.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:_.proposedExecpolicyAmendment}:{}}),!0;let F=R.state.questions??[],N=R.state.activeQuestionIndex??0,B=F.length>0?F[N]:void 0;if(I.questionId&&I.questionId!==B?.id)return!1;let Q=B?.options[W];if(B&&Q){R.answers={...R.answers,[B.id]:{answers:[Q.value??Q.label]}};let pt=N+1;return pt<F.length?(R.state=fd(R.state,pt,R.answers),R.options=R.state.options,o.enqueue(Ne(R.state)),!0):(R.resolveResponse({answers:R.answers}),!0)}let Y=R.options[W];return Y?(R.methodLower.includes("requestapproval")?R.resolveResponse({decision:Y}):R.resolveResponse({option:Y,index:W}),!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 T();for await(let W of K){let I=vm(W).trim();!I||await w(I)||await h(I)}}catch(W){Ce("session.error",{...Ge({threadId:i,turnId:s}),error:bn(W)}),o.enqueue(Ve({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:bn(W),session_id:i??e.resumeSessionId??""}))}finally{Ce("client.close.start",Ge({threadId:i,turnId:s})),await r.close().catch(()=>{}),Ce("client.close.done",Ge({threadId:i,turnId:s})),o.close()}})(),{messages:o.messages(),async setPermissionMode(W){l=W,o.enqueue(Vt(W))},async submitPendingInputOption(W,I){return L(W,I)},async submitPendingInputText(W){return w(W)},async interrupt(){!i||!s||await Pn({client:r,methods:["turn/interrupt"],payloads:ld({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as Pm}from"node:child_process";import{constants as bm,accessSync as Rm}from"node:fs";import{createServer as Am}from"node:net";import{delimiter as Im,dirname as ji,join as kd,sep as xm}from"node:path";function zt(t){return t instanceof Error?t.message:String(t)}function $m(t){try{return Rm(t,bm.X_OK),!0}catch{return!1}}function Em(t){return t.includes("/")||xm==="\\"&&t.includes("\\")}function Dm(t){let e=(t??"").split(Im).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(kd(ji(ji(ji(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function Om(t,e=process.env.PATH){if(Em(t))return t;for(let n of Dm(e)){let r=kd(n,t);if($m(r))return r}return t}function de(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Nm(t){if(typeof t=="string")return t;if(!de(t))return String(t);if(typeof t.text=="string")return t.text;let e=de(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function Sd(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 Wm(t){let e=Sd(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function hd(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return _m.map(r=>({permission:r,pattern:"*",action:n}))}function Gi(){let t=process.env.OPENCODE_SERVER_PASSWORD;if(!t)return{};let e=process.env.OPENCODE_SERVER_USERNAME||"opencode";return{Authorization:`Basic ${Buffer.from(`${e}:${t}`).toString("base64")}`}}async function Lm(){return new Promise((t,e)=>{let n=Am();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 vd(t){await new Promise(e=>setTimeout(e,t))}async function vr(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 Ht(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 Bm(t){return t.headers.get("content-type")?.toLowerCase()??""}function zi(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function Fm(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function qm(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=zi(r),s=Fm(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 Um(t,e,n){let r=Sd(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function Km(t,e){if(!de(t))return!1;if(!(e in t))return!0;let n=t[e];return de(n)&&n.type==="idle"}function Vm(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function jm(t){return new Promise((e,n)=>{yd=yd.then(()=>t().then(e,n)).catch(()=>{})})}async function Gm(t){return jm(async()=>{let e=await Lm(),n=process.env[Tm]?.trim()||"opencode",r=Om(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??Yi,1e4),a=t.startupTimeoutMs??Cm,d=Pm(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),l=`http://127.0.0.1:${e}`,u="",f="",p,k=(S,b)=>{let x=S+String(b);return x.length>8e3?x.slice(-8e3):x};d.stdout.on("data",S=>{u=k(u,S)}),d.stderr.on("data",S=>{f=k(f,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??""}.`,c=()=>{let S=[u.trim(),f.trim()].filter(Boolean).join(`
8
8
  `).trim();return`${m()}${S?` Output:
9
- ${S}`:""}`},y=()=>{Ht(d)};if(t.signal?.aborted)throw await Ht(d),new Error(`OpenCode server startup aborted before readiness.${c()}`);t.signal?.addEventListener("abort",y,{once:!0});try{let S=Date.now();for(;Date.now()-S<a;){if(t.signal?.aborted)throw await Ht(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 Hm({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 Ht(d)}}}catch{if(t.signal?.aborted)throw await Ht(d),new Error(`OpenCode server startup aborted before readiness.${c()}`)}await vd(100)}throw await Ht(d),new Error(`Timed out waiting for OpenCode server readiness.${c()}`)}finally{t.signal?.removeEventListener("abort",y)}})}async function Gm(t){for(let e=1;;e+=1)try{return await jm(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(zt(n)))throw n}}async function Hm(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await vr(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 zm(t){let e=de(t)&&de(t.payload)?t.payload:t;return de(e)?e.type==="sync"?{type:typeof e.name=="string"?e.name.replace(/\.\d+$/,""):void 0,properties:de(e.data)?e.data:{}}:{type:typeof e.type=="string"?e.type:void 0,properties:de(e.properties)?e.properties:e}:{properties:{}}}function Qm(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function Jm(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 Ym(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=qt(t),o=sr(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?Ke(a,s??0,i.length):n,options:d,...i.length>0?{questions:i}:{},...s!=null?{activeQuestionIndex:s}:{},allowsFreeText:!0}}function Zm(t,e,n){let r=t.questions??[],o=r[e],i=o?.options.map(s=>s.label)??[];return{...t,promptText:o?Ke(o,e,r.length):t.promptText,options:i,activeQuestionIndex:e,answers:n}}function Xm(t,e){return t.length===1?e[t[0].id]?.answers.join(", ")??"":t.map((n,r)=>{let o=e[n.id]?.answers.join(", ")??"";return`Q${r+1}: ${n.question}
9
+ ${S}`:""}`},y=()=>{Ht(d)};if(t.signal?.aborted)throw await Ht(d),new Error(`OpenCode server startup aborted before readiness.${c()}`);t.signal?.addEventListener("abort",y,{once:!0});try{let S=Date.now();for(;Date.now()-S<a;){if(t.signal?.aborted)throw await Ht(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 zm({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 Ht(d)}}}catch{if(t.signal?.aborted)throw await Ht(d),new Error(`OpenCode server startup aborted before readiness.${c()}`)}await vd(100)}throw await Ht(d),new Error(`Timed out waiting for OpenCode server readiness.${c()}`)}finally{t.signal?.removeEventListener("abort",y)}})}async function Hm(t){for(let e=1;;e+=1)try{return await Gm(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(zt(n)))throw n}}async function zm(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await vr(t.fetchImpl(`${t.baseUrl}/api/health`,{headers:Gi(),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 Qm(t){let e=de(t)&&de(t.payload)?t.payload:t;return de(e)?e.type==="sync"?{type:typeof e.name=="string"?e.name.replace(/\.\d+$/,""):void 0,properties:de(e.data)?e.data:{}}:{type:typeof e.type=="string"?e.type:void 0,properties:de(e.properties)?e.properties:e}:{properties:{}}}function Jm(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function Ym(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 Zm(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=qt(t),o=sr(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?Ke(a,s??0,i.length):n,options:d,...i.length>0?{questions:i}:{},...s!=null?{activeQuestionIndex:s}:{},allowsFreeText:!0}}function Xm(t,e,n){let r=t.questions??[],o=r[e],i=o?.options.map(s=>s.label)??[];return{...t,promptText:o?Ke(o,e,r.length):t.promptText,options:i,activeQuestionIndex:e,answers:n}}function ef(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 ef(t){return zi(t).result}function zi(t){let e=Array.isArray(t)?t:de(t)&&Array.isArray(t.messages)?t.messages:de(t)&&Array.isArray(t.items)?t.items:[],n=[];for(let r of e){let o=de(r)&&de(r.info)?r.info:r;if(!de(o)||(typeof o.role=="string"?o.role:o.type)!=="assistant")continue;let s=Array.isArray(o.content)?o.content:[],a=de(r)&&Array.isArray(r.parts)?r.parts:[];for(let d of[...s,...a])de(d)&&d.type==="text"&&typeof d.text=="string"&&n.push(d.text)}return{count:n.length,result:n.at(-1)}}var xm,Tm,Qi,Cm,Mm,ji,yd,Hi,wr,wd=J(()=>{Sn();ur();xm="OPENCLAW_OPENCODE_COMMAND",Tm=15e3,Qi=6e4,Cm=15*6e4,Mm=["edit","bash","task","todowrite","external_directory"];ji=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};yd=Promise.resolve();Hi=class{constructor(e,n,r=Qi){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.`,f=()=>{s=!0,i.abort()};o.signal?.aborted?(s=!0,i.abort()):o.signal?.addEventListener("abort",f,{once:!0});try{let p=await vr(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 c=await vr(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}}).catch(()=>"");throw new ji(e,n,p.status,Gi(c))}if(p.status===204)return;let k=await vr(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!k)return;let m=Lm(p);if(!m.includes("application/json")&&!m.includes("+json"))throw new Error(Fm(e,n,m,k));try{return JSON.parse(k)}catch(c){let y=Gi(k);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${zt(c)}${y?`: ${y}`:""}`)}}catch(p){if(i.signal.aborted){if(a)throw new Error(`OpenCode ${e} ${n} timed out after ${d}ms.`);if(s)throw new Error(`OpenCode ${e} ${n} was aborted.`)}throw p}finally{o.signal?.removeEventListener("abort",f)}}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(f=>f.startsWith("data:")).map(f=>f.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 f=/\r?\n\r?\n/.exec(s);for(;f;){let p=s.slice(0,f.index);s=s.slice(f.index+f[0].length),await a(p),f=/\r?\n\r?\n/.exec(s)}}let d=s.trim();d&&await a(d)}};wr=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,f=!e.resumeSessionId,p=!1,k=!1,m=new AbortController,c,y=!1,S=!1,b=!1,x=!1,T=!1,A=!1,h,w=new Set,L=M=>x?!1:(x=!0,n.enqueue(Ve(M)),!0),K=(M,C,E)=>L({success:M,outcome:C,duration_ms:0,total_cost_usd:0,num_turns:d,result:E,session_id:a??""}),W=()=>{a&&h!==a&&(h=a,n.enqueue(Ut({kind:"opencode-server",conversationId:a})))},I=M=>{M&&w.has(M)||(M&&w.add(M),n.enqueue(it(M)),M&&u?.requestId===M&&(u=void 0))},R=async()=>{if(i)return i;s??=(async()=>{let M=await(this.deps.createServer??Gm)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(T||e.abortController?.signal.aborted)throw await M.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=M,i=new Hi(M.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(M){throw s=void 0,M}},_=async(M,C)=>{!i||!a||await i.request("POST",`/permission/${encodeURIComponent(M)}/reply`,{reply:C})},F=async(M,C)=>{!i||!a||await i.request("POST",`/question/${encodeURIComponent(M)}/reply`,{answers:[[C]]})},N=async M=>{let C=zm(M),E=Qm(C.properties);if(!(E&&E!==a)){if((C.type==="session.next.text.delta"||C.type==="message.part.delta")&&C.properties.field!=="reasoning"&&typeof C.properties.delta=="string"){n.enqueue(yt(C.properties.delta));return}if(C.type==="session.next.tool.called"||C.type==="message.part.updated"){let q=de(C.properties.part)?C.properties.part:void 0;if(C.type==="message.part.updated"&&q?.type!=="tool"){n.enqueue({type:"activity"});return}let oe=typeof C.properties.tool=="string"?C.properties.tool:typeof q?.tool=="string"?q.tool:"tool";n.enqueue(dr(oe,C.properties.input));return}if(C.type==="session.next.step.failed"||C.type==="session.error"){let q=de(C.properties.error)&&typeof C.properties.error.message=="string"?C.properties.error.message:`${C.type} failed`;S&&!b&&(c?.abort(),K(!1,"failed",q));return}if(C.type==="permission.asked"){if(l==="bypassPermissions"){let oe=typeof C.properties.id=="string"?C.properties.id:void 0;oe&&(await _(oe,"once").catch(()=>{}),I(oe));return}let q=Jm(C.properties);u={requestId:q.requestId,kind:"approval",options:q.options,actions:q.actions??[],state:q},n.enqueue(Ne(q));return}if(C.type==="permission.replied"){let q=typeof C.properties.requestID=="string"?C.properties.requestID:void 0;I(q);return}if(C.type==="question.asked"){let q=Ym(C.properties);u={requestId:q.requestId,kind:"question",options:q.options,actions:[],state:q},n.enqueue(Ne(q));return}if(C.type==="question.replied"||C.type==="question.rejected"){let q=typeof C.properties.requestID=="string"?C.properties.requestID:void 0;I(q);return}(C.type?.startsWith("session.next.")||C.type?.startsWith("message.")||C.type==="session.status"||C.type==="session.idle")&&(Km(C)&&(A=!0),n.enqueue({type:"activity"}))}},B=()=>{y||!i||(y=!0,i.streamEvents(N,m.signal).catch(M=>{!m.signal.aborted&&S&&!b&&(c?.abort(),K(!1,"failed",zt(M)))}).finally(()=>{y=!1}))},Q=async(M,C)=>await M.request("GET",`/session/${encodeURIComponent(C)}/message`),Y=async(M,C,E,q,oe)=>{await M.request("POST",`/session/${encodeURIComponent(C)}/prompt_async`,qm(E,e.model,q),{signal:oe})},pt=async(M,C,E,q)=>{let oe=Date.now(),Ee=!1,we=E,Ye,_t=0,Ze,ha=this.deps.turnTimeoutMs??Cm;for(;;){if(q.aborted)throw new Error("wait aborted");let Hc=await Q(M,C).catch(()=>{}),Xe=zi(Hc),ya=Xe.count>E&&!!Xe.result;ya&&Xe.count===we&&Xe.result===Ye?_t+=1:(_t=ya?1:0,we=Xe.count,Ye=Xe.result);let Si=!1;try{let cn=await M.request("GET","/session/status",void 0,{signal:q,timeoutMs:Math.min(this.deps.requestTimeoutMs??Qi,1e4)});Si=Um(cn,C),Ze=void 0,Si||(Ee=!0)}catch(cn){if(q.aborted)throw new Error("wait aborted");Ze=zt(cn)}if(Si&&(Ee||Xe.count>E)||A&&Xe.count>E||_t>=2&&Ze)return;if(Date.now()-oe>ha){let cn=Ze?` Last status error: ${Ze}`:"";throw new Error(`Timed out waiting for OpenCode session ${C} to become idle after ${ha}ms.${cn}`)}await vd(250)}},ln=async()=>{let M=await R();if(a){if(e.forkSession&&!p){let q=await M.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,f=!0}else f||(await Q(M,a),f=!0);return W(),B(),a}let C=Nm(e.model),E=await M.request("POST","/session",{...C?{model:C}:{},metadata:{client:"openclaw-code-agent"},permission:hd(l)});if(!E.id)throw new Error("OpenCode did not return a session id.");return a=E.id,f=!0,W(),B(),a},un=async(M,C,E=M?"completed":"failed")=>{let q=C;if(M&&i&&a){let oe=await Q(i,a).catch(()=>{});q=q??ef(oe)}K(M,E,q)},jc=async M=>{S=!0,b=!1,x=!1,A=!1;try{let C=await R();if(T)return;let E=await ln();if(T)return;n.enqueue(Kt()),d+=1;let q=k?void 0:e.systemPrompt,oe=await Q(C,E).catch(()=>{}),Ee=zi(oe).count,we=new AbortController;c=we,await Y(C,E,M,q,we.signal),k=!0,await pt(C,E,Ee,we.signal),c=void 0,b=!0,await un(!0)}catch(C){c=void 0,await un(!1,zt(C))}finally{S=!1,b=!1}},ki=async(M,C={})=>{let E=u;if(!E||E.kind!=="question"||C.requestId&&C.requestId!==E.requestId)return!1;let q=M.trim();if(!q)return!1;let oe=E.state?.questions??[];if(oe.length>0){let Ee=E.state?.activeQuestionIndex??0,we=oe[Ee];if(!we||C.questionId&&C.questionId!==we.id)return!1;E.answers={...E.answers,[we.id]:{answers:[q]}};let Ye=Ee+1;return Ye<oe.length?(E.state=Zm(E.state,Ye,E.answers),E.options=E.state.options,n.enqueue(Ne(E.state)),!0):(await F(E.requestId,Xm(oe,E.answers)),I(E.requestId),!0)}return await F(E.requestId,q),I(E.requestId),!0},Gc=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{for await(let M of Gc){if(T)break;let C=Om(M).trim();if(C){if(u?.kind==="question"){await ki(C);continue}if(await jc(C),T)break}}}catch(M){T||(S||(x=!1),K(!1,"failed",zt(M)))}finally{m.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(M){a&&await(await R()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:hd(M)}),l=M,n.enqueue(Vt(M))},async submitPendingInputOption(M,C={}){let E=u;if(!E||C.requestId&&C.requestId!==E.requestId)return!1;if(E.kind==="approval"){let _t=E.actions[M],Ze=_t?.kind==="approval"?_t.responseDecision:void 0;return Ze?(await _(E.requestId,Ze),I(E.requestId),!0):!1}let q=E.state?.questions??[],oe=E.state?.activeQuestionIndex??0,Ee=q[oe];if(C.questionId&&C.questionId!==Ee?.id)return!1;let we=Ee?.options[M],Ye=we?.value??we?.label??E.options[M];return Ye?await ki(Ye,C):!1},async submitPendingInputText(M){return await ki(M)},async interrupt(){if(T=!0,m.abort(),c?.abort(),S||(x=!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 Yi(t){Ji.set(t.name,t)}function Rn(t){let e=Ji.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...Ji.keys()].join(", ")}`);return e}function Pd(){return Rn(me())}var Ji,Zi=J(()=>{Ga();gd();wd();ae();Ji=new Map;Yi(new cr);Yi(new Sr);Yi(new wr)});function O(t){return t.backendRef?.conversationId??t.harnessSessionId}function G(t){return t.id??t.sessionId??t.name??O(t)??t.harnessSessionId}function tf(t){return t.harnessSessionId}function fe(t){let e=[G(t),O(t),tf(t)].filter(n=>!!n);return[...new Set(e)]}function Xi(t){return t.harnessName??t.persistedHarness??me()}function An(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return Rn(Xi(t)).capabilities.worktrees}catch{return"plugin-managed"}}function es(t){return t==="native-execution"}function Pr(t){return t==="native-restore"}function nf(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function le(t){let e=An(t);return(es(e)||Pr(e))&&nf(t)}var ne=J(()=>{ae();Zi()});import{execFileSync as ie}from"child_process";import*as Br from"fs";import{tmpdir as Nf}from"os";import{dirname as Vd,join as Wf}from"path";function Lf(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 Fr(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(D.worktreeDir)return D.worktreeDir;if(t){let e=Lf(t);if(e)return Wf(e,".worktrees")}return Nf()}function jd(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100).replace(/[-.]+$/,"")||"session"}function qr(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")?Vd(e):void 0}catch{return}}function Bf(){if(Wr!==void 0)return Wr;try{return ie("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Wr=!0,!0}catch{return Wr=!1,!1}}function he(){if(Lr!==void 0)return Lr;try{return ie("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Lr=!0,!0}catch{return Lr=!1,!1}}function Ur(t){if(!Bf())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 Gd(t){try{let e=qf(t);if(!e)return`${Fr(t)}`,!0;let n=Br.statfsSync(e),r=n.bavail*n.bsize;return Uf(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function vt(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 Kr(t,e,n="origin"){let r=`refs/remotes/${n}/${e}`;try{return ie("git",["-C",t,"fetch",n,`+${e}:${r}`],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ie("git",["-C",t,"rev-parse","--verify",r],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r}catch{return}}function Ff(t){let e=t;for(;;){if(Br.existsSync(e))return e;let n=Vd(e);if(n===e)return;e=n}}function qf(t){return Ff(Fr(t))}function Uf(t){return t>=104857600}function Le(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 ke(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 xn(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 Hd(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 Se(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 Vr(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 Pe(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 Tn(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 Wr,Lr,Jt=J(()=>{ae()});import{execFileSync as Yt}from"child_process";import{randomBytes as Kf}from"crypto";import{appendFileSync as Vf,existsSync as ss,mkdirSync as zd,readFileSync as jf,rmSync as is}from"fs";import{relative as Gf,sep as Qd}from"path";function Hf(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function zf(t){try{return Yt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Qf(t){return t===0?"":`-${t}-${Kf(8).toString("hex")}`}function Jf(t,e){let n=zf(t);if(!n)return;let r=Gf(n,e);if(!r||r.startsWith("..")||r.includes(`..${Qd}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(Qd).join("/").replace(/\/$/,"")}/`;try{let s=ss(o)?jf(o,"utf-8"):"";s.split(/\r?\n/).map(d=>d.trim()).some(d=>d===i||d===`/${i}`)||Vf(o,`${s.endsWith(`
12
+ `)}function tf(t){return Ji(t).result}function Ji(t){let e=Array.isArray(t)?t:de(t)&&Array.isArray(t.messages)?t.messages:de(t)&&Array.isArray(t.items)?t.items:[],n=[];for(let r of e){let o=de(r)&&de(r.info)?r.info:r;if(!de(o)||(typeof o.role=="string"?o.role:o.type)!=="assistant")continue;let s=Array.isArray(o.content)?o.content:[],a=de(r)&&Array.isArray(r.parts)?r.parts:[];for(let d of[...s,...a])de(d)&&d.type==="text"&&typeof d.text=="string"&&n.push(d.text)}return{count:n.length,result:n.at(-1)}}var Tm,Cm,Yi,Mm,_m,Hi,yd,Qi,wr,wd=J(()=>{Sn();ur();Tm="OPENCLAW_OPENCODE_COMMAND",Cm=15e3,Yi=6e4,Mm=15*6e4,_m=["edit","bash","task","todowrite","external_directory"];Hi=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};yd=Promise.resolve();Qi=class{constructor(e,n,r=Yi){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.`,f=()=>{s=!0,i.abort()};o.signal?.aborted?(s=!0,i.abort()):o.signal?.addEventListener("abort",f,{once:!0});try{let p=await vr(this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:{...Gi(),...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 vr(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}}).catch(()=>"");throw new Hi(e,n,p.status,zi(c))}if(p.status===204)return;let k=await vr(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!k)return;let m=Bm(p);if(!m.includes("application/json")&&!m.includes("+json"))throw new Error(qm(e,n,m,k));try{return JSON.parse(k)}catch(c){let y=zi(k);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${zt(c)}${y?`: ${y}`:""}`)}}catch(p){if(i.signal.aborted){if(a)throw new Error(`OpenCode ${e} ${n} timed out after ${d}ms.`);if(s)throw new Error(`OpenCode ${e} ${n} was aborted.`)}throw p}finally{o.signal?.removeEventListener("abort",f)}}async streamEvents(e,n){let r=await this.fetchImpl(`${this.baseUrl}/event`,{headers:Gi(),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(f=>f.startsWith("data:")).map(f=>f.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 f=/\r?\n\r?\n/.exec(s);for(;f;){let p=s.slice(0,f.index);s=s.slice(f.index+f[0].length),await a(p),f=/\r?\n\r?\n/.exec(s)}}let d=s.trim();d&&await a(d)}};wr=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,f=!e.resumeSessionId,p=!1,k=!1,m=new AbortController,c,y=!1,S=!1,b=!1,x=!1,T=!1,A=!1,h,w=new Set,L=M=>x?!1:(x=!0,n.enqueue(Ve(M)),!0),K=(M,C,E)=>L({success:M,outcome:C,duration_ms:0,total_cost_usd:0,num_turns:d,result:E,session_id:a??""}),W=()=>{a&&h!==a&&(h=a,n.enqueue(Ut({kind:"opencode-server",conversationId:a})))},I=M=>{M&&w.has(M)||(M&&w.add(M),n.enqueue(it(M)),M&&u?.requestId===M&&(u=void 0))},R=async()=>{if(i)return i;s??=(async()=>{let M=await(this.deps.createServer??Hm)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(T||e.abortController?.signal.aborted)throw await M.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=M,i=new Qi(M.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(M){throw s=void 0,M}},_=async(M,C)=>{!i||!a||await i.request("POST",`/permission/${encodeURIComponent(M)}/reply`,{reply:C})},F=async(M,C)=>{!i||!a||await i.request("POST",`/question/${encodeURIComponent(M)}/reply`,{answers:[[C]]})},N=async M=>{let C=Qm(M),E=Jm(C.properties);if(!(E&&E!==a)){if((C.type==="session.next.text.delta"||C.type==="message.part.delta")&&C.properties.field!=="reasoning"&&typeof C.properties.delta=="string"){n.enqueue(yt(C.properties.delta));return}if(C.type==="session.next.tool.called"||C.type==="message.part.updated"){let q=de(C.properties.part)?C.properties.part:void 0;if(C.type==="message.part.updated"&&q?.type!=="tool"){n.enqueue({type:"activity"});return}let oe=typeof C.properties.tool=="string"?C.properties.tool:typeof q?.tool=="string"?q.tool:"tool";n.enqueue(dr(oe,C.properties.input));return}if(C.type==="session.next.step.failed"||C.type==="session.error"){let q=de(C.properties.error)&&typeof C.properties.error.message=="string"?C.properties.error.message:`${C.type} failed`;S&&!b&&(c?.abort(),K(!1,"failed",q));return}if(C.type==="permission.asked"){if(l==="bypassPermissions"){let oe=typeof C.properties.id=="string"?C.properties.id:void 0;oe&&(await _(oe,"once").catch(()=>{}),I(oe));return}let q=Ym(C.properties);u={requestId:q.requestId,kind:"approval",options:q.options,actions:q.actions??[],state:q},n.enqueue(Ne(q));return}if(C.type==="permission.replied"){let q=typeof C.properties.requestID=="string"?C.properties.requestID:void 0;I(q);return}if(C.type==="question.asked"){let q=Zm(C.properties);u={requestId:q.requestId,kind:"question",options:q.options,actions:[],state:q},n.enqueue(Ne(q));return}if(C.type==="question.replied"||C.type==="question.rejected"){let q=typeof C.properties.requestID=="string"?C.properties.requestID:void 0;I(q);return}(C.type?.startsWith("session.next.")||C.type?.startsWith("message.")||C.type==="session.status"||C.type==="session.idle")&&(Vm(C)&&(A=!0),n.enqueue({type:"activity"}))}},B=()=>{y||!i||(y=!0,i.streamEvents(N,m.signal).catch(M=>{!m.signal.aborted&&S&&!b&&(c?.abort(),K(!1,"failed",zt(M)))}).finally(()=>{y=!1}))},Q=async(M,C)=>await M.request("GET",`/session/${encodeURIComponent(C)}/message`),Y=async(M,C,E,q,oe)=>{await M.request("POST",`/session/${encodeURIComponent(C)}/prompt_async`,Um(E,e.model,q),{signal:oe})},pt=async(M,C,E,q)=>{let oe=Date.now(),Ee=!1,we=E,Ye,_t=0,Ze,ka=this.deps.turnTimeoutMs??Mm;for(;;){if(q.aborted)throw new Error("wait aborted");let Hc=await Q(M,C).catch(()=>{}),Xe=Ji(Hc),Sa=Xe.count>E&&!!Xe.result;Sa&&Xe.count===we&&Xe.result===Ye?_t+=1:(_t=Sa?1:0,we=Xe.count,Ye=Xe.result);let Si=!1;try{let cn=await M.request("GET","/session/status",void 0,{signal:q,timeoutMs:Math.min(this.deps.requestTimeoutMs??Yi,1e4)});Si=Km(cn,C),Ze=void 0,Si||(Ee=!0)}catch(cn){if(q.aborted)throw new Error("wait aborted");Ze=zt(cn)}if(Si&&(Ee||Xe.count>E)||A&&Xe.count>E||_t>=2&&Ze)return;if(Date.now()-oe>ka){let cn=Ze?` Last status error: ${Ze}`:"";throw new Error(`Timed out waiting for OpenCode session ${C} to become idle after ${ka}ms.${cn}`)}await vd(250)}},ln=async()=>{let M=await R();if(a){if(e.forkSession&&!p){let q=await M.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,f=!0}else f||(await Q(M,a),f=!0);return W(),B(),a}let C=Wm(e.model),E=await M.request("POST","/session",{...C?{model:C}:{},metadata:{client:"openclaw-code-agent"},permission:hd(l)});if(!E.id)throw new Error("OpenCode did not return a session id.");return a=E.id,f=!0,W(),B(),a},un=async(M,C,E=M?"completed":"failed")=>{let q=C;if(M&&i&&a){let oe=await Q(i,a).catch(()=>{});q=q??tf(oe)}K(M,E,q)},jc=async M=>{S=!0,b=!1,x=!1,A=!1;try{let C=await R();if(T)return;let E=await ln();if(T)return;n.enqueue(Kt()),d+=1;let q=k?void 0:e.systemPrompt,oe=await Q(C,E).catch(()=>{}),Ee=Ji(oe).count,we=new AbortController;c=we,await Y(C,E,M,q,we.signal),k=!0,await pt(C,E,Ee,we.signal),c=void 0,b=!0,await un(!0)}catch(C){c=void 0,await un(!1,zt(C))}finally{S=!1,b=!1}},ki=async(M,C={})=>{let E=u;if(!E||E.kind!=="question"||C.requestId&&C.requestId!==E.requestId)return!1;let q=M.trim();if(!q)return!1;let oe=E.state?.questions??[];if(oe.length>0){let Ee=E.state?.activeQuestionIndex??0,we=oe[Ee];if(!we||C.questionId&&C.questionId!==we.id)return!1;E.answers={...E.answers,[we.id]:{answers:[q]}};let Ye=Ee+1;return Ye<oe.length?(E.state=Xm(E.state,Ye,E.answers),E.options=E.state.options,n.enqueue(Ne(E.state)),!0):(await F(E.requestId,ef(oe,E.answers)),I(E.requestId),!0)}return await F(E.requestId,q),I(E.requestId),!0},Gc=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{for await(let M of Gc){if(T)break;let C=Nm(M).trim();if(C){if(u?.kind==="question"){await ki(C);continue}if(await jc(C),T)break}}}catch(M){T||(S||(x=!1),K(!1,"failed",zt(M)))}finally{m.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(M){a&&await(await R()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:hd(M)}),l=M,n.enqueue(Vt(M))},async submitPendingInputOption(M,C={}){let E=u;if(!E||C.requestId&&C.requestId!==E.requestId)return!1;if(E.kind==="approval"){let _t=E.actions[M],Ze=_t?.kind==="approval"?_t.responseDecision:void 0;return Ze?(await _(E.requestId,Ze),I(E.requestId),!0):!1}let q=E.state?.questions??[],oe=E.state?.activeQuestionIndex??0,Ee=q[oe];if(C.questionId&&C.questionId!==Ee?.id)return!1;let we=Ee?.options[M],Ye=we?.value??we?.label??E.options[M];return Ye?await ki(Ye,C):!1},async submitPendingInputText(M){return await ki(M)},async interrupt(){if(T=!0,m.abort(),c?.abort(),S||(x=!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){Zi.set(t.name,t)}function Rn(t){let e=Zi.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...Zi.keys()].join(", ")}`);return e}function Pd(){return Rn(me())}var Zi,es=J(()=>{Ga();gd();wd();ae();Zi=new Map;Xi(new cr);Xi(new Sr);Xi(new wr)});function O(t){return t.backendRef?.conversationId??t.harnessSessionId}function G(t){return t.id??t.sessionId??t.name??O(t)??t.harnessSessionId}function nf(t){return t.harnessSessionId}function fe(t){let e=[G(t),O(t),nf(t)].filter(n=>!!n);return[...new Set(e)]}function ts(t){return t.harnessName??t.persistedHarness??me()}function An(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return Rn(ts(t)).capabilities.worktrees}catch{return"plugin-managed"}}function ns(t){return t==="native-execution"}function Pr(t){return t==="native-restore"}function rf(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function le(t){let e=An(t);return(ns(e)||Pr(e))&&rf(t)}var ne=J(()=>{ae();es()});import{execFileSync as ie}from"child_process";import*as Br from"fs";import{tmpdir as Wf}from"os";import{dirname as Vd,join as Lf}from"path";function Bf(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 Fr(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(D.worktreeDir)return D.worktreeDir;if(t){let e=Bf(t);if(e)return Lf(e,".worktrees")}return Wf()}function jd(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100).replace(/[-.]+$/,"")||"session"}function qr(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")?Vd(e):void 0}catch{return}}function Ff(){if(Wr!==void 0)return Wr;try{return ie("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Wr=!0,!0}catch{return Wr=!1,!1}}function he(){if(Lr!==void 0)return Lr;try{return ie("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Lr=!0,!0}catch{return Lr=!1,!1}}function Ur(t){if(!Ff())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 Gd(t){try{let e=Uf(t);if(!e)return`${Fr(t)}`,!0;let n=Br.statfsSync(e),r=n.bavail*n.bsize;return Kf(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function vt(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 Kr(t,e,n="origin"){let r=`refs/remotes/${n}/${e}`;try{return ie("git",["-C",t,"fetch",n,`+${e}:${r}`],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ie("git",["-C",t,"rev-parse","--verify",r],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r}catch{return}}function qf(t){let e=t;for(;;){if(Br.existsSync(e))return e;let n=Vd(e);if(n===e)return;e=n}}function Uf(t){return qf(Fr(t))}function Kf(t){return t>=104857600}function Le(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 ke(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 xn(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 Hd(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 Se(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 Vr(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 Pe(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 Tn(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 Wr,Lr,Jt=J(()=>{ae()});import{execFileSync as Yt}from"child_process";import{randomBytes as Vf}from"crypto";import{appendFileSync as jf,existsSync as ds,mkdirSync as zd,readFileSync as Gf,rmSync as as}from"fs";import{relative as Hf,sep as Qd}from"path";function zf(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function Qf(t){try{return Yt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Jf(t){return t===0?"":`-${t}-${Vf(8).toString("hex")}`}function Yf(t,e){let n=Qf(t);if(!n)return;let r=Hf(n,e);if(!r||r.startsWith("..")||r.includes(`..${Qd}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(Qd).join("/").replace(/\/$/,"")}/`;try{let s=ds(o)?Gf(o,"utf-8"):"";s.split(/\r?\n/).map(d=>d.trim()).some(d=>d===i||d===`/${i}`)||jf(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 as(t,e,n={}){let r=jd(e),o=Fr(t);Jf(t,o),zd(o,{recursive:!0});let i=n.allowExistingBranch===!0,s,a,d=10,l=!1;for(let f=0;f<d;f++){let p=Qf(f),k=`${o}/openclaw-worktree-${r}${p}`,m=`agent/${r}${p}`;if(!i&&vt(t,m))continue;let c=!1;do{c=!1;try{zd(k,{recursive:!1}),s=k,a=m;break}catch(y){if(Hf(y,"EEXIST")){if(i&&f===0&&!l)try{is(k,{recursive:!0,force:!0}),l=!0,c=!0}catch(S){throw new Error(`Failed to recreate existing worktree branch ${m}: could not clear blocked path ${k}: ${S instanceof Error?S.message:String(S)}`)}else if(i&&f===0)throw new Error(`Failed to recreate existing worktree branch ${m}: path ${k} remains blocked after one cleanup attempt`);continue}throw y}}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=vt(t,a);try{u?Yt("git",["-C",t,"worktree","add",s,a],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):Yt("git",["-C",t,"worktree","add","-b",a,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){try{is(s,{recursive:!0,force:!0})}catch{}throw f}return s}function wt(t){if(!ss(t))return[];try{let e=Yt("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 Pt(t){return wt(t).length>0}function ce(t,e,n={}){let r=n.destructive===!0,o=wt(e);if(o.length>0&&!r)return`${e}${o[0]}`,!1;try{return Yt("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 is(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 jr(t){try{Yt("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}`}}function Jd(t){return ss(t)}var ds=J(()=>{Jt()});import{execFileSync as ee}from"child_process";import{existsSync as Yf}from"fs";function Zt(t){return(t.warnings??[]).filter(e=>!(t.stashPopConflict&&e.startsWith("Failed to pop auto-stash after merge"))).map(e=>`Recovery warning: ${e}`)}function Be(t,e){let n=Zt(e);return n.length===0?t:`${t}
16
+ `,"utf-8")}catch(s){`${i}${o}${s instanceof Error?s.message:String(s)}`}}function ls(t,e,n={}){let r=jd(e),o=Fr(t);Yf(t,o),zd(o,{recursive:!0});let i=n.allowExistingBranch===!0,s,a,d=10,l=!1;for(let f=0;f<d;f++){let p=Jf(f),k=`${o}/openclaw-worktree-${r}${p}`,m=`agent/${r}${p}`;if(!i&&vt(t,m))continue;let c=!1;do{c=!1;try{zd(k,{recursive:!1}),s=k,a=m;break}catch(y){if(zf(y,"EEXIST")){if(i&&f===0&&!l)try{as(k,{recursive:!0,force:!0}),l=!0,c=!0}catch(S){throw new Error(`Failed to recreate existing worktree branch ${m}: could not clear blocked path ${k}: ${S instanceof Error?S.message:String(S)}`)}else if(i&&f===0)throw new Error(`Failed to recreate existing worktree branch ${m}: path ${k} remains blocked after one cleanup attempt`);continue}throw y}}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=vt(t,a);try{u?Yt("git",["-C",t,"worktree","add",s,a],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):Yt("git",["-C",t,"worktree","add","-b",a,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){try{as(s,{recursive:!0,force:!0})}catch{}throw f}return s}function wt(t){if(!ds(t))return[];try{let e=Yt("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 Pt(t){return wt(t).length>0}function ce(t,e,n={}){let r=n.destructive===!0,o=wt(e);if(o.length>0&&!r)return`${e}${o[0]}`,!1;try{return Yt("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 as(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 jr(t){try{Yt("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}`}}function Jd(t){return ds(t)}var us=J(()=>{Jt()});import{execFileSync as ee}from"child_process";import{existsSync as Zf}from"fs";function Zt(t){return(t.warnings??[]).filter(e=>!(t.stashPopConflict&&e.startsWith("Failed to pop auto-stash after merge"))).map(e=>`Recovery warning: ${e}`)}function Be(t,e){let n=Zt(e);return n.length===0?t:`${t}
18
18
  ${n.map(r=>`⚠️ ${r}`).join(`
19
19
  `)}`}function Gr(t){return t instanceof Error?t.message:String(t)}function He(t,e,n){try{let r=ee("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10),s=ee("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 f=s.match(/(\d+)\s+insertions?\(/);f&&(d=parseInt(f[1],10));let p=s.match(/(\d+)\s+deletions?\(/);p&&(l=parseInt(p[1],10));let m=ee("git",["-C",t,"diff","--name-only","--diff-filter=ACMR",`${n}...${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
20
20
  `).map(S=>S.trim()).filter(Boolean),y=ee("git",["-C",t,"log",`${n}..${e}`,"--format=%h|%s|%an","-n","5"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
21
21
  `).filter(Boolean).map(S=>{let[b,x,T]=S.split("|");return{hash:b||"",message:x||"",author:T||""}});return{commits:o,filesChanged:a,insertions:d,deletions:l,changedFiles:m,commitMessages:y}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function Hr(t,e,n="origin"){try{return ee("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 Yd(t){try{return ee("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 zr(t,e,n,r="merge",o){let i=!1,s,a=[],d=f=>a.length>0?{...f,warnings:[...a]}:f,l=(f,p)=>{a.push(`${f}: ${Gr(p)}`)},u=f=>{if(i)try{ee("git",["-C",f,"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(ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Yd(t)){let c;try{c=ee("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(y){return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Gr(y)}. Commit or stash changes manually, then retry.`})}if(!c.includes("No local changes to save")){i=!0;try{s=ee("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(y){l("Failed to determine auto-stash ref",y)}}}ee("git",["-C",t,"merge","--squash",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ee("git",["-C",t,"commit","-m",`Squash merge ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let m=!1;if(i)try{ee("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){m=!0,l("Failed to pop auto-stash after merge",c)}return d({success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:m||void 0})}let f=o&&Yf(o),p=f?o:t;if(f||ee("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Yd(t)){let m;try{m=ee("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(y){l(`Failed to check out ${n} after auto-stash failure`,y)}return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Gr(c)}. Commit or stash changes manually, then retry.`})}if(!m.includes("No local changes to save")){i=!0;try{s=ee("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{ee("git",["-C",p,"rebase",n],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{try{ee("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{ee("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
- `)})}ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ee("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let k=!1;if(i)try{ee("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){k=!0,l("Failed to pop auto-stash after merge",m)}return d({success:!0,fastForward:!0,stashed:i||void 0,stashRef:s,stashPopConflict:k||void 0})}catch(f){try{ee("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:Gr(f),stashed:i||void 0,stashRef:s})}}var Zd=J(()=>{});import{execFileSync as ze}from"child_process";function tl(t){let e=t.toLowerCase();return e==="open"?"open":e==="merged"?"merged":e==="closed"?"closed":"none"}function nl(t){if(/\r|\n/.test(t)||!/(?<!\\)\\n\\n/.test(t))return t;let e=t.replace(Zf,`
22
+ `).some(n=>n.length>0&&!n.startsWith("??")&&!n.startsWith("!!"))}catch{return!1}}function zr(t,e,n,r="merge",o){let i=!1,s,a=[],d=f=>a.length>0?{...f,warnings:[...a]}:f,l=(f,p)=>{a.push(`${f}: ${Gr(p)}`)},u=f=>{if(i)try{ee("git",["-C",f,"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(ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Yd(t)){let c;try{c=ee("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(y){return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Gr(y)}. Commit or stash changes manually, then retry.`})}if(!c.includes("No local changes to save")){i=!0;try{s=ee("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(y){l("Failed to determine auto-stash ref",y)}}}ee("git",["-C",t,"merge","--squash",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ee("git",["-C",t,"commit","-m",`Squash merge ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let m=!1;if(i)try{ee("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){m=!0,l("Failed to pop auto-stash after merge",c)}return d({success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:m||void 0})}let f=o&&Zf(o),p=f?o:t;if(f||ee("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Yd(t)){let m;try{m=ee("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(y){l(`Failed to check out ${n} after auto-stash failure`,y)}return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Gr(c)}. Commit or stash changes manually, then retry.`})}if(!m.includes("No local changes to save")){i=!0;try{s=ee("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{ee("git",["-C",p,"rebase",n],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{try{ee("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{ee("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
+ `)})}ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ee("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let k=!1;if(i)try{ee("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){k=!0,l("Failed to pop auto-stash after merge",m)}return d({success:!0,fastForward:!0,stashed:i||void 0,stashRef:s,stashPopConflict:k||void 0})}catch(f){try{ee("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:Gr(f),stashed:i||void 0,stashRef:s})}}var Zd=J(()=>{});import{execFileSync as ze}from"child_process";function tl(t){let e=t.toLowerCase();return e==="open"?"open":e==="merged"?"merged":e==="closed"?"closed":"none"}function nl(t){if(/\r|\n/.test(t)||!/(?<!\\)\\n\\n/.test(t))return t;let e=t.replace(Xf,`
24
24
  `),n=e.split(`
25
- `);return n.some(o=>/^#{1,6}\s+\S/.test(o.trim()))&&n.some(o=>/^(?:[-*+]\s+|\d+\.\s+|```)/.test(o.trim()))?e:t}function Xf(t){return t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:""}function Xd(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function el(t,e,n){let r=be(t,e,n);if(r.exists&&r.state==="open"&&r.url)return{success:!0,prUrl:r.url,warnings:["A PR already exists for this branch; reused the existing open PR."]};if(r.exists&&r.url)return{success:!1,error:`A PR already exists for ${e}, but it is ${r.state}: ${r.url}`}}function rl(t){try{return ze("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function eg(t,e,n){if(!n)return e;let r=rl(t);return r?`${r}:${e}`:e}function ol(t,e,n,r,o,i,s={}){if(!he())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",eg(t,e,i)),r&&o?a.push("--title",r,"--body",nl(o)):a.push("--fill-verbose"),{success:!0,prUrl:ze("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(Xd(l))return el(t,e,i)??{success:!1,error:l};if((s.draft??!0)&&a&&/draft/i.test(l))try{let u=a.filter(k=>k!=="--draft");return{success:!0,prUrl:ze("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 f=u instanceof Error?u.message:String(u);return Xd(f)?el(t,e,i)??{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${f}`}:{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${f}`}}return{success:!1,error:l}}}function be(t,e,n){if(!he())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=ze("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?rl(t)?.toLowerCase():void 0,d=s.find(f=>f.headRefName===e&&(!a||f.headRepositoryOwner?.login?.toLowerCase()===a));if(!d)return{exists:!1,state:"none"};let u={exists:!0,state:tl(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 Qe(t,e,n){if(!he())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=ze("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim()),s={exists:!0,state:tl(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 il(t,e,n){if(!he())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=ze("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 sl(t,e,n,r){if(!he())return!1;try{let o=["pr","edit",String(e),"--body",nl(n)];return r&&o.push("--repo",r),ze("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 al(t,e,n,r){if(!he())return!1;try{let o=["pr","edit",String(e),"--title",n];return r&&o.push("--repo",r),ze("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 dl(t,e,n,r){if(!he())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),ze("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 bt(t){let e=Xf(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 Zf,ls=J(()=>{Jt();Zf=/(?<!\\)\\(?:r\\)?n/g});import{existsSync as us}from"fs";function ll(){return new Date().toISOString()}function tg(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:ll(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function ng(t){let e=ul(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&us(e)?Le(e):void 0)}function ul(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function lt(t,e={}){let n=tg(t),r=ll(),o=new Set,i=ul(t),s=!!(i&&us(i)),a=!!(t.worktreePath&&us(t.worktreePath)),d=t.worktreeBranch,l=ng(t),u=!1,f=!1,p=!1,k=!1,m=!1,c,y,S="none",b=t.worktreePrUrl,x=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=vt(i,d),u||o.add("branch_missing")),a&&t.worktreePath&&(f=Pt(t.worktreePath),f&&o.add("dirty_worktree_entries")),s&&i&&u&&d&&l){let R=Hd(i,d,l);c=R?.ahead,y=R?.behind,p=Se(i,d,l),p?o.add("topology_merged"):(k=Vr(i,d,l),k&&o.add("merge_noop_content_already_on_base"),!k&&(c??0)>0&&o.add("unique_content"));let _=ke(i);if(e.includePrSync&&t.worktreePrUrl&&_&&_!==d&&_!==l){let F=Qe(i,t.worktreePrUrl,t.worktreePrTargetRepo??n.targetRepo);m=!!((F.state==="open"||F.state==="merged")&&F.headRefName===_&&F.baseRefName===l&&Se(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 R=be(i,d,t.worktreePrTargetRepo??n.targetRepo);S=R.state,b=R.url??b,x=R.number??x}S==="open"&&o.add("pr_open"),S==="merged"&&!p&&!k&&o.add("pr_merged_not_reflected_locally");let T=e.includePrSync&&n.state==="pr_open"&&S!=="open";T&&o.add("stale_pr_open");let A;p?A="merged":(k||m)&&(A="released");let h=e.activeSession||f,w=n.state;!h&&A?w=A:T?w="pending_decision":!u&&n.state==="pending_decision"&&(w="cleanup_failed");let L=w==="merged"||w==="released",K=e.activeSession||f||!L&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||S==="open"||o.has("pr_merged_not_reflected_locally"),W=!K&&(w==="merged"||w==="released"||n.state==="dismissed"||n.state==="no_change"),I={checkedAt:r,repoExists:s,branchExists:u,worktreeExists:a,activeSession:e.activeSession===!0,dirtyTracked:f,topologyMerged:p,releaseNoopMerge:k,representedByTargetPrBranch:m,branchAheadCount:c,baseAheadCount:y,prState:S,prUrl:b,prNumber:x,reasons:[...o]};return{lifecycle:n,evidence:I,derivedState:w,cleanupSafe:W,preserve:K,reasons:[...o]}}var Cn=J(()=>{Jt();ls();ds()});var Re=J(()=>{Jt();ds();Zd();ls();Cn()});function oo(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function io(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:oo(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function Ol(t,e,n,r={}){let o=r.updatedAt??new Date().toISOString();return{autoMergeConflictResolutionAttemptCount:n,autoMergeResolverSessionId:e,pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,lifecycle:"terminal",worktreeState:"merge_conflict_resolving",worktreeLifecycle:oo(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function en(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:oo(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function Nl(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:oo(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=J(()=>{});import{existsSync as Qg,readFileSync as Jg}from"fs";function Wl(t){if(!t)return!1;let e=new Set(t.split(/\r?\n/).map(i=>i.trim().replace(/^[#*_\s]+|[:*_\s]+$/g,"").toLowerCase())),n=["root cause","summary","result"].some(i=>e.has(i)),r=["fix","changes","implementation","implemented"].some(i=>e.has(i)),o=["validation","verification","tests"].some(i=>e.has(i));return n&&r&&o}function tn(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?G(n):r?G(r):void 0,i=n?.getOutput?.().join(`
26
- `).trim(),s;if(r?.outputPath&&Qg(r.outputPath))try{s=Jg(r.outputPath,"utf-8").trim()}catch{}let a=Wl(i),d=Wl(s),l=a===d?(s?.length??0)>(i?.length??0)?s:i:d?s:i;return{activeSession:n,persistedSession:r,persistedRef:o,sessionName:n?.name??r?.name??e,prompt:n?.prompt??r?.prompt,outputPreview:l?l.slice(-12e3):void 0,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?fe(t.persistedSession):[],...t.activeSession?fe(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function Yg(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 so(t,e,n={}){let{activeSession:r,persistedSession:o}=Yg(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 ao(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 lo(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function At(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 uo(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=J(()=>{ne();Cn()});function Fl(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
25
+ `);return n.some(o=>/^#{1,6}\s+\S/.test(o.trim()))&&n.some(o=>/^(?:[-*+]\s+|\d+\.\s+|```)/.test(o.trim()))?e:t}function eg(t){return t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:""}function Xd(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function el(t,e,n){let r=be(t,e,n);if(r.exists&&r.state==="open"&&r.url)return{success:!0,prUrl:r.url,warnings:["A PR already exists for this branch; reused the existing open PR."]};if(r.exists&&r.url)return{success:!1,error:`A PR already exists for ${e}, but it is ${r.state}: ${r.url}`}}function rl(t){try{return ze("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function tg(t,e,n){if(!n)return e;let r=rl(t);return r?`${r}:${e}`:e}function ol(t,e,n,r,o,i,s={}){if(!he())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",tg(t,e,i)),r&&o?a.push("--title",r,"--body",nl(o)):a.push("--fill-verbose"),{success:!0,prUrl:ze("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(Xd(l))return el(t,e,i)??{success:!1,error:l};if((s.draft??!0)&&a&&/draft/i.test(l))try{let u=a.filter(k=>k!=="--draft");return{success:!0,prUrl:ze("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 f=u instanceof Error?u.message:String(u);return Xd(f)?el(t,e,i)??{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${f}`}:{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${f}`}}return{success:!1,error:l}}}function be(t,e,n){if(!he())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=ze("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?rl(t)?.toLowerCase():void 0,d=s.find(f=>f.headRefName===e&&(!a||f.headRepositoryOwner?.login?.toLowerCase()===a));if(!d)return{exists:!1,state:"none"};let u={exists:!0,state:tl(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 Qe(t,e,n){if(!he())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=ze("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim()),s={exists:!0,state:tl(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 il(t,e,n){if(!he())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=ze("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 sl(t,e,n,r){if(!he())return!1;try{let o=["pr","edit",String(e),"--body",nl(n)];return r&&o.push("--repo",r),ze("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 al(t,e,n,r){if(!he())return!1;try{let o=["pr","edit",String(e),"--title",n];return r&&o.push("--repo",r),ze("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 dl(t,e,n,r){if(!he())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),ze("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 bt(t){let e=eg(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 Xf,cs=J(()=>{Jt();Xf=/(?<!\\)\\(?:r\\)?n/g});import{existsSync as ps}from"fs";function ll(){return new Date().toISOString()}function ng(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:ll(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function rg(t){let e=ul(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&ps(e)?Le(e):void 0)}function ul(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function lt(t,e={}){let n=ng(t),r=ll(),o=new Set,i=ul(t),s=!!(i&&ps(i)),a=!!(t.worktreePath&&ps(t.worktreePath)),d=t.worktreeBranch,l=rg(t),u=!1,f=!1,p=!1,k=!1,m=!1,c,y,S="none",b=t.worktreePrUrl,x=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=vt(i,d),u||o.add("branch_missing")),a&&t.worktreePath&&(f=Pt(t.worktreePath),f&&o.add("dirty_worktree_entries")),s&&i&&u&&d&&l){let R=Hd(i,d,l);c=R?.ahead,y=R?.behind,p=Se(i,d,l),p?o.add("topology_merged"):(k=Vr(i,d,l),k&&o.add("merge_noop_content_already_on_base"),!k&&(c??0)>0&&o.add("unique_content"));let _=ke(i);if(e.includePrSync&&t.worktreePrUrl&&_&&_!==d&&_!==l){let F=Qe(i,t.worktreePrUrl,t.worktreePrTargetRepo??n.targetRepo);m=!!((F.state==="open"||F.state==="merged")&&F.headRefName===_&&F.baseRefName===l&&Se(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 R=be(i,d,t.worktreePrTargetRepo??n.targetRepo);S=R.state,b=R.url??b,x=R.number??x}S==="open"&&o.add("pr_open"),S==="merged"&&!p&&!k&&o.add("pr_merged_not_reflected_locally");let T=e.includePrSync&&n.state==="pr_open"&&S!=="open";T&&o.add("stale_pr_open");let A;p?A="merged":(k||m)&&(A="released");let h=e.activeSession||f,w=n.state;!h&&A?w=A:T?w="pending_decision":!u&&n.state==="pending_decision"&&(w="cleanup_failed");let L=w==="merged"||w==="released",K=e.activeSession||f||!L&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||S==="open"||o.has("pr_merged_not_reflected_locally"),W=!K&&(w==="merged"||w==="released"||n.state==="dismissed"||n.state==="no_change"),I={checkedAt:r,repoExists:s,branchExists:u,worktreeExists:a,activeSession:e.activeSession===!0,dirtyTracked:f,topologyMerged:p,releaseNoopMerge:k,representedByTargetPrBranch:m,branchAheadCount:c,baseAheadCount:y,prState:S,prUrl:b,prNumber:x,reasons:[...o]};return{lifecycle:n,evidence:I,derivedState:w,cleanupSafe:W,preserve:K,reasons:[...o]}}var Cn=J(()=>{Jt();cs();us()});var Re=J(()=>{Jt();us();Zd();cs();Cn()});function oo(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function io(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:oo(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function Ol(t,e,n,r={}){let o=r.updatedAt??new Date().toISOString();return{autoMergeConflictResolutionAttemptCount:n,autoMergeResolverSessionId:e,pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,lifecycle:"terminal",worktreeState:"merge_conflict_resolving",worktreeLifecycle:oo(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function en(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:oo(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function Nl(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:oo(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=J(()=>{});import{existsSync as Jg,readFileSync as Yg}from"fs";function Wl(t){if(!t)return!1;let e=new Set(t.split(/\r?\n/).map(i=>i.trim().replace(/^[#*_\s]+|[:*_\s]+$/g,"").toLowerCase())),n=["root cause","summary","result"].some(i=>e.has(i)),r=["fix","changes","implementation","implemented"].some(i=>e.has(i)),o=["validation","verification","tests"].some(i=>e.has(i));return n&&r&&o}function tn(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?G(n):r?G(r):void 0,i=n?.getOutput?.().join(`
26
+ `).trim(),s;if(r?.outputPath&&Jg(r.outputPath))try{s=Yg(r.outputPath,"utf-8").trim()}catch{}let a=Wl(i),d=Wl(s),l=a===d?(s?.length??0)>(i?.length??0)?s:i:d?s:i;return{activeSession:n,persistedSession:r,persistedRef:o,sessionName:n?.name??r?.name??e,prompt:n?.prompt??r?.prompt,outputPreview:l?l.slice(-12e3):void 0,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?fe(t.persistedSession):[],...t.activeSession?fe(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function Zg(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 so(t,e,n={}){let{activeSession:r,persistedSession:o}=Zg(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 ao(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 lo(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function At(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 uo(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=J(()=>{ne();Cn()});function Fl(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
27
27
  `).split(`
28
28
  `).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?`
29
- `:" ").replace(/[ \t]+/g," ").trim()||void 0}function It(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_-]{${Bl},}\\b`,"g"),"[redacted token]")}function Bn(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_-]{${Bl},}\\b`).test(t)}function nh(t){let e=Fl(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=Ln(n).replace(/\s+/g," ").trim();return r?It(r,180):void 0}function ql(t){return Ln(t.trim()).replace(/\s+/g," ").trim()}function rh(t,e){return t?.commitMessages.map(n=>ql(n.message)).filter(Boolean).slice(0,e)??[]}function Is(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function Ul(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function oh(t){let e={summary:[],changes:[],validation:[]},n;for(let r of(t??"").split(/\r?\n/)){let o=r.trim(),i=o.replace(/^[#*_\s]+|[:*_\s]+$/g,"").toLowerCase();if(/^(?:root cause|summary|result)$/.test(i)){n="summary";continue}if(/^(?:fix|changes|implementation|implemented)$/.test(i)){n="changes";continue}if(/^(?:validation|verification|tests)$/.test(i)){n="validation";continue}if(/^[A-Za-z][A-Za-z /_-]{2,30}:$/.test(o)){n=void 0;continue}let s=o.match(/^[-*•]\s+(.+)$/)?.[1]?.trim();if(!n||!s||s.length<8)continue;let a=It(Fe(s),n==="validation"?160:180);a&&!Bn(a)&&e[n].push(a)}return{summary:e.summary.slice(0,5),changes:e.changes.slice(0,10),validation:e.validation.slice(0,5)}}function ih(t){let e=nh(t.prompt),n=t.diffSummary,r=oh(t.outputPreview);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:rh(n,5),sessionSummary:r.summary,sessionChanges:r.changes,validation:r.validation.length>0?r.validation:Is(),notes:Ul()}}function mo(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 Kl(t,e){let n=Fl(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 Kl(e,n.objective).some(o=>r.includes(o))}function Ll(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function xs(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 k=p[1],m=p[2]?.toLowerCase();if(m!==void 0&&d.has(m)&&!o.has(k)&&!Ll(k))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 k=p[1],m=p[2]?.toLowerCase();return m!==void 0&&d.has(m)&&!o.has(k)&&!Ll(k)})}function Fe(t){return Ln(t).replace(/\s+/g," ").trim()}function sh(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||!mo(r.summary,5,180)||!mo(r.changes,10,160)||!mo(r.validation,5,160)||!mo(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(a=>Bn(a)||Wn(a,n,e)))return;let i={title:Fe(r.title),summary:r.summary.map(Fe),changes:r.changes.map(Fe),validation:r.validation.map(Fe),notes:r.notes.map(Fe)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(a=>!a||Bn(a)||Wn(a,n,e))&&!s.some(a=>xs(a,e)))return i}function As(t,e,n={}){let r=It(Ln(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),o=t.sessionSummary.length>0||t.sessionChanges.length>0,i=o?t.commitSubjects[0]?.replace(/^(?:feat|fix|chore|refactor|test|docs|build|ci|perf)(?:\([^)]*\))?!?:\s*/i,""):void 0,s=It(i||`OpenClaw agent changes: ${r}`,90),a=o?th:n.reason==="provider-failed"||n.reason==="provider-invalid"?Ms:Cs,d=[a,...t.sessionSummary,`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."]],l=t.sessionChanges.length>0?t.sessionChanges:t.changedFiles.length>0?t.changedFiles.slice(0,10).map(S=>`\`${S}\``):["Review the pushed worktree branch for the full set of changes."],u=t.sessionChanges.length===0&&t.changedFiles.length>10?[`...and ${t.changedFiles.length-10} more changed files.`]:[],f=["Fallback metadata is conservative; review the diff and CI/checks before marking the draft PR ready.",...t.notes],p={title:s,summary:d,changes:[...l,...u],validation:t.validation,notes:f},k=!1,m=!1,c=S=>{let b=Fe(S);if(Wn(b,e,t)){k=!0;let x=Kl(e,t.objective);for(let T of x){let A=new RegExp(T.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");b=b.replace(A,"[redacted prompt detail]")}b=Fe(b)}return xs(b,t)&&(m=!0,b="[redacted file reference outside change set]"),b=Fe(b),(Wn(b,e,t)||Bn(b))&&(k=!0,b="[redacted prompt detail]"),b};if(p={title:c(p.title)||It(`OpenClaw agent changes: ${r}`,90),summary:p.summary.map(c).filter(S=>S&&S.length>0),changes:p.changes.map(c).filter(S=>S&&S.length>0),validation:p.validation.map(c).filter(S=>S&&S.length>0),notes:p.notes.map(c).filter(S=>S&&S.length>0)},p.summary.length===0&&(p.summary=[a]),p.changes.length===0&&(p.changes=["Review the pushed worktree branch for the full set of changes."]),p.validation.length===0&&(p.validation=Is()),p.notes.length===0&&(p.notes=Ul()),k||m){let S="Some content was stripped from fallback metadata due to safety checks (prompt leak guard or references to files outside the diff).";p.notes.some(b=>b.toLowerCase().includes("stripped")||b.toLowerCase().includes("sanitized"))||(p.notes=[...p.notes,S])}let y=[p.title,...p.summary,...p.changes,...p.validation,...p.notes];if(y.some(S=>!S)||y.some(S=>Bn(S)||Wn(S,e,t))||y.some(S=>xs(S,t))){let S=It(Ln(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);p={title:It(`OpenClaw agent changes: ${S}`,90),summary:["Deterministic fallback metadata (sanitized for safety)."],changes:t.changedFiles.length>0?t.changedFiles.slice(0,5).map(b=>`\`${b}\``):["See the worktree branch diff for the full set of changes."],validation:Is(),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 S=Fe(t.branchName);p.notes.some(b=>b.toLowerCase().includes(S.toLowerCase()))||(p.notes=[...p.notes,`Branch: ${S}`])}return p}async function Fn(t){let e=ih({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,outputPreview:t.outputPreview,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:As(e,t.prompt,{reason:"no-provider"}),evidence:e,fallbackReason:"no-provider"};try{let n=await t.provider.generatePrMetadata(e),r=sh(lh(n),e,t.prompt);return r?{ok:!0,metadata:r,evidence:e}:{ok:!0,metadata:As(e,t.prompt,{reason:"provider-invalid"}),evidence:e,fallbackReason:"provider-invalid"}}catch(n){return`${n instanceof Error?n.message:String(n)}`,{ok:!0,metadata:As(e,t.prompt,{reason:"provider-failed"}),evidence:e,fallbackReason:"provider-failed"}}}function fo(){let t=tt(),e=ah(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=dh(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 ah(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 dh(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(`
30
- `)}function lh(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 go(t){return t?t.includes(Ts)||t.includes(Cs)||t.includes(Ms):!1}function ho(t){return t?t.trim()===Ts||t.includes(Cs)||t.includes(Ms):!1}function yo(t){return t?/^OpenClaw agent changes:/i.test(t.trim()):!1}function qn(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} ${ql(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("---",Ts),e.join(`
31
- `)}var Bl,Ts,Cs,Ms,th,_s=J(()=>{ft();Bl=32,Ts="Generated with [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)",Cs="Deterministic fallback metadata generated because no LLM PR metadata provider is configured.",Ms="Deterministic fallback metadata generated because the LLM PR metadata provider failed or returned unusable output.",th="PR metadata generated from the coding agent's final session report."});var Jl={};Qc(Jl,{buildPrCompletionWakeOutcomeKey:()=>Os,buildPrMetadata:()=>Fn,buildPrOutcomeDetailLines:()=>Ds,createRuntimePrMetadataProvider:()=>fo,discoverExistingTargetPr:()=>Hl,formatPrBody:()=>qn,isOcaFallbackPrBody:()=>ho,isOcaGeneratedPrBody:()=>go,isOcaGeneratedPrTitle:()=>yo,makeAgentPrTool:()=>Un,normalizeForceNewReplacementPrStatus:()=>Es,refreshOpenPrMetadata:()=>Ql,resolveExistingTargetPrUpdateBranch:()=>Gl,resolveExistingTargetPrUpdateSourceBranch:()=>zl,shouldIgnoreClosedTargetPrForForceNew:()=>jl});import{execFileSync as ko}from"child_process";import{existsSync as uh}from"fs";function ch(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function jl(t,e){return t===!0&&e?.exists===!0&&e.state!=="open"}function Es(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 ph(t,e){try{let n=ko("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 Vl(t,e,n){try{let r=ph(t,e);return r?(ko("git",["-C",r,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1}):(ke(t)===e?ko("git",["-C",t,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):ko("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 Gl(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,i=Kr(e,o),s=i??o;if(o===n&&!i)return{success:!0,branchName:n,alreadyRepresented:!1};if(!vt(e,o)&&!i)return{success:!1,error:`Target PR branch ${o} is not available locally. Fetch it before updating the PR.`};if(Se(e,n,s)){if(i&&!Se(e,i,o)&&Se(e,o,i)){let a=Vl(e,o,i);if("error"in a)return a}return{success:!0,branchName:o,alreadyRepresented:!!i}}return ke(e)===o&&Se(e,s,o)&&Se(e,n,o)?{success:!0,branchName:o,alreadyRepresented:!1}:Se(e,s,n)?Vl(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 Hl(t){let e=ke(t.repoDir);if(!e||e!==t.expectedParentBranch||e===t.worktreeBranch||e===t.baseBranch)return;let n=be(t.repoDir,e,t.targetRepo);return n.exists&&n.state==="open"&&n.headRefName===e&&(!n.baseRefName||n.baseRefName===t.baseBranch)?n:void 0}function zl(t){let e=t.targetPrStatus.headRefName;if(!e||e===t.fallbackBranch)return t.fallbackBranch;let n=ke(t.repoDir);return n===e?n:t.fallbackBranch}function Ds(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 Os(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 Ql(t){let e=t.prStatus.number??t.prStatus.url;if(!e)return{status:"skipped",reason:"missing-pr-identity"};let n=t.operations?.getBody??il,r=t.operations?.updateBody??sl,o=t.operations?.updateTitle??al;if(t.explicitTitle!==void 0||t.explicitBody!==void 0){let m=t.explicitTitle===void 0?!1:o(t.repoDir,e,t.explicitTitle,t.targetRepo);if(t.explicitTitle!==void 0&&!m)return{status:"failed",reason:"failed to update explicit PR title"};let c=t.explicitBody===void 0?!1:r(t.repoDir,e,t.explicitBody,t.targetRepo);return t.explicitBody!==void 0&&!c?{status:"failed",reason:"failed to update explicit PR body"}:{status:"updated",updatedTitle:m,updatedBody:c,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||go(s)))return{status:"skipped",reason:"human-edited"};let d=await Fn({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,outputPreview:t.outputPreview,diffSummary:t.diffSummary,provider:t.metadataProvider});if(d.ok===!1)return{status:"failed",reason:d.error};let l=d.evidence.sessionSummary.length>0||d.evidence.sessionChanges.length>0;if(d.fallbackReason!==void 0&&(!l||!ho(s)))return{status:"failed",reason:"generated PR metadata was unavailable; preserved existing generated PR metadata"};let u=qn({sessionName:t.sessionName,metadata:d.metadata,diffSummary:t.diffSummary}),f=t.forceRefresh||yo(t.prStatus.title),p=!1;if(f&&t.prStatus.title?.trim()!==d.metadata.title.trim()&&(p=o(t.repoDir,e,d.metadata.title,t.targetRepo),!p))return{status:"failed",reason:"failed to update generated PR title"};if(u.trim()===s.trim())return p?{status:"updated",updatedTitle:p,updatedBody:!1,reason:t.forceRefresh?"forced":"generated"}:{status:"skipped",reason:"unchanged"};let k=r(t.repoDir,e,u,t.targetRepo);return k?{status:"updated",updatedTitle:p,updatedBody:k,reason:t.forceRefresh?"forced":"generated"}:{status:"failed",reason:"failed to update generated PR body"}}function $s(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 Un(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(!ch(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(!he())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=tn(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"}};uh(a)||`${a}${u}${d}`;let f=r.base_branch??Le(d),p=e.metadataProvider??fo(),k=R=>{let _=Nl({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??f,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:R.prUrl,prNumber:R.prNumber,baseBranch:f,targetRepo:R.targetRepo,disposition:R.disposition});for(let F of On(o))v.updatePersistedSession(F,_)},m=Tn(d,r.target_repo??s?.worktreePrTargetRepo),c=s?.worktreePrUrl??i?.worktreePrUrl,y=c?Qe(d,c,m):void 0;if(c&&!y?.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=jl(r.force_new,y),b=S?void 0:c,x=!c&&!r.force_new?Hl({repoDir:d,worktreeBranch:u,expectedParentBranch:s?.worktreeParentBranch??i?.worktreeParentBranch,baseBranch:f,targetRepo:m}):void 0,T=S?void 0:y??x,A=b??x?.url,h=!1;if(T?.exists&&T.state==="open"){let R=zl({repoDir:d,fallbackBranch:u,targetPrStatus:T}),_=Gl({repoDir:d,sourceBranch:R,targetPrStatus:T});if("error"in _)return{content:[{type:"text",text:`Error: ${_.error}`}],meta:{success:!1,state:"error"}};u=_.branchName,h=_.alreadyRepresented}let w=v.resolveRepoPolicy(d),L=Es(T?.exists?T:be(d,u,m),y,{forceNewIgnoresClosedTargetPr:S}),K=L.exists&&L.state==="open";if(w?.policy==="never-pr"&&!K)return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${w.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};if(w&&!w.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${w.identity?.repoRoot??d}. Provider: ${w.provider}.`}],meta:{success:!1,state:"error"}};if((!T||T.state==="open")&&!h&&!Hr(d,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let I=Es(A?Qe(d,A,m):be(d,u,m),y,{forceNewIgnoresClosedTargetPr:S});if(r.force_new&&I.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${I.state}).
29
+ `:" ").replace(/[ \t]+/g," ").trim()||void 0}function It(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_-]{${Bl},}\\b`,"g"),"[redacted token]")}function Bn(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_-]{${Bl},}\\b`).test(t)}function rh(t){let e=Fl(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=Ln(n).replace(/\s+/g," ").trim();return r?It(r,180):void 0}function ql(t){return Ln(t.trim()).replace(/\s+/g," ").trim()}function oh(t,e){return t?.commitMessages.map(n=>ql(n.message)).filter(Boolean).slice(0,e)??[]}function Ts(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function Ul(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function ih(t){let e={summary:[],changes:[],validation:[]},n;for(let r of(t??"").split(/\r?\n/)){let o=r.trim(),i=o.replace(/^[#*_\s]+|[:*_\s]+$/g,"").toLowerCase();if(/^(?:root cause|summary|result)$/.test(i)){n="summary";continue}if(/^(?:fix|changes|implementation|implemented)$/.test(i)){n="changes";continue}if(/^(?:validation|verification|tests)$/.test(i)){n="validation";continue}if(/^[A-Za-z][A-Za-z /_-]{2,30}:$/.test(o)){n=void 0;continue}let s=o.match(/^[-*•]\s+(.+)$/)?.[1]?.trim();if(!n||!s||s.length<8)continue;let a=It(Fe(s),n==="validation"?160:180);a&&!Bn(a)&&e[n].push(a)}return{summary:e.summary.slice(0,5),changes:e.changes.slice(0,10),validation:e.validation.slice(0,5)}}function sh(t){let e=rh(t.prompt),n=t.diffSummary,r=ih(t.outputPreview);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:oh(n,5),sessionSummary:r.summary,sessionChanges:r.changes,validation:r.validation.length>0?r.validation:Ts(),notes:Ul()}}function mo(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 Kl(t,e){let n=Fl(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 Kl(e,n.objective).some(o=>r.includes(o))}function Ll(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function Cs(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 k=p[1],m=p[2]?.toLowerCase();if(m!==void 0&&d.has(m)&&!o.has(k)&&!Ll(k))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 k=p[1],m=p[2]?.toLowerCase();return m!==void 0&&d.has(m)&&!o.has(k)&&!Ll(k)})}function Fe(t){return Ln(t).replace(/\s+/g," ").trim()}function ah(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||!mo(r.summary,5,180)||!mo(r.changes,10,160)||!mo(r.validation,5,160)||!mo(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(a=>Bn(a)||Wn(a,n,e)))return;let i={title:Fe(r.title),summary:r.summary.map(Fe),changes:r.changes.map(Fe),validation:r.validation.map(Fe),notes:r.notes.map(Fe)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(a=>!a||Bn(a)||Wn(a,n,e))&&!s.some(a=>Cs(a,e)))return i}function xs(t,e,n={}){let r=It(Ln(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),o=t.sessionSummary.length>0||t.sessionChanges.length>0,i=o?t.commitSubjects[0]?.replace(/^(?:feat|fix|chore|refactor|test|docs|build|ci|perf)(?:\([^)]*\))?!?:\s*/i,""):void 0,s=It(i||`OpenClaw agent changes: ${r}`,90),a=o?nh:n.reason==="provider-failed"||n.reason==="provider-invalid"?$s:_s,d=[a,...t.sessionSummary,`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."]],l=t.sessionChanges.length>0?t.sessionChanges:t.changedFiles.length>0?t.changedFiles.slice(0,10).map(S=>`\`${S}\``):["Review the pushed worktree branch for the full set of changes."],u=t.sessionChanges.length===0&&t.changedFiles.length>10?[`...and ${t.changedFiles.length-10} more changed files.`]:[],f=["Fallback metadata is conservative; review the diff and CI/checks before marking the draft PR ready.",...t.notes],p={title:s,summary:d,changes:[...l,...u],validation:t.validation,notes:f},k=!1,m=!1,c=S=>{let b=Fe(S);if(Wn(b,e,t)){k=!0;let x=Kl(e,t.objective);for(let T of x){let A=new RegExp(T.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");b=b.replace(A,"[redacted prompt detail]")}b=Fe(b)}return Cs(b,t)&&(m=!0,b="[redacted file reference outside change set]"),b=Fe(b),(Wn(b,e,t)||Bn(b))&&(k=!0,b="[redacted prompt detail]"),b};if(p={title:c(p.title)||It(`OpenClaw agent changes: ${r}`,90),summary:p.summary.map(c).filter(S=>S&&S.length>0),changes:p.changes.map(c).filter(S=>S&&S.length>0),validation:p.validation.map(c).filter(S=>S&&S.length>0),notes:p.notes.map(c).filter(S=>S&&S.length>0)},p.summary.length===0&&(p.summary=[a]),p.changes.length===0&&(p.changes=["Review the pushed worktree branch for the full set of changes."]),p.validation.length===0&&(p.validation=Ts()),p.notes.length===0&&(p.notes=Ul()),k||m){let S="Some content was stripped from fallback metadata due to safety checks (prompt leak guard or references to files outside the diff).";p.notes.some(b=>b.toLowerCase().includes("stripped")||b.toLowerCase().includes("sanitized"))||(p.notes=[...p.notes,S])}let y=[p.title,...p.summary,...p.changes,...p.validation,...p.notes];if(y.some(S=>!S)||y.some(S=>Bn(S)||Wn(S,e,t))||y.some(S=>Cs(S,t))){let S=It(Ln(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);p={title:It(`OpenClaw agent changes: ${S}`,90),summary:["Deterministic fallback metadata (sanitized for safety)."],changes:t.changedFiles.length>0?t.changedFiles.slice(0,5).map(b=>`\`${b}\``):["See the worktree branch diff for the full set of changes."],validation:Ts(),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 S=Fe(t.branchName);p.notes.some(b=>b.toLowerCase().includes(S.toLowerCase()))||(p.notes=[...p.notes,`Branch: ${S}`])}return p}async function Fn(t){let e=sh({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,outputPreview:t.outputPreview,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:xs(e,t.prompt,{reason:"no-provider"}),evidence:e,fallbackReason:"no-provider"};try{let n=await t.provider.generatePrMetadata(e),r=ah(uh(n),e,t.prompt);return r?{ok:!0,metadata:r,evidence:e}:{ok:!0,metadata:xs(e,t.prompt,{reason:"provider-invalid"}),evidence:e,fallbackReason:"provider-invalid"}}catch(n){return`${n instanceof Error?n.message:String(n)}`,{ok:!0,metadata:xs(e,t.prompt,{reason:"provider-failed"}),evidence:e,fallbackReason:"provider-failed"}}}function fo(){let t=tt(),e=dh(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=lh(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 dh(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 lh(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(`
30
+ `)}function uh(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 go(t){return t?t.includes(Ms)||t.includes(_s)||t.includes($s):!1}function ho(t){return t?t.trim()===Ms||t.includes(_s)||t.includes($s):!1}function yo(t){return t?/^OpenClaw agent changes:/i.test(t.trim()):!1}function qn(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} ${ql(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("---",Ms),e.join(`
31
+ `)}var Bl,Ms,_s,$s,nh,Es=J(()=>{ft();Bl=32,Ms="Generated with [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)",_s="Deterministic fallback metadata generated because no LLM PR metadata provider is configured.",$s="Deterministic fallback metadata generated because the LLM PR metadata provider failed or returned unusable output.",nh="PR metadata generated from the coding agent's final session report."});var Jl={};Qc(Jl,{buildPrCompletionWakeOutcomeKey:()=>Ws,buildPrMetadata:()=>Fn,buildPrOutcomeDetailLines:()=>Ns,createRuntimePrMetadataProvider:()=>fo,discoverExistingTargetPr:()=>Hl,formatPrBody:()=>qn,isOcaFallbackPrBody:()=>ho,isOcaGeneratedPrBody:()=>go,isOcaGeneratedPrTitle:()=>yo,makeAgentPrTool:()=>Un,normalizeForceNewReplacementPrStatus:()=>Os,refreshOpenPrMetadata:()=>Ql,resolveExistingTargetPrUpdateBranch:()=>Gl,resolveExistingTargetPrUpdateSourceBranch:()=>zl,shouldIgnoreClosedTargetPrForForceNew:()=>jl});import{execFileSync as ko}from"child_process";import{existsSync as ch}from"fs";function ph(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function jl(t,e){return t===!0&&e?.exists===!0&&e.state!=="open"}function Os(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 mh(t,e){try{let n=ko("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 Vl(t,e,n){try{let r=mh(t,e);return r?(ko("git",["-C",r,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1}):(ke(t)===e?ko("git",["-C",t,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):ko("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 Gl(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,i=Kr(e,o),s=i??o;if(o===n&&!i)return{success:!0,branchName:n,alreadyRepresented:!1};if(!vt(e,o)&&!i)return{success:!1,error:`Target PR branch ${o} is not available locally. Fetch it before updating the PR.`};if(Se(e,n,s)){if(i&&!Se(e,i,o)&&Se(e,o,i)){let a=Vl(e,o,i);if("error"in a)return a}return{success:!0,branchName:o,alreadyRepresented:!!i}}return ke(e)===o&&Se(e,s,o)&&Se(e,n,o)?{success:!0,branchName:o,alreadyRepresented:!1}:Se(e,s,n)?Vl(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 Hl(t){let e=ke(t.repoDir);if(!e||e!==t.expectedParentBranch||e===t.worktreeBranch||e===t.baseBranch)return;let n=be(t.repoDir,e,t.targetRepo);return n.exists&&n.state==="open"&&n.headRefName===e&&(!n.baseRefName||n.baseRefName===t.baseBranch)?n:void 0}function zl(t){let e=t.targetPrStatus.headRefName;if(!e||e===t.fallbackBranch)return t.fallbackBranch;let n=ke(t.repoDir);return n===e?n:t.fallbackBranch}function Ns(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 Ws(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 Ql(t){let e=t.prStatus.number??t.prStatus.url;if(!e)return{status:"skipped",reason:"missing-pr-identity"};let n=t.operations?.getBody??il,r=t.operations?.updateBody??sl,o=t.operations?.updateTitle??al;if(t.explicitTitle!==void 0||t.explicitBody!==void 0){let m=t.explicitTitle===void 0?!1:o(t.repoDir,e,t.explicitTitle,t.targetRepo);if(t.explicitTitle!==void 0&&!m)return{status:"failed",reason:"failed to update explicit PR title"};let c=t.explicitBody===void 0?!1:r(t.repoDir,e,t.explicitBody,t.targetRepo);return t.explicitBody!==void 0&&!c?{status:"failed",reason:"failed to update explicit PR body"}:{status:"updated",updatedTitle:m,updatedBody:c,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||go(s)))return{status:"skipped",reason:"human-edited"};let d=await Fn({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,outputPreview:t.outputPreview,diffSummary:t.diffSummary,provider:t.metadataProvider});if(d.ok===!1)return{status:"failed",reason:d.error};let l=d.evidence.sessionSummary.length>0||d.evidence.sessionChanges.length>0;if(d.fallbackReason!==void 0&&(!l||!ho(s)))return{status:"failed",reason:"generated PR metadata was unavailable; preserved existing generated PR metadata"};let u=qn({sessionName:t.sessionName,metadata:d.metadata,diffSummary:t.diffSummary}),f=t.forceRefresh||yo(t.prStatus.title),p=!1;if(f&&t.prStatus.title?.trim()!==d.metadata.title.trim()&&(p=o(t.repoDir,e,d.metadata.title,t.targetRepo),!p))return{status:"failed",reason:"failed to update generated PR title"};if(u.trim()===s.trim())return p?{status:"updated",updatedTitle:p,updatedBody:!1,reason:t.forceRefresh?"forced":"generated"}:{status:"skipped",reason:"unchanged"};let k=r(t.repoDir,e,u,t.targetRepo);return k?{status:"updated",updatedTitle:p,updatedBody:k,reason:t.forceRefresh?"forced":"generated"}:{status:"failed",reason:"failed to update generated PR body"}}function Ds(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 Un(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(!ph(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(!he())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=tn(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"}};ch(a)||`${a}${u}${d}`;let f=r.base_branch??Le(d),p=e.metadataProvider??fo(),k=R=>{let _=Nl({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??f,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:R.prUrl,prNumber:R.prNumber,baseBranch:f,targetRepo:R.targetRepo,disposition:R.disposition});for(let F of On(o))v.updatePersistedSession(F,_)},m=Tn(d,r.target_repo??s?.worktreePrTargetRepo),c=s?.worktreePrUrl??i?.worktreePrUrl,y=c?Qe(d,c,m):void 0;if(c&&!y?.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=jl(r.force_new,y),b=S?void 0:c,x=!c&&!r.force_new?Hl({repoDir:d,worktreeBranch:u,expectedParentBranch:s?.worktreeParentBranch??i?.worktreeParentBranch,baseBranch:f,targetRepo:m}):void 0,T=S?void 0:y??x,A=b??x?.url,h=!1;if(T?.exists&&T.state==="open"){let R=zl({repoDir:d,fallbackBranch:u,targetPrStatus:T}),_=Gl({repoDir:d,sourceBranch:R,targetPrStatus:T});if("error"in _)return{content:[{type:"text",text:`Error: ${_.error}`}],meta:{success:!1,state:"error"}};u=_.branchName,h=_.alreadyRepresented}let w=v.resolveRepoPolicy(d),L=Os(T?.exists?T:be(d,u,m),y,{forceNewIgnoresClosedTargetPr:S}),K=L.exists&&L.state==="open";if(w?.policy==="never-pr"&&!K)return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${w.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};if(w&&!w.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${w.identity?.repoRoot??d}. Provider: ${w.provider}.`}],meta:{success:!1,state:"error"}};if((!T||T.state==="open")&&!h&&!Hr(d,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let I=Os(A?Qe(d,A,m):be(d,u,m),y,{forceNewIgnoresClosedTargetPr:S});if(r.force_new&&I.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${I.state}).
32
32
 
33
33
  Existing PR: ${I.url}
34
34
 
35
35
  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(I.exists&&I.state==="open"){let R=He(d,u,f),_=await Ql({repoDir:d,prStatus:I,targetRepo:m,sessionName:l,branchName:u,prompt:o.prompt,outputPreview:o.outputPreview,diffSummary:R,explicitTitle:r.title,explicitBody:r.body,forceRefresh:r.update_body===!0||r.update_metadata===!0,metadataProvider:p});if(R&&R.commits>0){let F=R.commitMessages.slice(0,5).map(Y=>`• ${Y.hash} ${Y.message} (${Y.author})`).join(`
36
36
  `),N=R.commits>5?`
37
37
  ...and ${R.commits-5} more commits`:"",B=["🔄 **New commits pushed**","",`${R.commits} new commits (+${R.insertions} / -${R.deletions})`,"","### Latest commits:",F+N,"","---","🤖 [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)"].join(`
38
- `);if(dl(d,I.number,B,m)){k({prUrl:I.url,prNumber:I.number,targetRepo:m});let Y=bt({kind:"pr-updated",branch:u,prUrl:I.url,filesChanged:R.filesChanged,insertions:R.insertions,deletions:R.deletions});return v.notifyWorktreeOutcome(o.notificationTarget,Y,{completionWakeOutcomeKey:Os({action:"updated",branchName:u,prUrl:I.url,prNumber:I.number,targetRepo:m,diffSummary:R}),detailLines:Ds({action:"updated",branchName:u,baseBranch:f,prUrl:I.url,prNumber:I.number,targetRepo:m,commits:R.commits,insertions:R.insertions,deletions:R.deletions})}),{content:[{type:"text",text:[`${Y}`,"",`📝 Added comment detailing ${R.commits} new commits (+${R.insertions} / -${R.deletions})`,$s(_)].filter(Boolean).join(`
39
- `)}],meta:{success:!0,state:"pr_updated"}}}else{let Y=$s(_);return{content:[{type:"text",text:`⚠️ Pushed to ${I.url} but failed to add comment.
38
+ `);if(dl(d,I.number,B,m)){k({prUrl:I.url,prNumber:I.number,targetRepo:m});let Y=bt({kind:"pr-updated",branch:u,prUrl:I.url,filesChanged:R.filesChanged,insertions:R.insertions,deletions:R.deletions});return v.notifyWorktreeOutcome(o.notificationTarget,Y,{completionWakeOutcomeKey:Ws({action:"updated",branchName:u,prUrl:I.url,prNumber:I.number,targetRepo:m,diffSummary:R}),detailLines:Ns({action:"updated",branchName:u,baseBranch:f,prUrl:I.url,prNumber:I.number,targetRepo:m,commits:R.commits,insertions:R.insertions,deletions:R.deletions})}),{content:[{type:"text",text:[`${Y}`,"",`📝 Added comment detailing ${R.commits} new commits (+${R.insertions} / -${R.deletions})`,Ds(_)].filter(Boolean).join(`
39
+ `)}],meta:{success:!0,state:"pr_updated"}}}else{let Y=Ds(_);return{content:[{type:"text",text:`⚠️ Pushed to ${I.url} but failed to add comment.
40
40
 
41
41
  ${R.commits} new commits (+${R.insertions} / -${R.deletions})${Y?`
42
- ${Y}`:""}`}],meta:{success:!0,state:"pr_open"}}}}else{k({prUrl:I.url,prNumber:I.number,targetRepo:m});let F=$s(_);return{content:[{type:"text",text:`ℹ️ PR already exists and is up to date: ${I.url}
42
+ ${Y}`:""}`}],meta:{success:!0,state:"pr_open"}}}}else{k({prUrl:I.url,prNumber:I.number,targetRepo:m});let F=Ds(_);return{content:[{type:"text",text:`ℹ️ PR already exists and is up to date: ${I.url}
43
43
 
44
44
  No new commits to push.${F?`
45
45
  ${F}`:""}`}],meta:{success:!0,state:"pr_open"}}}}else if(I.exists&&I.state==="merged"){let R={...en({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??f,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{resolutionSource:"agent_pr",clearResolverSessionId:!0}),worktreePrUrl:I.url,worktreePrNumber:I.number,worktreeDisposition:"merged",worktreeDecisionSnoozedUntil:void 0};for(let _ of On(o))v.updatePersistedSession(_,R);return{content:[{type:"text",text:`✅ PR was already merged: ${I.url}
@@ -52,200 +52,200 @@ What would you like to do?
52
52
  2. Close and delete the branch with agent_merge(delete_branch=true), then start a new session/worktree
53
53
  3. Manually delete the closed PR on GitHub, then call agent_pr(force_new=true) to create a fresh PR
54
54
 
55
- (This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{if(w?.policy==="never-pr")return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${w.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};let R=!r.title||!r.body?He(d,u,f):void 0,_;if(!r.title||!r.body){let Q=await Fn({sessionName:l,branchName:u,prompt:o.prompt,outputPreview:o.outputPreview,diffSummary:R,provider:p});if(Q.ok===!1)return{content:[{type:"text",text:`❌ ${Q.error}`}],meta:{success:!1,state:"error"}};_=Q.metadata}let F=r.title??_.title,N=r.body;N||(N=qn({sessionName:l,metadata:_,diffSummary:R}));let B=ol(d,u,f,F,N,m,{draft:!0});if(B.success&&B.prUrl){let Q=be(d,u,m);k({prUrl:B.prUrl,prNumber:Q.number,targetRepo:m,disposition:"pr-opened"});let Y=bt({kind:"pr-opened",branch:u,targetRepo:m,prUrl:B.prUrl});return v.notifyWorktreeOutcome(o.notificationTarget,Y,{completionWakeOutcomeKey:Os({action:"opened",branchName:u,prUrl:B.prUrl,prNumber:Q.number,targetRepo:m}),detailLines:Ds({action:"opened",branchName:u,baseBranch:f,prUrl:B.prUrl,prNumber:Q.number,targetRepo:m})}),{content:[{type:"text",text:B.warnings&&B.warnings.length>0?`${Y}
55
+ (This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{if(w?.policy==="never-pr")return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${w.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};let R=!r.title||!r.body?He(d,u,f):void 0,_;if(!r.title||!r.body){let Q=await Fn({sessionName:l,branchName:u,prompt:o.prompt,outputPreview:o.outputPreview,diffSummary:R,provider:p});if(Q.ok===!1)return{content:[{type:"text",text:`❌ ${Q.error}`}],meta:{success:!1,state:"error"}};_=Q.metadata}let F=r.title??_.title,N=r.body;N||(N=qn({sessionName:l,metadata:_,diffSummary:R}));let B=ol(d,u,f,F,N,m,{draft:!0});if(B.success&&B.prUrl){let Q=be(d,u,m);k({prUrl:B.prUrl,prNumber:Q.number,targetRepo:m,disposition:"pr-opened"});let Y=bt({kind:"pr-opened",branch:u,targetRepo:m,prUrl:B.prUrl});return v.notifyWorktreeOutcome(o.notificationTarget,Y,{completionWakeOutcomeKey:Ws({action:"opened",branchName:u,prUrl:B.prUrl,prNumber:Q.number,targetRepo:m}),detailLines:Ns({action:"opened",branchName:u,baseBranch:f,prUrl:B.prUrl,prNumber:Q.number,targetRepo:m})}),{content:[{type:"text",text:B.warnings&&B.warnings.length>0?`${Y}
56
56
 
57
- ⚠️ ${B.warnings.join("; ")}`:Y}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${B.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var So=J(()=>{se();V();Re();_s();Dn();Nn();_s()});import{readdirSync as av,statSync as dv,rmSync as lv}from"fs";import{execFileSync as uv}from"child_process";import{join as ga}from"path";var ka={name:"openclaw-code-agent",version:"4.7.1",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.7.1",pluginSdkVersion:"2026.7.1"}},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.7.1",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 Ip}from"node:child_process";import{mkdirSync as xp,readFileSync as Tp,renameSync as Cp,writeFileSync as Mp}from"node:fs";import{dirname as _p,join as $p}from"node:path";import{promisify as Ep}from"node:util";import*as Ta from"child_process";import{createHash as Yc}from"crypto";var re="code-agent";var Zc=new Set(["1","true","yes","on"]);function wi(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&Zc.has(t))}function Ie(t){if(!(typeof t!="string"||t.length===0))return Yc("sha256").update(t).digest("hex").slice(0,12)}function Sa(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function X(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=Sa(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>Ie(Sa(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 wa(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 Pa(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 Pi(t){let e=Pa(t);return{presentationBlockTypes:wa(t),...X(e)}}function bi(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:wa(n),...va("interactive",X(Pa(n))),...va("telegramChannelData",X(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function ba(t){let e=et(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:vi(e.messageId),chatId:vi(e.chatId),telegramThreadId:vi(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function vi(t){return typeof t=="string"||typeof t=="number"?t:void 0}function va(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(!wi())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:re,...n})}`}ft();var Ia=5e3,Ca=64,Xc={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},ep={execFile:Ta.execFile},nt=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},Dt=class{constructor(e=ep.execFile){this.execFile=e}execFile;async send(e,n,r){U("direct_send_started",{...xe(e),messageTextLength:n.length,...X(r)});try{await this.sendViaRuntime(e,n,r),U("direct_send_succeeded",{...xe(e),deliveryPath:"runtime",...X(r)});return}catch(o){if(!(o instanceof nt))throw U("direct_send_failed",{...xe(e),deliveryPath:"runtime",...X(r),error:Ai(o)}),o;U("direct_send_runtime_capability_missing",{...xe(e),deliveryPath:"runtime",...X(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),U("direct_send_succeeded",{...xe(e),deliveryPath:"cli-fallback",...X(r)})}}async sendViaRuntime(e,n,r){let o=tt(),i=Aa(),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=${Ii(o)})`);if(!o.channel.outbound)throw new nt(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${Ii(o)})`);if(!s)throw new nt(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${Ii(o)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let d=er(r);if(U("runtime_adapter_loaded",{...xe(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...X(r),...d?Pi(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=np(i),a={text:o,presentation:i,interactive:s};U("presentation_render_started",{...xe(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Pi(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=op(l,s,r.channel);if(U("presentation_render_completed",{...xe(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...bi(u)}),!u||typeof u!="object"||!e.sendPayload)throw new Error(`OpenClaw outbound adapter for channel "${r.channel}" cannot preserve interactive presentation`);let f=await e.sendPayload({...d,payload:u});U("presentation_send_payload_completed",{...xe(r),...bi(u),...ba(f)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let a=tp(e,n,r);U("direct_send_cli_fallback_started",{...xe(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...X(r)}),this.execFile("openclaw",a,{timeout:Ia,killSignal:"SIGKILL"},(d,l,u)=>{if(!d){U("direct_send_cli_fallback_completed",{...xe(e),deliveryPath:"cli-fallback",...X(r)}),i();return}let f=u?.trim()?` | stderr: ${u.trim()}`:"";U("direct_send_cli_fallback_failed",{...xe(e),deliveryPath:"cli-fallback",...X(r),error:Ai(d),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${Ia}ms timeout: ${Ai(d)}${f}`))})})}};function xe(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function tp(t,e,n){let r=er(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 Ai(t){return t instanceof Error?t.message:String(t)}function Ii(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function er(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:up(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function np(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 rp(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 op(t,e,n){if(!e)return t;let r=rp(t)?t:ip(t,e);return n!=="telegram"?r:sp(r,e)}function ip(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function sp(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Ot(n.channelData),o=Ot(r?.telegram),i=dp(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=ap(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function ap(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")<=Ca).map(r=>({text:r.label,callback_data:r.value,...Ma(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function dp(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")>Ca))&&lp(i))return{...i,...Ma(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function lp(t){return Xn(t.callback_data)||Xn(t.url)||Zn(t.web_app)||Zn(t.webApp)||Zn(t.login_url)||Zn(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||Ot(t.switch_inline_query_chosen_chat)!==void 0||Ot(t.callback_game)!==void 0||t.pay===!0||xa(t.copy_text)||xa(t.copyText)}function Xn(t){return typeof t=="string"&&t.trim().length>0}function Zn(t){let e=Ot(t);return Xn(e?.url)}function xa(t){let e=Ot(t);return Xn(e?.text)}function Ma(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=Xc[e];return n?{style:n}:{}}function Ot(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function up(t){return t.startsWith(`${re}:`)?t:`${re}:${t}`}ae();ye();var Dp=Ep(Ip),Oi="openclaw-code-agent",Op=`https://registry.npmjs.org/${encodeURIComponent(Oi)}/latest`,Np="openclaw-code-agent-auto-update.json",qa=1440*60*1e3,Wp=7*qa,Bt="plugin:auto-update";function Ua(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Wa(t){return t instanceof Error?t.message:String(t)}function ht(t){return t?.trim().replace(/^v/i,"")||void 0}function La(t){let n=ht(t)?.match(/^(\d+)\.(\d+)\.(\d+)$/);if(!(!n?.[1]||!n[2]||!n[3]))return[Number(n[1]),Number(n[2]),Number(n[3])]}function Lp(t,e){let n=La(t),r=La(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 Bp(t){if(!Ua(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 Ba(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 Fa(){if(D.fallbackChannel)return _e(D.fallbackChannel)}async function Fp(){let t=await fetch(Op,{headers:{accept:"application/json"}});if(!t.ok)throw new Error(`npm registry returned HTTP ${t.status}`);let e=await t.json(),n=Ua(e)&&typeof e.version=="string"?ht(e.version):void 0;return n?{version:n}:void 0}async function qp(t,e){let n=await Dp(t,e,{timeout:12e4,maxBuffer:1048576});return{stdout:n.stdout?.toString()??"",stderr:n.stderr?.toString()??""}}var rr=class{constructor(e){this.options=e;this.statePath=$p(e.stateDir,Np),this.notifier=e.notifier??new Dt,this.fetchLatestRelease=e.fetchLatestRelease??Fp,this.runCommand=e.runCommand??qp,this.now=e.now??Date.now}options;statePath;notifier;fetchLatestRelease;runCommand;now;checkInFlight;maybeCheckForUpdate(e={}){this.checkInFlight||(this.checkInFlight=this.checkForUpdate(e).catch(n=>{`${Wa(n)}`}).finally(()=>{this.checkInFlight=void 0}))}async waitForIdle(){await this.checkInFlight}async installConfirmed(e,n){let r=ht(e);if(!r)return"Could not determine which OCA version to update to.";await this.runCommand("openclaw",["plugins","update",Oi]);let o=this.readState();this.writeState({...o,updateInstalledVersion:r});let i=Ba(n?.route??Fa());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(`
58
- `)}async restartConfirmed(e){let n=ht(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=ht(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<qa){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=ht(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:Wa(s)}),s}}async promptFromState(e,n){let r=ht(e.latestVersion);if(!Lp(r,this.options.currentVersion)||!this.shouldPromptForVersion(e,r))return;let o=Ba(n.route??Fa());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 ${Oi}`,"If the update succeeds, OCA will ask separately before restarting the Gateway."].join(`
57
+ ⚠️ ${B.warnings.join("; ")}`:Y}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${B.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var So=J(()=>{se();V();Re();Es();Dn();Nn();Es()});import{readdirSync as dv,statSync as lv,rmSync as uv}from"fs";import{execFileSync as cv}from"child_process";import{join as ya}from"path";var va={name:"openclaw-code-agent",version:"4.7.2",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.7.1"},compat:{pluginApi:">=2026.4.21",minGatewayVersion:"2026.4.21"},build:{openclawVersion:"2026.7.1",pluginSdkVersion:"2026.7.1"}},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.7.1",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",provenance:!0},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 Ip}from"node:child_process";import{mkdirSync as xp,readFileSync as Tp,renameSync as Cp,writeFileSync as Mp}from"node:fs";import{dirname as _p,join as $p}from"node:path";import{promisify as Ep}from"node:util";import*as Ma from"child_process";import{createHash as Yc}from"crypto";var re="code-agent";var Zc=new Set(["1","true","yes","on"]);function wi(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&Zc.has(t))}function Ie(t){if(!(typeof t!="string"||t.length===0))return Yc("sha256").update(t).digest("hex").slice(0,12)}function wa(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function X(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=wa(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>Ie(wa(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 ba(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 Ra(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 Pi(t){let e=Ra(t);return{presentationBlockTypes:ba(t),...X(e)}}function bi(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:ba(n),...Pa("interactive",X(Ra(n))),...Pa("telegramChannelData",X(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function Aa(t){let e=et(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:vi(e.messageId),chatId:vi(e.chatId),telegramThreadId:vi(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function vi(t){return typeof t=="string"||typeof t=="number"?t:void 0}function Pa(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(!wi())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:re,...n})}`}ft();var Ta=5e3,_a=64,Xc={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},ep={execFile:Ma.execFile},nt=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},Dt=class{constructor(e=ep.execFile){this.execFile=e}execFile;async send(e,n,r){U("direct_send_started",{...xe(e),messageTextLength:n.length,...X(r)});try{await this.sendViaRuntime(e,n,r),U("direct_send_succeeded",{...xe(e),deliveryPath:"runtime",...X(r)});return}catch(o){if(!(o instanceof nt))throw U("direct_send_failed",{...xe(e),deliveryPath:"runtime",...X(r),error:Ai(o)}),o;U("direct_send_runtime_capability_missing",{...xe(e),deliveryPath:"runtime",...X(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),U("direct_send_succeeded",{...xe(e),deliveryPath:"cli-fallback",...X(r)})}}async sendViaRuntime(e,n,r){let o=tt(),i=xa(),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=${Ii(o)})`);if(!o.channel.outbound)throw new nt(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${Ii(o)})`);if(!s)throw new nt(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${Ii(o)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let d=er(r);if(U("runtime_adapter_loaded",{...xe(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...X(r),...d?Pi(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=np(i),a={text:o,presentation:i,interactive:s};U("presentation_render_started",{...xe(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Pi(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=op(l,s,r.channel);if(U("presentation_render_completed",{...xe(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...bi(u)}),!u||typeof u!="object"||!e.sendPayload)throw new Error(`OpenClaw outbound adapter for channel "${r.channel}" cannot preserve interactive presentation`);let f=await e.sendPayload({...d,payload:u});U("presentation_send_payload_completed",{...xe(r),...bi(u),...Aa(f)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let a=tp(e,n,r);U("direct_send_cli_fallback_started",{...xe(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...X(r)}),this.execFile("openclaw",a,{timeout:Ta,killSignal:"SIGKILL"},(d,l,u)=>{if(!d){U("direct_send_cli_fallback_completed",{...xe(e),deliveryPath:"cli-fallback",...X(r)}),i();return}let f=u?.trim()?` | stderr: ${u.trim()}`:"";U("direct_send_cli_fallback_failed",{...xe(e),deliveryPath:"cli-fallback",...X(r),error:Ai(d),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${Ta}ms timeout: ${Ai(d)}${f}`))})})}};function xe(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function tp(t,e,n){let r=er(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 Ai(t){return t instanceof Error?t.message:String(t)}function Ii(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function er(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:up(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function np(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 rp(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 op(t,e,n){if(!e)return t;let r=rp(t)?t:ip(t,e);return n!=="telegram"?r:sp(r,e)}function ip(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function sp(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Ot(n.channelData),o=Ot(r?.telegram),i=dp(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=ap(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function ap(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")<=_a).map(r=>({text:r.label,callback_data:r.value,...$a(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function dp(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")>_a))&&lp(i))return{...i,...$a(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function lp(t){return Xn(t.callback_data)||Xn(t.url)||Zn(t.web_app)||Zn(t.webApp)||Zn(t.login_url)||Zn(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||Ot(t.switch_inline_query_chosen_chat)!==void 0||Ot(t.callback_game)!==void 0||t.pay===!0||Ca(t.copy_text)||Ca(t.copyText)}function Xn(t){return typeof t=="string"&&t.trim().length>0}function Zn(t){let e=Ot(t);return Xn(e?.url)}function Ca(t){let e=Ot(t);return Xn(e?.text)}function $a(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=Xc[e];return n?{style:n}:{}}function Ot(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function up(t){return t.startsWith(`${re}:`)?t:`${re}:${t}`}ae();ye();var Dp=Ep(Ip),Ni="openclaw-code-agent",Op=`https://registry.npmjs.org/${encodeURIComponent(Ni)}/latest`,Np="openclaw-code-agent-auto-update.json",qa=1440*60*1e3,Wp=7*qa,Lp=1e4,Bt="plugin:auto-update";function Ua(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Oi(t){return t instanceof Error?t.message:String(t)}function ht(t){return t?.trim().replace(/^v/i,"")||void 0}function Wi(t){let n=ht(t)?.match(/^((?:0|[1-9]\d*))\.((?:0|[1-9]\d*))\.((?:0|[1-9]\d*))$/);if(!n?.[1]||!n[2]||!n[3])return;let r=[Number(n[1]),Number(n[2]),Number(n[3])];return r.every(Number.isSafeInteger)?r:void 0}function Bp(t,e){let n=Wi(t),r=Wi(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 Fp(t){if(!Ua(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 Ba(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 Fa(){if(D.fallbackChannel)return _e(D.fallbackChannel)}async function qp(){let t=await fetch(Op,{headers:{accept:"application/json"},signal:AbortSignal.timeout(Lp)});if(!t.ok)throw new Error(`npm registry returned HTTP ${t.status}`);let e=await t.json(),n=Ua(e)&&typeof e.version=="string"?ht(e.version):void 0;return n?{version:n}:void 0}async function Up(t,e){let n=await Dp(t,e,{timeout:12e4,maxBuffer:1048576});return{stdout:n.stdout?.toString()??"",stderr:n.stderr?.toString()??""}}var rr=class{constructor(e){this.options=e;this.statePath=$p(e.stateDir,Np),this.notifier=e.notifier??new Dt,this.fetchLatestRelease=e.fetchLatestRelease??qp,this.runCommand=e.runCommand??Up,this.now=e.now??Date.now}options;statePath;notifier;fetchLatestRelease;runCommand;now;checkInFlight;maybeCheckForUpdate(e={}){this.checkInFlight||(this.checkInFlight=this.checkForUpdate(e).catch(n=>{`${Oi(n)}`}).finally(()=>{this.checkInFlight=void 0}))}async waitForIdle(){await this.checkInFlight}async installConfirmed(e,n){let r=ht(e);if(!r||!Wi(r))return"Could not determine which stable OCA version to update to.";await this.runCommand("openclaw",["plugins","update",`${Ni}@${r}`]);let o=this.readState();this.writeState({...o,updateInstalledVersion:r});let i=Ba(n?.route??Fa());if(i)try{return await this.sendRestartPrompt(i,r),`OCA update command completed for ${r}. Restart confirmation was sent.`}catch(s){`${r}${Oi(s)}`}return[`OCA update command completed for ${r}.`,"Restart the Gateway explicitly to load it: openclaw gateway restart"].join(`
58
+ `)}async restartConfirmed(e){let n=ht(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=ht(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<qa){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=ht(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:Oi(s)}),s}}async promptFromState(e,n){let r=ht(e.latestVersion);if(!Bp(r,this.options.currentVersion)||!this.shouldPromptForVersion(e,r))return;let o=Ba(n.route??Fa());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 ${Ni}@${n}`,"If the update succeeds, OCA will ask separately before restarting the Gateway."].join(`
59
59
  `),[[this.options.actionButtonFactory(Bt,"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(Bt,"plugin-update-remind-later","Remind later",{pluginUpdateVersion:n}),this.options.actionButtonFactory(Bt,"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)>=Wp}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(`
60
- `),[[this.options.actionButtonFactory(Bt,"plugin-update-restart","Restart Gateway",{pluginUpdateVersion:n}),this.options.actionButtonFactory(Bt,"plugin-update-remind-later","Remind later",{pluginUpdateVersion:n}),this.options.actionButtonFactory(Bt,"plugin-update-dismiss","Dismiss",{pluginUpdateVersion:n})]]),this.writeState({...this.readState(),restartPromptedVersion:n})}readState(){try{return Bp(JSON.parse(Tp(this.statePath,"utf-8")))}catch{return{}}}writeState(e){xp(_p(this.statePath),{recursive:!0});let n=`${this.statePath}.tmp`;Mp(n,JSON.stringify(e,null,2),"utf-8"),Cp(n,this.statePath)}};se();V();function Vp(t){return t.length>80?`${t.slice(0,80)}...`:t}function jp(t){return t.worktreePath?!t.originalWorkdir||t.originalWorkdir===t.worktreePath?`${t.worktreePath} (worktree)`:`${t.worktreePath} (worktree of ${t.originalWorkdir})`:t.workdir}function Gp(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: ${jp(t)}`,` Model: ${t.model??"default"}`,` Prompt: "${Vp(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(`
61
- `)}function or(t,e){return Gp({...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 ir(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}`}ae();function Ft(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}}ne();function br(t){return"id"in t?t.id:t.sessionId}function In(t){return t.status==="completed"||t.killReason==="done"}function rf(t){return!In(t)||!O(t)?!1:t.backendRef?.kind==="codex-app-server"||t.backendRef?.kind==="opencode-server"}function of(t){return(t.killReason==="shutdown"||t.killReason==="startup-timeout")&&!O(t)}function kt(t){if(t.status==="running")return{kind:"direct",reason:"already_running"};let e=br(t);if(In(t)&&!rf(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}=Ft({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 of(t)?{kind:"relaunch",stableSessionId:e}:{kind:"unavailable",reason:"missing_backend_state",stableSessionId:e}}ae();hr();import{existsSync as Id}from"fs";ne();function bd(t){return t==null?void 0:String(t).trim()||void 0}function sf(t){return t.trim().replace(/^['"`](.*)['"`]$/s,"$1").trim()}function af(t){let e=t.split(/\n\s*\n/,1)[0]?.split(`
62
- `).map(n=>n.trim()).filter(Boolean)??[];if(e.length!==0)for(let n of e){let r=n.match(/^(Workdir|Repo):\s*(.+)$/),o=sf(r?.[2]??"");if(o.startsWith("/")&&Id(o))return o}}function Rd(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&&bd(t.originThreadId)===bd(e.originThreadId)}function Ad(t){return t.slice(0,3).map(e=>` - ${e.name} [${e.ref}] | status=${e.status}${e.lifecycle?` | lifecycle=${e.lifecycle}`:""}`).join(`
63
- `)}function df(t,e){let n=[],r=[],o=new Set;for(let i of t.list?.("all")??[]){if(!Rd(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||!Rd(i,e))continue;let s=G(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 Rr(t,e,n){let r=t.workdir||af(t.prompt)||e.workspaceDir||D.defaultWorkdir||process.cwd();if(!Id(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=t.harness??me(),i=Nt(o),s=t.model??i,a=je(o,s),d=t.model!==void 0,l=tr(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&&!Gt(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&&!fr(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=gr(o,a,l),f=nr(e),p=yn(e,f||gt(r)),k=e.sessionKey||void 0,m=Na(k)??Di(e);if(!t.resume_session_id&&!t.force_new_session){let h=df(n,{workdir:r,originSessionKey:k,originChannel:p,originThreadId:m});if(h.resumable.length>0||h.active.length>0){let w=h.resumable.length>0?["Linked resumable session(s) already exist for this thread/workdir:",Ad(h.resumable),"","Resume the latest one with:",` agent_respond(session='${h.resumable[0].ref}', message='<next instruction>')`,"Fork from it with:",` agent_launch(prompt='<new task>', resume_session_id='${h.resumable[0].ref}', fork_session=true)`].join(`
60
+ `),[[this.options.actionButtonFactory(Bt,"plugin-update-restart","Restart Gateway",{pluginUpdateVersion:n}),this.options.actionButtonFactory(Bt,"plugin-update-remind-later","Remind later",{pluginUpdateVersion:n}),this.options.actionButtonFactory(Bt,"plugin-update-dismiss","Dismiss",{pluginUpdateVersion:n})]]),this.writeState({...this.readState(),restartPromptedVersion:n})}readState(){try{return Fp(JSON.parse(Tp(this.statePath,"utf-8")))}catch{return{}}}writeState(e){xp(_p(this.statePath),{recursive:!0});let n=`${this.statePath}.tmp`;Mp(n,JSON.stringify(e,null,2),"utf-8"),Cp(n,this.statePath)}};se();V();function jp(t){return t.length>80?`${t.slice(0,80)}...`:t}function Gp(t){return t.worktreePath?!t.originalWorkdir||t.originalWorkdir===t.worktreePath?`${t.worktreePath} (worktree)`:`${t.worktreePath} (worktree of ${t.originalWorkdir})`:t.workdir}function Hp(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: ${Gp(t)}`,` Model: ${t.model??"default"}`,` Prompt: "${jp(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(`
61
+ `)}function or(t,e){return Hp({...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 ir(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}`}ae();function Ft(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}}ne();function br(t){return"id"in t?t.id:t.sessionId}function In(t){return t.status==="completed"||t.killReason==="done"}function of(t){return!In(t)||!O(t)?!1:t.backendRef?.kind==="codex-app-server"||t.backendRef?.kind==="opencode-server"}function sf(t){return(t.killReason==="shutdown"||t.killReason==="startup-timeout")&&!O(t)}function kt(t){if(t.status==="running")return{kind:"direct",reason:"already_running"};let e=br(t);if(In(t)&&!of(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}=Ft({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 sf(t)?{kind:"relaunch",stableSessionId:e}:{kind:"unavailable",reason:"missing_backend_state",stableSessionId:e}}ae();hr();import{existsSync as Id}from"fs";ne();function bd(t){return t==null?void 0:String(t).trim()||void 0}function af(t){return t.trim().replace(/^['"`](.*)['"`]$/s,"$1").trim()}function df(t){let e=t.split(/\n\s*\n/,1)[0]?.split(`
62
+ `).map(n=>n.trim()).filter(Boolean)??[];if(e.length!==0)for(let n of e){let r=n.match(/^(Workdir|Repo):\s*(.+)$/),o=af(r?.[2]??"");if(o.startsWith("/")&&Id(o))return o}}function Rd(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&&bd(t.originThreadId)===bd(e.originThreadId)}function Ad(t){return t.slice(0,3).map(e=>` - ${e.name} [${e.ref}] | status=${e.status}${e.lifecycle?` | lifecycle=${e.lifecycle}`:""}`).join(`
63
+ `)}function lf(t,e){let n=[],r=[],o=new Set;for(let i of t.list?.("all")??[]){if(!Rd(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||!Rd(i,e))continue;let s=G(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 Rr(t,e,n){let r=t.workdir||df(t.prompt)||e.workspaceDir||D.defaultWorkdir||process.cwd();if(!Id(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=t.harness??me(),i=Nt(o),s=t.model??i,a=je(o,s),d=t.model!==void 0,l=tr(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&&!Gt(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&&!fr(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=gr(o,a,l),f=nr(e),p=yn(e,f||gt(r)),k=e.sessionKey||void 0,m=La(k)??Di(e);if(!t.resume_session_id&&!t.force_new_session){let h=lf(n,{workdir:r,originSessionKey:k,originChannel:p,originThreadId:m});if(h.resumable.length>0||h.active.length>0){let w=h.resumable.length>0?["Linked resumable session(s) already exist for this thread/workdir:",Ad(h.resumable),"","Resume the latest one with:",` agent_respond(session='${h.resumable[0].ref}', message='<next instruction>')`,"Fork from it with:",` agent_launch(prompt='<new task>', resume_session_id='${h.resumable[0].ref}', fork_session=true)`].join(`
64
64
  `):"",L=h.active.length>0?[h.resumable.length>0?"Linked active session(s):":"Linked active session(s) already exist for this thread/workdir:",Ad(h.active),"","Send a follow-up instead of launching a duplicate:",` agent_respond(session='${h.active[0].ref}', message='<next instruction>')`].join(`
65
65
  `):"";return{kind:"blocked",text:["Resume-first protection blocked a fresh launch.","",w,L,["If you intentionally want a brand-new independent session here, call:"," agent_launch(prompt='<new task>', force_new_session=true)"].join(`
66
66
  `)].filter(Boolean).join(`
67
67
 
68
- `)}}}let c=t.resume_session_id,y=c?n.resolve?.(c):void 0,S=c?n.getPersistedSession?.(c):void 0;if(c){let h=n.resolveBackendConversationId?.(c)??n.resolveHarnessSessionId?.(c);if(!h)return{kind:"error",text:`Error: Could not resolve resume_session_id "${c}" to a session ID. Use agent_sessions to list available sessions.`};c=h}let{resumeSessionId:b,clearedPersistedCodexResume:x}=Ft({requestedResumeSessionId:c,activeSession:y?{harnessSessionId:y.backendConversationId??y.harnessSessionId}:void 0,persistedSession:S?{harness:S.harness,backendRef:S.backendRef}:void 0}),T=t.permission_mode??D.permissionMode,A=t.plan_approval??D.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:u,permissionMode:T,planApproval:A,originChannel:p,originThreadId:m,originSessionKey:k,route:Lt(e,p,k),resumeSessionId:b,resolvedResumeId:c,clearedPersistedCodexResume:x,reasoningEffort:rt(o),fastMode:Wt(o)}}ne();function at(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function We(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 lf=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 Td(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!lf.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var xd={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function uf(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 Cd(t){let e=xd[t.phase]??xd[t.status]??"❓",n=We(t.duration),r=t.multiTurn?"multi-turn":"single",o=t.prompt.length>80?t.prompt.slice(0,80)+"...":t.prompt,i=t.costUsd>0?` | $${t.costUsd.toFixed(2)}`:"",s=[`${e} ${t.name} [${t.id}] (${n}${i}) — ${r}`,` 📁 ${t.workdir}`,` 📝 "${o}"`];if(t.worktreePath&&t.worktreeBranch&&s.push(` 🌿 Worktree: ${t.worktreeBranch} ${uf(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=O(t);return a&&s.push(` 🔗 Backend ID: ${a}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
68
+ `)}}}let c=t.resume_session_id,y=c?n.resolve?.(c):void 0,S=c?n.getPersistedSession?.(c):void 0;if(c){let h=n.resolveBackendConversationId?.(c)??n.resolveHarnessSessionId?.(c);if(!h)return{kind:"error",text:`Error: Could not resolve resume_session_id "${c}" to a session ID. Use agent_sessions to list available sessions.`};c=h}let{resumeSessionId:b,clearedPersistedCodexResume:x}=Ft({requestedResumeSessionId:c,activeSession:y?{harnessSessionId:y.backendConversationId??y.harnessSessionId}:void 0,persistedSession:S?{harness:S.harness,backendRef:S.backendRef}:void 0}),T=t.permission_mode??D.permissionMode,A=t.plan_approval??D.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:u,permissionMode:T,planApproval:A,originChannel:p,originThreadId:m,originSessionKey:k,route:Lt(e,p,k),resumeSessionId:b,resolvedResumeId:c,clearedPersistedCodexResume:x,reasoningEffort:rt(o),fastMode:Wt(o)}}ne();function at(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function We(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 uf=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 Td(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!uf.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var xd={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function cf(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 Cd(t){let e=xd[t.phase]??xd[t.status]??"❓",n=We(t.duration),r=t.multiTurn?"multi-turn":"single",o=t.prompt.length>80?t.prompt.slice(0,80)+"...":t.prompt,i=t.costUsd>0?` | $${t.costUsd.toFixed(2)}`:"",s=[`${e} ${t.name} [${t.id}] (${n}${i}) — ${r}`,` 📁 ${t.workdir}`,` 📝 "${o}"`];if(t.worktreePath&&t.worktreeBranch&&s.push(` 🌿 Worktree: ${t.worktreeBranch} ${cf(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=O(t);return a&&s.push(` 🔗 Backend ID: ${a}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
69
69
  `)}function Ar(t,e){let n=t.sessionsWithDuration>0?t.totalDurationMs/t.sessionsWithDuration:0,{completed:r,failed:o,killed:i}=t.sessionsByStatus,s=["📊 OpenClaw Code Agent Stats","","📋 Sessions",` Launched: ${t.totalLaunched}`,` Running: ${e}`,` Completed: ${r}`,` Failed: ${o}`,` Killed: ${i}`,"",`⏱️ Average duration: ${n>0?We(n):"n/a"}`];if(t.mostExpensive){let a=t.mostExpensive;s.push("","🏆 Notable session",` ${a.name} [${a.id}]`,` 📝 "${a.prompt}"`)}return s.join(`
70
70
  `)}function ue(t,e){return e<=0?"":t.length<=e?t:e<=3?".".repeat(e):t.slice(0,e-3)+"..."}function Md(t,e){let n=t.split(`
71
71
  `),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(`
72
72
  `)}function _d(t,e){let n=t.split(`
73
73
  `),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(`
74
- `)}ft();var cf="openclaw-code-agent",pf=160,Ir={create(){},progress(){},finalize(){}};function xr(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function ns(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function mf(t){let e=t.prompt.trim().replace(/\s+/g," ");return ue(e||t.name,pf)}function $d(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 Ed(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 Tr(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 ff(t){return Cr(t.lifecycle)}function Cr(t){return t==="awaiting_plan_decision"||t==="awaiting_user_input"||t==="awaiting_worktree_decision"||t==="suspended"}function gf(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:Cr(e)}return t.lifecycle==="suspended"?t.resumable===!0:Cr(t.lifecycle)}function hf(t){if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;if(Cr(e))return e}return t.lifecycle}function ts(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 yf(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 Mr(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var rs=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:cf,goal:mf(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:ts(e,"created",n),createdAt:e.startedAt,updatedAt:r}),e.taskFlowMirror=this.flow,this.lastProgressKey=this.progressKey(e,n)}catch(o){xr("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=$d(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=ts(e,"progress",n),i=Date.now(),s=ff(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=Mr(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.lastProgressKey=r}catch(o){xr("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=Ed(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":Tr(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...ts(e,"terminal",r),terminalStatus:n,terminalSummary:Tr(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:Tr(e.status,e.killReason),updatedAt:o,endedAt:o});ns("finalize",s),this.flow=Mr(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.finalized=!0}catch(o){xr("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function kf(t){return t==="succeeded"||t==="failed"||t==="cancelled"||t==="lost"}function Sf(t){if(!t?.trim())return;let e=Ri()?.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 vf(t){return t.originSessionKey??t.route?.sessionKey}function wf(t){return t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"Lost after OCA restart without live process":Tr(t.status,t.killReason??"unknown")}function Dd(t){let e=t.taskFlowMirror?{...t.taskFlowMirror}:void 0;if(!e||kf(e.status))return;let n=Sf(vf(t));if(!n)return;let r=Date.now();if(gf(t)){let l=$d({status:t.status,lifecycle:hf(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 ns("reconcile-waiting",u),Mr(e,u)}let o=Ed({status:t.status,killReason:t.killReason??"unknown"})??"failed",i=wf(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 ns("reconcile-terminal",d),Mr(e,d)}function _r(t){if(!t.sessionKey?.trim())return Ir;try{let e=Ri()?.fromToolContext;if(typeof e!="function")return Ir;let n=e(t);return yf(n)?new rs(n):Ir}catch(e){return xr("resolve",e),Ir}}function Pf(t){return t instanceof Error?t.message:String(t)}function Od(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function bf(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function Rf(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function Af(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function Nd(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(!bf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=Rr(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:f,route:p,resumeSessionId:k,resolvedResumeId:m,clearedPersistedCodexResume:c,reasoningEffort:y,fastMode:S}=r,b=n.resume_session_id?v.resolve(n.resume_session_id)??v.getPersistedSession(n.resume_session_id):void 0,x=!n.fork_session&&b?kt(b):void 0;if(x?.kind==="direct")return{content:[{type:"text",text:`Session ${b.name} [${Od(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(x?.kind==="unavailable")return{content:[{type:"text",text:`Resume unavailable for session ${b.name} [${Od(b,n.resume_session_id)}] (${x.reason}). Use agent_launch(prompt='<new task>') for a fresh session or set fork_session=true to fork from prior context.`}]};let T=b&&"resumedFromSessionName"in b?b.resumedFromSessionName:void 0,A=x?.kind==="resume"&&!n.fork_session?T??b?.name:void 0,h=A&&!n.name?A:n.name,w=n.worktree_strategy??D.defaultWorktreeStrategy??"off",L=n.fork_session?void 0:x?.kind==="resume"||x?.kind==="relaunch"?x.stableSessionId:void 0;if(w!=="off"&&Af(v)&&v.checkRepoPolicyForLaunch(o,n.worktree_strategy).ok===!1)return{content:[{type:"text",text:v.requestRepoPolicyForLaunch({route:p,prompt:n.prompt,workdir:o,name:h,model:s,reasoningEffort:y,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:k,resumedFromSessionName:A,resumeWorktreeFrom:m,sessionIdOverride:L,clearedPersistedCodexResume:c,forkSession:k?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 K=v.spawn({prompt:n.prompt,sessionIdOverride:L,name:h,workdir:o,model:s,reasoningEffort:y,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:k,resumedFromSessionName:A,resumeWorktreeFrom:m,forkSession:k?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:f,route:p,harness:i,taskLifecycle:_r(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:Rf(v)?v.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:d,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,resumeSessionName:A,forkSession:n.fork_session,clearedPersistedCodexResume:c},K):or({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:d,resumeSessionId:n.resume_session_id,resumeSessionName:A,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:c},{id:K.id,name:K.name,model:K.model,reasoningEffort:K.reasoningEffort??rt(i),fastMode:K.fastMode??S,worktreeStrategy:K.worktreeStrategy??n.worktree_strategy??D.defaultWorktreeStrategy??"off",repoIntegrationPolicy:K.repoIntegrationPolicy,repoProvider:K.repoProvider,worktreePath:K.worktreePath,originalWorkdir:K.originalWorkdir})}]}}catch(r){let o=Pf(r),i=o.includes("Max sessions")?"":`
74
+ `)}ft();var pf="openclaw-code-agent",mf=160,Ir={create(){},progress(){},finalize(){}};function xr(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function os(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function ff(t){let e=t.prompt.trim().replace(/\s+/g," ");return ue(e||t.name,mf)}function $d(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 Ed(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 Tr(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 gf(t){return Cr(t.lifecycle)}function Cr(t){return t==="awaiting_plan_decision"||t==="awaiting_user_input"||t==="awaiting_worktree_decision"||t==="suspended"}function hf(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:Cr(e)}return t.lifecycle==="suspended"?t.resumable===!0:Cr(t.lifecycle)}function yf(t){if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;if(Cr(e))return e}return t.lifecycle}function rs(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 kf(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 Mr(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var is=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:pf,goal:ff(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:rs(e,"created",n),createdAt:e.startedAt,updatedAt:r}),e.taskFlowMirror=this.flow,this.lastProgressKey=this.progressKey(e,n)}catch(o){xr("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=$d(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=rs(e,"progress",n),i=Date.now(),s=gf(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=Mr(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.lastProgressKey=r}catch(o){xr("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=Ed(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":Tr(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...rs(e,"terminal",r),terminalStatus:n,terminalSummary:Tr(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:Tr(e.status,e.killReason),updatedAt:o,endedAt:o});os("finalize",s),this.flow=Mr(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.finalized=!0}catch(o){xr("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function Sf(t){return t==="succeeded"||t==="failed"||t==="cancelled"||t==="lost"}function vf(t){if(!t?.trim())return;let e=Ri()?.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 wf(t){return t.originSessionKey??t.route?.sessionKey}function Pf(t){return t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"Lost after OCA restart without live process":Tr(t.status,t.killReason??"unknown")}function Dd(t){let e=t.taskFlowMirror?{...t.taskFlowMirror}:void 0;if(!e||Sf(e.status))return;let n=vf(wf(t));if(!n)return;let r=Date.now();if(hf(t)){let l=$d({status:t.status,lifecycle:yf(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 os("reconcile-waiting",u),Mr(e,u)}let o=Ed({status:t.status,killReason:t.killReason??"unknown"})??"failed",i=Pf(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 os("reconcile-terminal",d),Mr(e,d)}function _r(t){if(!t.sessionKey?.trim())return Ir;try{let e=Ri()?.fromToolContext;if(typeof e!="function")return Ir;let n=e(t);return kf(n)?new is(n):Ir}catch(e){return xr("resolve",e),Ir}}function bf(t){return t instanceof Error?t.message:String(t)}function Od(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function Rf(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function Af(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function If(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function Nd(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(!Rf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=Rr(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:f,route:p,resumeSessionId:k,resolvedResumeId:m,clearedPersistedCodexResume:c,reasoningEffort:y,fastMode:S}=r,b=n.resume_session_id?v.resolve(n.resume_session_id)??v.getPersistedSession(n.resume_session_id):void 0,x=!n.fork_session&&b?kt(b):void 0;if(x?.kind==="direct")return{content:[{type:"text",text:`Session ${b.name} [${Od(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(x?.kind==="unavailable")return{content:[{type:"text",text:`Resume unavailable for session ${b.name} [${Od(b,n.resume_session_id)}] (${x.reason}). Use agent_launch(prompt='<new task>') for a fresh session or set fork_session=true to fork from prior context.`}]};let T=b&&"resumedFromSessionName"in b?b.resumedFromSessionName:void 0,A=x?.kind==="resume"&&!n.fork_session?T??b?.name:void 0,h=A&&!n.name?A:n.name,w=n.worktree_strategy??D.defaultWorktreeStrategy??"off",L=n.fork_session?void 0:x?.kind==="resume"||x?.kind==="relaunch"?x.stableSessionId:void 0;if(w!=="off"&&If(v)&&v.checkRepoPolicyForLaunch(o,n.worktree_strategy).ok===!1)return{content:[{type:"text",text:v.requestRepoPolicyForLaunch({route:p,prompt:n.prompt,workdir:o,name:h,model:s,reasoningEffort:y,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:k,resumedFromSessionName:A,resumeWorktreeFrom:m,sessionIdOverride:L,clearedPersistedCodexResume:c,forkSession:k?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 K=v.spawn({prompt:n.prompt,sessionIdOverride:L,name:h,workdir:o,model:s,reasoningEffort:y,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:k,resumedFromSessionName:A,resumeWorktreeFrom:m,forkSession:k?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:f,route:p,harness:i,taskLifecycle:_r(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:Af(v)?v.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:d,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,resumeSessionName:A,forkSession:n.fork_session,clearedPersistedCodexResume:c},K):or({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:d,resumeSessionId:n.resume_session_id,resumeSessionName:A,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:c},{id:K.id,name:K.name,model:K.model,reasoningEffort:K.reasoningEffort??rt(i),fastMode:K.fastMode??S,worktreeStrategy:K.worktreeStrategy??n.worktree_strategy??D.defaultWorktreeStrategy??"off",repoIntegrationPolicy:K.repoIntegrationPolicy,repoProvider:K.repoProvider,worktreePath:K.worktreePath,originalWorkdir:K.originalWorkdir})}]}}catch(r){let o=bf(r),i=o.includes("Max sessions")?"":`
75
75
 
76
- Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}se();V();ae();import{existsSync as ps,readFileSync as ml}from"fs";import{EventEmitter as og}from"events";import{webcrypto as Ld}from"node:crypto";var Wd="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var If=128,dt,Qt;function xf(t){if(t<0)throw new RangeError("Wrong ID size");try{!dt||dt.length<t?(dt=Buffer.allocUnsafe(t*If),Ld.getRandomValues(dt),Qt=0):Qt+t>dt.length&&(Ld.getRandomValues(dt),Qt=0)}catch(e){throw dt=void 0,e}Qt+=t}function $r(t=21){xf(t|=0);let e="";for(let n=Qt-t;n<Qt;n++)e+=Wd[dt[n]&63];return e}Zi();ae();ne();var Bd={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function te(t,e){return Object.hasOwn(t,e)}var Fd=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function Tf(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 ge(t){return{...t,approvalExecutionState:Tf(t)}}function os(t,e){switch(e.type){case"initialize":return ge({...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"?ge({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?ge({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):ge({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return ge({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return ge({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return ge({...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 ge({...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 ge({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return ge({...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 ge({...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 ge({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return ge({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return ge({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":Fd.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return ge({...t,deliveryState:e.deliveryState})}}function qd(t,e){let n={...t,...te(e,"lifecycle")?{lifecycle:e.lifecycle}:{},...te(e,"approvalState")?{approvalState:e.approvalState}:{},...te(e,"approvalExecutionState")?{approvalExecutionState:e.approvalExecutionState}:{},...te(e,"worktreeState")?{worktreeState:e.worktreeState}:{},...te(e,"runtimeState")?{runtimeState:e.runtimeState}:{},...te(e,"deliveryState")?{deliveryState:e.deliveryState}:{},...te(e,"requestedPermissionMode")?{requestedPermissionMode:e.requestedPermissionMode}:{},...te(e,"currentPermissionMode")?{currentPermissionMode:e.currentPermissionMode}:{},...te(e,"pendingPlanApproval")?{pendingPlanApproval:e.pendingPlanApproval}:{},...te(e,"planApprovalContext")?{planApprovalContext:e.planApprovalContext}:{},...te(e,"planDecisionVersion")?{planDecisionVersion:e.planDecisionVersion}:{},...te(e,"actionablePlanDecisionVersion")?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...te(e,"canonicalPlanPromptVersion")?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...te(e,"approvalPromptRequiredVersion")?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...te(e,"approvalPromptVersion")?{approvalPromptVersion:e.approvalPromptVersion}:{},...te(e,"approvalPromptStatus")?{approvalPromptStatus:e.approvalPromptStatus}:{},...te(e,"approvalPromptTransport")?{approvalPromptTransport:e.approvalPromptTransport}:{},...te(e,"approvalPromptMessageKind")?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...te(e,"approvalPromptLastAttemptAt")?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...te(e,"approvalPromptDeliveredAt")?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...te(e,"approvalPromptFailedAt")?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{},...te(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"}),te(e,"pendingWorktreeDecisionSince")&&e.pendingWorktreeDecisionSince!==void 0||n.worktreeState==="pending_decision"?n=os(n,{type:"worktree.decision_requested"}):Fd.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),ge(n)}var Er=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 Cf}from"crypto";import{appendFileSync as Mf}from"fs";import{tmpdir as _f}from"os";import{join as $f}from"path";var Ud=2e3,Ef=/^[A-Za-z0-9_.-]+$/;function Df(t){return Ef.test(t)?t:`hashed+${Cf("sha256").update(t,"utf8").digest("hex")}`}function St(t){return $f(_f(),`openclaw-agent-${Df(t)}.txt`)}function Of(t,e){if(!e)return;let n=e.split(`
77
- `),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function Kd(t,e,n){Of(t,n),t.length>Ud&&t.splice(0,t.length-Ud);try{Mf(St(e),n,"utf-8")}catch{}return t}var Dr=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 Or=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?`
78
- ${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 Nr=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}};Re();var rg=[/\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 cs(t){return t?.trim()?rg.some(e=>e.test(t)):!1}function cl(t){if(!t?.trim())return;let e=t.split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return e.find(n=>cs(n))??e.at(-1)}var ig=120*1e3;function Qr(t){return t instanceof Error?t.message:String(t)}function sg(t,e){JSON.stringify({component:"Session",event:t,at:new Date().toISOString(),...e})}function ag(t){return t?{backendRefKind:t.kind,hasBackendConversationId:!!t.conversationId,hasBackendRunId:!!t.runId,hasBackendWorktreeId:!!t.worktreeId,hasBackendWorktreePath:!!t.worktreePath}:{}}var Jr=class extends og{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;worktreeParentBranch;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 Dr;constructor(e,n){super(),this.id=e.sessionIdOverride??$r(8),this.name=n,this.harness=e.harness?Rn(e.harness):Pd(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??Nt(this.harness.name),this.reasoningEffort=e.reasoningEffort??rt(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??Wt(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??D.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??D.planApproval,this.codexApprovalPolicy=this.harness.name==="codex"?"never":void 0,this.currentPermissionMode=this.permissionMode,this.originChannel=e.originChannel,this.originThreadId=e.originThreadId,this.originAgentId=e.originAgentId,this.originSessionKey=e.originSessionKey,this.route=e.route?{...e.route}:void 0,this.backendRef=e.backendRef?{...e.backendRef}:void 0,this.resumeSessionId=e.resumeSessionId,this.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,this.worktreeParentBranch=e.worktreeParentBranch,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 Or({appendOutput:r=>Kd(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 Nr({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??=ke(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(f=>typeof f=="string").join(`
79
- `):"",s=o==="completed"&&cs(i),a=s?"failed":o,d=s?cl(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,worktreeParentBranch:this.worktreeParentBranch,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(!Bd[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=wt(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(i=>`- ${i}`).join(`
76
+ Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}se();V();ae();import{existsSync as fs,readFileSync as ml}from"fs";import{EventEmitter as ig}from"events";import{webcrypto as Ld}from"node:crypto";var Wd="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var xf=128,dt,Qt;function Tf(t){if(t<0)throw new RangeError("Wrong ID size");try{!dt||dt.length<t?(dt=Buffer.allocUnsafe(t*xf),Ld.getRandomValues(dt),Qt=0):Qt+t>dt.length&&(Ld.getRandomValues(dt),Qt=0)}catch(e){throw dt=void 0,e}Qt+=t}function $r(t=21){Tf(t|=0);let e="";for(let n=Qt-t;n<Qt;n++)e+=Wd[dt[n]&63];return e}es();ae();ne();var Bd={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function te(t,e){return Object.hasOwn(t,e)}var Fd=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function Cf(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 ge(t){return{...t,approvalExecutionState:Cf(t)}}function ss(t,e){switch(e.type){case"initialize":return ge({...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"?ge({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?ge({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):ge({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return ge({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return ge({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return ge({...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 ge({...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 ge({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return ge({...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 ge({...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 ge({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return ge({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return ge({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":Fd.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return ge({...t,deliveryState:e.deliveryState})}}function qd(t,e){let n={...t,...te(e,"lifecycle")?{lifecycle:e.lifecycle}:{},...te(e,"approvalState")?{approvalState:e.approvalState}:{},...te(e,"approvalExecutionState")?{approvalExecutionState:e.approvalExecutionState}:{},...te(e,"worktreeState")?{worktreeState:e.worktreeState}:{},...te(e,"runtimeState")?{runtimeState:e.runtimeState}:{},...te(e,"deliveryState")?{deliveryState:e.deliveryState}:{},...te(e,"requestedPermissionMode")?{requestedPermissionMode:e.requestedPermissionMode}:{},...te(e,"currentPermissionMode")?{currentPermissionMode:e.currentPermissionMode}:{},...te(e,"pendingPlanApproval")?{pendingPlanApproval:e.pendingPlanApproval}:{},...te(e,"planApprovalContext")?{planApprovalContext:e.planApprovalContext}:{},...te(e,"planDecisionVersion")?{planDecisionVersion:e.planDecisionVersion}:{},...te(e,"actionablePlanDecisionVersion")?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...te(e,"canonicalPlanPromptVersion")?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...te(e,"approvalPromptRequiredVersion")?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...te(e,"approvalPromptVersion")?{approvalPromptVersion:e.approvalPromptVersion}:{},...te(e,"approvalPromptStatus")?{approvalPromptStatus:e.approvalPromptStatus}:{},...te(e,"approvalPromptTransport")?{approvalPromptTransport:e.approvalPromptTransport}:{},...te(e,"approvalPromptMessageKind")?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...te(e,"approvalPromptLastAttemptAt")?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...te(e,"approvalPromptDeliveredAt")?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...te(e,"approvalPromptFailedAt")?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{},...te(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"}),te(e,"pendingWorktreeDecisionSince")&&e.pendingWorktreeDecisionSince!==void 0||n.worktreeState==="pending_decision"?n=ss(n,{type:"worktree.decision_requested"}):Fd.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),ge(n)}var Er=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 Mf}from"crypto";import{appendFileSync as _f}from"fs";import{tmpdir as $f}from"os";import{join as Ef}from"path";var Ud=2e3,Df=/^[A-Za-z0-9_.-]+$/;function Of(t){return Df.test(t)?t:`hashed+${Mf("sha256").update(t,"utf8").digest("hex")}`}function St(t){return Ef($f(),`openclaw-agent-${Of(t)}.txt`)}function Nf(t,e){if(!e)return;let n=e.split(`
77
+ `),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function Kd(t,e,n){Nf(t,n),t.length>Ud&&t.splice(0,t.length-Ud);try{_f(St(e),n,"utf-8")}catch{}return t}var Dr=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 Or=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?`
78
+ ${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 Nr=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}};Re();var og=[/\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 ms(t){return t?.trim()?og.some(e=>e.test(t)):!1}function cl(t){if(!t?.trim())return;let e=t.split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return e.find(n=>ms(n))??e.at(-1)}var sg=120*1e3;function Qr(t){return t instanceof Error?t.message:String(t)}function ag(t,e){JSON.stringify({component:"Session",event:t,at:new Date().toISOString(),...e})}function dg(t){return t?{backendRefKind:t.kind,hasBackendConversationId:!!t.conversationId,hasBackendRunId:!!t.runId,hasBackendWorktreeId:!!t.worktreeId,hasBackendWorktreePath:!!t.worktreePath}:{}}var Jr=class extends ig{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;worktreeParentBranch;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 Dr;constructor(e,n){super(),this.id=e.sessionIdOverride??$r(8),this.name=n,this.harness=e.harness?Rn(e.harness):Pd(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??Nt(this.harness.name),this.reasoningEffort=e.reasoningEffort??rt(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??Wt(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??D.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??D.planApproval,this.codexApprovalPolicy=this.harness.name==="codex"?"never":void 0,this.currentPermissionMode=this.permissionMode,this.originChannel=e.originChannel,this.originThreadId=e.originThreadId,this.originAgentId=e.originAgentId,this.originSessionKey=e.originSessionKey,this.route=e.route?{...e.route}:void 0,this.backendRef=e.backendRef?{...e.backendRef}:void 0,this.resumeSessionId=e.resumeSessionId,this.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,this.worktreeParentBranch=e.worktreeParentBranch,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 Or({appendOutput:r=>Kd(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 Nr({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??=ke(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(f=>typeof f=="string").join(`
79
+ `):"",s=o==="completed"&&ms(i),a=s?"failed":o,d=s?cl(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,worktreeParentBranch:this.worktreeParentBranch,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(!Bd[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=wt(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(i=>`- ${i}`).join(`
80
80
  `),r=e.length>20?`
81
81
  - ...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(`
82
- `);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 Er,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:Ea(),canUseTool:this.canUseTool});this.harnessHandle=n,this.logDiagnostic("harness.launch.created",{hasStreamInput:!!n.streamInput,hasInterrupt:!!n.interrupt,hasPermissionModeSwitch:!!n.setPermissionMode}),this.setTimer("startup",ig,()=>{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: ${Qr(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${Qr(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.]
82
+ `);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 Er,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:Oa(),canUseTool:this.canUseTool});this.harnessHandle=n,this.logDiagnostic("harness.launch.created",{hasStreamInput:!!n.streamInput,hasInterrupt:!!n.interrupt,hasPermissionModeSwitch:!!n.setPermissionMode}),this.setTimer("startup",sg,()=>{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: ${Qr(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${Qr(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.]
83
83
 
84
84
  ${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.]
85
85
 
86
- ${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}${Qr(r)}`}if(this.multiTurn&&this.messageStream)this.messageStream.push(this.harness.buildUserMessage(n,this.backendConversationId??""));else if(this.harnessHandle?.streamInput){let r=this.harness.buildUserMessage(n,this.backendConversationId??"");async function*o(){yield r}await this.harnessHandle.streamInput(o())}else throw new Error("Session does not support follow-up messages (launched in single-turn mode).")}async interrupt(){return!this.turnInProgress||!this.harnessHandle?.interrupt?!1:(await this.harnessHandle.interrupt(),!0)}async submitPendingInputOption(e,n){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputOption)return!1;let r=await this.harnessHandle.submitPendingInputOption(e,n);return r&&(this.waitingForInputFired=!1),r}canSubmitPendingInputOption(){return!!(this.pendingInputState&&this.harnessHandle?.submitPendingInputOption)}async submitPendingInputText(e){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputText)return!1;let n=await this.harnessHandle.submitPendingInputText(e);return n&&(this.waitingForInputFired=!1),n}switchPermissionMode(e){this.pendingModeSwitch=e}get isActive(){return this._status==="starting"||this._status==="running"}kill(e){this.transitionToTerminal("killed",{reason:e})}complete(e="done"){this.transitionToTerminal("completed",{reason:e})}incrementAutoRespond(){this.autoRespondCount++}resetAutoRespond(){this.autoRespondCount=0}getOutput(e){return e===void 0?this.outputBuffer.slice():this.outputBuffer.slice(-e)}resetIdleTimer(){if(!this.multiTurn)return;let e=(D.idleTimeoutMinutes??15)*60*1e3;this.setTimer("idle",e,()=>{this._status==="running"&&(this.logDiagnostic("idle_timeout.fire",{idleTimeoutMinutes:D.idleTimeoutMinutes??15}),this.applyControlEvent({type:"terminal.entered",suspended:!0}),this.kill("idle-timeout"))})}teardown(){this.clearAllTimers(),this.completedAt||(this.completedAt=Date.now()),this.messageStream&&this.messageStream.end(),this.harnessHandle?.interrupt&&this.harnessHandle.interrupt().catch(e=>{`${this.id}${Qr(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=os(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=qd(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;sg(e,{sessionId:this.id,name:this.name,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState,harness:this.harnessName,hasHarnessSessionId:!!this.harnessSessionId,...ag(this.backendRef),...i})}};var dg=50,lg=1,ug=new Set(["starting","running","completed","failed","killed"]),cg=5,pg=1440*60*1e3,Yr=new Set(["merged","released","dismissed","no_change"]);function mg(t){let e=Number(t);return!Number.isFinite(e)||e<lg?dg:Math.floor(e)}function fg(t){return typeof t=="string"&&ug.has(t)}function gg(t){let e=t.split(`
87
- `);return e.at(-1)===""&&e.pop(),e}function ms(t){return t.backendRef?.conversationId??t.harnessSessionId}function hg(t,e){return e&&Yr.has(e)&&(!t||!Yr.has(t))?e:t??e}function yg(t,e){return e&&Yr.has(e.state)&&(!t||!Yr.has(t.state))?e:t??e}function fl(t,e,n){let r=ml(t,"utf-8"),o=gg(r);return e.full?o:o.slice(-n)}function kg(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=St(t.id);if(!ps(r))return null;try{return fl(r,e,n)}catch{return null}}function Sg(t){let e=We(t.duration),n=` | Cost: $${t.costUsd.toFixed(4)}`,r=t.phase?` | Phase: ${t.phase}`:"",o=t.lifecycle&&t.lifecycle!==t.phase?` | Lifecycle: ${t.lifecycle}`:"";return[`Session: ${t.name} [${t.id}] | Status: ${t.status.toUpperCase()}${r}${o}${n} | Duration: ${e}`,`${"─".repeat(60)}`].join(`
88
- `)}function gl(t,e){let n=t.name||t.sessionId||ms(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(`
89
- `)}function vg(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function wg(t){return t.outputPath?`(persisted session metadata recovered; output file is unavailable at ${t.outputPath})`:"(persisted session metadata recovered; no output file was recorded before the runtime was interrupted)"}function pl(t,e){let n=gl(t,wg(t)),r=ms(t),o=r?`
86
+ ${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}${Qr(r)}`}if(this.multiTurn&&this.messageStream)this.messageStream.push(this.harness.buildUserMessage(n,this.backendConversationId??""));else if(this.harnessHandle?.streamInput){let r=this.harness.buildUserMessage(n,this.backendConversationId??"");async function*o(){yield r}await this.harnessHandle.streamInput(o())}else throw new Error("Session does not support follow-up messages (launched in single-turn mode).")}async interrupt(){return!this.turnInProgress||!this.harnessHandle?.interrupt?!1:(await this.harnessHandle.interrupt(),!0)}async submitPendingInputOption(e,n){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputOption)return!1;let r=await this.harnessHandle.submitPendingInputOption(e,n);return r&&(this.waitingForInputFired=!1),r}canSubmitPendingInputOption(){return!!(this.pendingInputState&&this.harnessHandle?.submitPendingInputOption)}async submitPendingInputText(e){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputText)return!1;let n=await this.harnessHandle.submitPendingInputText(e);return n&&(this.waitingForInputFired=!1),n}switchPermissionMode(e){this.pendingModeSwitch=e}get isActive(){return this._status==="starting"||this._status==="running"}kill(e){this.transitionToTerminal("killed",{reason:e})}complete(e="done"){this.transitionToTerminal("completed",{reason:e})}incrementAutoRespond(){this.autoRespondCount++}resetAutoRespond(){this.autoRespondCount=0}getOutput(e){return e===void 0?this.outputBuffer.slice():this.outputBuffer.slice(-e)}resetIdleTimer(){if(!this.multiTurn)return;let e=(D.idleTimeoutMinutes??15)*60*1e3;this.setTimer("idle",e,()=>{this._status==="running"&&(this.logDiagnostic("idle_timeout.fire",{idleTimeoutMinutes:D.idleTimeoutMinutes??15}),this.applyControlEvent({type:"terminal.entered",suspended:!0}),this.kill("idle-timeout"))})}teardown(){this.clearAllTimers(),this.completedAt||(this.completedAt=Date.now()),this.messageStream&&this.messageStream.end(),this.harnessHandle?.interrupt&&this.harnessHandle.interrupt().catch(e=>{`${this.id}${Qr(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=ss(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=qd(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;ag(e,{sessionId:this.id,name:this.name,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState,harness:this.harnessName,hasHarnessSessionId:!!this.harnessSessionId,...dg(this.backendRef),...i})}};var lg=50,ug=1,cg=new Set(["starting","running","completed","failed","killed"]),pg=5,mg=1440*60*1e3,Yr=new Set(["merged","released","dismissed","no_change"]);function fg(t){let e=Number(t);return!Number.isFinite(e)||e<ug?lg:Math.floor(e)}function gg(t){return typeof t=="string"&&cg.has(t)}function hg(t){let e=t.split(`
87
+ `);return e.at(-1)===""&&e.pop(),e}function gs(t){return t.backendRef?.conversationId??t.harnessSessionId}function yg(t,e){return e&&Yr.has(e)&&(!t||!Yr.has(t))?e:t??e}function kg(t,e){return e&&Yr.has(e.state)&&(!t||!Yr.has(t.state))?e:t??e}function fl(t,e,n){let r=ml(t,"utf-8"),o=hg(r);return e.full?o:o.slice(-n)}function Sg(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=St(t.id);if(!fs(r))return null;try{return fl(r,e,n)}catch{return null}}function vg(t){let e=We(t.duration),n=` | Cost: $${t.costUsd.toFixed(4)}`,r=t.phase?` | Phase: ${t.phase}`:"",o=t.lifecycle&&t.lifecycle!==t.phase?` | Lifecycle: ${t.lifecycle}`:"";return[`Session: ${t.name} [${t.id}] | Status: ${t.status.toUpperCase()}${r}${o}${n} | Duration: ${e}`,`${"─".repeat(60)}`].join(`
88
+ `)}function gl(t,e){let n=t.name||t.sessionId||gs(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(`
89
+ `)}function wg(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function Pg(t){return t.outputPath?`(persisted session metadata recovered; output file is unavailable at ${t.outputPath})`:"(persisted session metadata recovered; no output file was recorded before the runtime was interrupted)"}function pl(t,e){let n=gl(t,Pg(t)),r=gs(t),o=r?`
90
90
  Backend session: ${r}`:"";return`${n}
91
- (no persisted output available: ${e})${o}`}function Pg(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?`
91
+ (no persisted output available: ${e})${o}`}function bg(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?`
92
92
  (no output yet)
93
93
  ${e.join(`
94
94
  `)}`:`
95
- (no output yet)`}function Zr(t,e,n={}){let r=mg(n.lines),o=t.resolve(e);if(!o){let l=t.getPersistedSession(e);if(l?.outputPath&&ps(l.outputPath))try{let u=fl(l.outputPath,n,r).join(`
96
- `),f=gl(l,vg(l));return u?`${f}
95
+ (no output yet)`}function Zr(t,e,n={}){let r=fg(n.lines),o=t.resolve(e);if(!o){let l=t.getPersistedSession(e);if(l?.outputPath&&fs(l.outputPath))try{let u=fl(l.outputPath,n,r).join(`
96
+ `),f=gl(l,wg(l));return u?`${f}
97
97
  ${u}`:`${f}
98
- (output file was empty)`}catch(u){let f=u instanceof Error?u.message:String(u);return`Error: Session "${e}" was cleaned up (expired) and output file could not be read: ${f}`}return l?.outputPath?pl(l,`output file is missing at ${l.outputPath}`):l?pl(l,"no outputPath is stored for this recovered session"):`Error: Session "${e}" not found.`}let i=kg(o,n,r),s=i&&i.length>0?i:n.full?o.getOutput():o.getOutput(r),a=Sg(o),d=s.length===0?`${a}${Pg(o)}`:`${a}
98
+ (output file was empty)`}catch(u){let f=u instanceof Error?u.message:String(u);return`Error: Session "${e}" was cleaned up (expired) and output file could not be read: ${f}`}return l?.outputPath?pl(l,`output file is missing at ${l.outputPath}`):l?pl(l,"no outputPath is stored for this recovered session"):`Error: Session "${e}" not found.`}let i=Sg(o,n,r),s=i&&i.length>0?i:n.full?o.getOutput():o.getOutput(r),a=vg(o),d=s.length===0?`${a}${bg(o)}`:`${a}
99
99
  ${s.join(`
100
- `)}`;if(o.pendingPlanApproval&&o.planFilePath)try{if(ps(o.planFilePath)){let l=ml(o.planFilePath,"utf-8"),u="─".repeat(60);return`${d}
100
+ `)}`;if(o.pendingPlanApproval&&o.planFilePath)try{if(fs(o.planFilePath)){let l=ml(o.planFilePath,"utf-8"),u="─".repeat(60);return`${d}
101
101
  ${u}
102
102
  Plan file: ${o.planFilePath}
103
103
  ${u}
104
- ${l}`}}catch{}return d}function Xr(t,e="all",n,r={}){let o=t.listPersistedSessions()??[],s=bg(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()-pg;s=s.filter(d=>(d.startedAt??0)>=a)}else s=s.slice(0,cg);return s.length===0?"No sessions found.":s.map(a=>Cd(a)).join(`
104
+ ${l}`}}catch{}return d}function Xr(t,e="all",n,r={}){let o=t.listPersistedSessions()??[],s=Rg(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()-mg;s=s.filter(d=>(d.startedAt??0)>=a)}else s=s.slice(0,pg);return s.length===0?"No sessions found.":s.map(a=>Cd(a)).join(`
105
105
 
106
- `)}function bg(t,e){let n=new Map;for(let r of e){if(!fg(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=ms(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:hg(r.worktreeState,o?.worktreeState),worktreeLifecycle:yg(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 Rg(t){if(!t||typeof t!="object")return"all";let e=t.status;switch(e){case"running":case"completed":case"failed":case"killed":case"all":return e;default:return"all"}}function hl(t){return{name:"agent_sessions",description:"List coding agent sessions with their status and progress. By default, shows the 5 most recent sessions; set `full` to show all sessions from the last 24 hours.",parameters:g.Object({status:g.Optional(g.Union([g.Literal("all"),g.Literal("running"),g.Literal("completed"),g.Literal("failed"),g.Literal("killed")],{description:'Filter by status (default "all")'})),full:g.Optional(g.Boolean({description:"Show all sessions from the last 24h instead of just the most recent 5"}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=Rg(n),o=t?.workspaceDir?gt(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:Xr(v,r,o,{full:i})}]}}}}se();V();function eo(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 Ag(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session!="string"?!1:e.reason===void 0?!0:e.reason==="completed"||e.reason==="killed"}function yl(t){return{name:"agent_kill",description:"Terminate or complete a running coding agent session by name or ID. Use reason='completed' to mark a session as successfully completed instead of killed.",parameters:g.Object({session:g.String({description:"Session name or ID to terminate"}),reason:g.Optional(g.Union([g.Literal("completed"),g.Literal("killed")],{description:"Reason for closing the session. 'completed' marks it as successfully done (sends ✅ notification). 'killed' (default) terminates it."}))}),async execute(e,n){return v?Ag(n)?{content:[{type:"text",text:eo(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."}]}}}}se();V();function Ig(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function to(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?Ig(n)?{content:[{type:"text",text:Zr(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."}]}}}}se();V();ae();ne();var xg=10;function gs(t){return t instanceof Error?t.message:String(t)}function Rt(t){return G(t)??t.harnessSessionId??"unknown-session"}function Tg(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return br(t)??G(t)??O(t)}function kl(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!O(t)}function Cg(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='${Rt(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='${Rt(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='${Rt(t)}', fork_session=true, prompt='<new task>').`:`Use agent_respond(session='${Rt(t)}', message='<next instruction>') to continue the running session.`,o=n?` ${n}`:"";return{text:`Resume unavailable for session ${t.name} [${Rt(t)}] (${e}).${o} ${r}`,isError:!0}}async function Sl(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:br(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} [${Rt(e)}]: ${gs(r)}`,isError:!0}}}var Mg=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
106
+ `)}function Rg(t,e){let n=new Map;for(let r of e){if(!gg(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=gs(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:yg(r.worktreeState,o?.worktreeState),worktreeLifecycle:kg(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 Ag(t){if(!t||typeof t!="object")return"all";let e=t.status;switch(e){case"running":case"completed":case"failed":case"killed":case"all":return e;default:return"all"}}function hl(t){return{name:"agent_sessions",description:"List coding agent sessions with their status and progress. By default, shows the 5 most recent sessions; set `full` to show all sessions from the last 24 hours.",parameters:g.Object({status:g.Optional(g.Union([g.Literal("all"),g.Literal("running"),g.Literal("completed"),g.Literal("failed"),g.Literal("killed")],{description:'Filter by status (default "all")'})),full:g.Optional(g.Boolean({description:"Show all sessions from the last 24h instead of just the most recent 5"}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=Ag(n),o=t?.workspaceDir?gt(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:Xr(v,r,o,{full:i})}]}}}}se();V();function eo(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 Ig(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session!="string"?!1:e.reason===void 0?!0:e.reason==="completed"||e.reason==="killed"}function yl(t){return{name:"agent_kill",description:"Terminate or complete a running coding agent session by name or ID. Use reason='completed' to mark a session as successfully completed instead of killed.",parameters:g.Object({session:g.String({description:"Session name or ID to terminate"}),reason:g.Optional(g.Union([g.Literal("completed"),g.Literal("killed")],{description:"Reason for closing the session. 'completed' marks it as successfully done (sends ✅ notification). 'killed' (default) terminates it."}))}),async execute(e,n){return v?Ig(n)?{content:[{type:"text",text:eo(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."}]}}}}se();V();function xg(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function to(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?xg(n)?{content:[{type:"text",text:Zr(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."}]}}}}se();V();ae();ne();var Tg=10;function ys(t){return t instanceof Error?t.message:String(t)}function Rt(t){return G(t)??t.harnessSessionId??"unknown-session"}function Cg(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return br(t)??G(t)??O(t)}function kl(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!O(t)}function Mg(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='${Rt(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='${Rt(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='${Rt(t)}', fork_session=true, prompt='<new task>').`:`Use agent_respond(session='${Rt(t)}', message='<next instruction>') to continue the running session.`,o=n?` ${n}`:"";return{text:`Resume unavailable for session ${t.name} [${Rt(t)}] (${e}).${o} ${r}`,isError:!0}}async function Sl(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:br(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} [${Rt(e)}]: ${ys(r)}`,isError:!0}}}var _g=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
107
107
 
108
- `;function vl(t){let e=t?.replace(/\s+/g," ").trim();if(e)return ue(e,240)}function fs(t){if(t.approvalState==="changes_requested"&&!no(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 no(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function _g(t){return fs(t)?!1:no(t)||t.currentPermissionMode==="plan"}function $g(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 Eg(t){return(t.planDecisionVersion??0)+1}function wl(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:Eg(t),actionablePlanDecisionVersion:void 0,canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:void 0,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",approvalPromptTransport:"none",approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:void 0};return e==="rejected"&&(n.runtimeState="stopped"),n}function Pl(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function hs(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),!o)return{text:`Plan rejected for [${i}].`,isError:!1};let s=wl(o,"rejected");return n?(Pl(n,s),t.updatePersistedSession?.(e,s),t.kill(n.id,"user"),{text:`Plan rejected for [${n.name}]. Session stopped.`}):(t.updatePersistedSession?.(e,s),{text:`Plan rejected for [${i}]. Session remains stopped.`})}function ys(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),o){let s=wl(o,"changes_requested");n&&Pl(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function Dg(t,e,n,r={}){let o=kt(e);if(!(o.kind==="resume"||kl(e)))return;let s=!!(r.approve&&_g(e)),a=s?vl(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?Sl(t,e,n):Mn(e,o.reason);let d={prompt:s?Mg+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:Tg(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: ${gs(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"}:kt(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?Cg(e.message):void 0;if(s==="approve")return Ae(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return ys(t,n?.id??r?.sessionId??e.session);if(s==="reject")return hs(t,n?.id??r?.sessionId??e.session);if(e.approve){let d=fs(o);if(d)return{text:d,isError:!0}}if(i.kind==="resume"||kl(o)){let d=await Dg(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(d)return d}else{if(i.kind==="relaunch")return Sl(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} [${Rt(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=D.maxAutoResponds??xg;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=fs(n);if(m)return{text:m,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let c=ue(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${c}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let m=ue(e.message,80);return{text:[`Pending input answered for session ${n.name} [${n.id}].`,` Message: "${m}"`,"Use agent_output to see the response."].join(`
108
+ `;function vl(t){let e=t?.replace(/\s+/g," ").trim();if(e)return ue(e,240)}function hs(t){if(t.approvalState==="changes_requested"&&!no(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 no(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function $g(t){return hs(t)?!1:no(t)||t.currentPermissionMode==="plan"}function Eg(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 Dg(t){return(t.planDecisionVersion??0)+1}function wl(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:Dg(t),actionablePlanDecisionVersion:void 0,canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:void 0,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",approvalPromptTransport:"none",approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:void 0};return e==="rejected"&&(n.runtimeState="stopped"),n}function Pl(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function ks(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),!o)return{text:`Plan rejected for [${i}].`,isError:!1};let s=wl(o,"rejected");return n?(Pl(n,s),t.updatePersistedSession?.(e,s),t.kill(n.id,"user"),{text:`Plan rejected for [${n.name}]. Session stopped.`}):(t.updatePersistedSession?.(e,s),{text:`Plan rejected for [${i}]. Session remains stopped.`})}function Ss(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),o){let s=wl(o,"changes_requested");n&&Pl(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function Og(t,e,n,r={}){let o=kt(e);if(!(o.kind==="resume"||kl(e)))return;let s=!!(r.approve&&$g(e)),a=s?vl(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?Sl(t,e,n):Mn(e,o.reason);let d={prompt:s?_g+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:Cg(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: ${ys(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"}:kt(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?Mg(e.message):void 0;if(s==="approve")return Ae(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return Ss(t,n?.id??r?.sessionId??e.session);if(s==="reject")return ks(t,n?.id??r?.sessionId??e.session);if(e.approve){let d=hs(o);if(d)return{text:d,isError:!0}}if(i.kind==="resume"||kl(o)){let d=await Og(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(d)return d}else{if(i.kind==="relaunch")return Sl(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} [${Rt(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=D.maxAutoResponds??Tg;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=hs(n);if(m)return{text:m,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let c=ue(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${c}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let m=ue(e.message,80);return{text:[`Pending input answered for session ${n.name} [${n.id}].`,` Message: "${m}"`,"Use agent_output to see the response."].join(`
109
109
  `)}}let l=!1;e.interrupt&&(l=await n.interrupt());let u=!!(e.approve&&no(n)),f=u?vl(e.approvalRationale):void 0,p="";if(e.approve&&no(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=f):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?p=`
110
110
  ℹ️ approve=true was set but session is already in bypassPermissions mode.`:e.approve?p=`
111
111
  ⚠️ approve=true was set but session has no pending plan approval.`:(n.pendingPlanApproval||n.approvalState==="changes_requested")&&(p=`
112
- ℹ️ 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&&$g(t,n),u)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let m=ue(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${m}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let k=ue(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: "${k}"`,p,"Use agent_output to see the response."].filter(Boolean).join(`
113
- `)}}catch(d){return{text:`Error sending message to session ${n.name} [${n.id}]: ${gs(d)}`,isError:!0}}}function Og(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.message=="string"&&(e.approval_rationale===void 0||typeof e.approval_rationale=="string")}function bl(t){return{name:"agent_respond",description:"Send a follow-up message to a running coding agent session. The session must be running. All sessions are multi-turn.",parameters:g.Object({session:g.String({description:"Session name or ID to respond to"}),message:g.String({description:"The message to send to the session"}),interrupt:g.Optional(g.Boolean({description:"If true, interrupt the current turn before sending the message. Useful to redirect the session mid-response."})),userInitiated:g.Optional(g.Boolean({description:"Set to true when the message comes from the user (not auto-generated). Resets the auto-respond counter and bypasses the auto-respond limit."})),approve:g.Optional(g.Boolean({description:"Set to true to escalate session permissions to bypassPermissions. Works in two scenarios: (1) approve a pending plan in plan mode, or (2) escalate a default-mode session to skip remaining OpenClaw approval checkpoints. No-op if already in bypassPermissions mode. In plan mode without a pending plan, this flag is ignored."})),approval_rationale:g.Optional(g.String({description:"Optional structured rationale for a direct delegated plan approval. Use this instead of embedding the rationale in message text when approve=true for a pending plan."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Og(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}]}}}}se();V();function Ng(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Rl(t){return{name:"agent_request_plan_approval",description:"Send a plan-approval decision prompt to the user for a session that is already waiting on plan approval. Reuses the plugin's Approve/Revise/Reject buttons so the user can decide directly from the message.",parameters:g.Object({session:g.String({description:"Session name or ID awaiting plan approval"}),summary:g.String({description:"Concise user-facing summary of scope, risk, and any concerns that should accompany the approval buttons"})}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Ng(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}]}}}}se();V();function Wg(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Al(t){return{name:"agent_request_worktree_decision",description:"Send a worktree Merge/Open PR/Later/Discard decision prompt to the user for a delegated worktree session that is awaiting human choice.",parameters:g.Object({session:g.String({description:"Delegated session name or ID awaiting a worktree decision"}),summary:g.String({description:"Concise user-facing summary of scope, risk, and why human choice is needed"})}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Wg(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}]}}}}se();V();ae();var ks=["off","manual","ask","delegate","auto-merge","auto-pr"],ro=new Set(ks),Lg=["pr-required","pr-allowed","never-pr","manual"],Il=new Set(Lg),Bg=["low","medium","high","xhigh","max"],xl=new Set(Bg);function Fg(t){return typeof t=="string"&&ro.has(t)}var qg=g.Union(ks.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 Ug(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||Fg(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 Kg(t,e){let n=Lt(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 Vg(t,e){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=Kg(t,e);return!n?.provider||!n.target?{content:[{type:"text",text:"Error: Could not resolve a direct delivery route for the plan offer."}]}:(v.sendPlanOffer({offerId:e.offer_id,route:n,text:e.offer_text,planName:e.plan_name??e.offer_id,planPrompt:e.plan_prompt,planWorkdir:e.plan_workdir,planWorktreeStrategy:e.plan_worktree_strategy}),{content:[{type:"text",text:`Interactive plan offer queued for ${n.provider}|${n.target}${n.threadId?`#${n.threadId}`:""}.`}]})}function Tl(t){return{name:"agent_send_plan_offer",description:"Post a user-facing message to the current or explicit chat route with human-gated Start Plan and Dismiss inline buttons. Use this when an external workflow wants the user to open a plan-only code-agent session from the message.",parameters:g.Object({offer_id:g.String({description:"Stable offer identifier, for example 'plugin-readiness-v2026.5.5'."}),offer_text:g.String({description:"Final user-facing text to deliver."}),plan_prompt:g.String({description:"Prompt to seed into the plan-only session when the user clicks Start Plan."}),plan_workdir:g.String({description:"Working directory for the planning session."}),plan_worktree_strategy:g.Optional(qg),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 Ug(n)?Vg(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}se();V();function Cl(t){return{name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics: session counts by status, average duration, and notable sessions.",parameters:g.Object({}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=v.getMetrics(),o=v.list("running").length;return{content:[{type:"text",text:Ar(r,o)}]}}}}se();V();Jt();import{execFileSync as jg}from"child_process";var vs=[{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."}],Gg=new Map(vs.map(t=>[t.policy,t]));function _n(t){return t?vs:vs.filter(e=>e.policy==="never-pr"||e.policy==="manual")}function Ml(t){return Gg.get(t)??{policy:t,label:t,title:t,description:"Custom repo integration policy."}}function Xt(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 ws(t){let{policy:e,prAvailable:n}=t;return{merge:e!=="pr-required"&&e!=="manual",pr:e!=="never-pr"&&e!=="manual"&&n}}function Ss(t,e){try{return jg("git",e,{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function _l(t){if(!t)return;let e=t.trim().replace(/\/+$/,"").replace(/\.git$/i,""),n=e.match(/^git@([^:]+):(.+)$/);if(n)return`https://${n[1].toLowerCase()}/${n[2].toLowerCase()}`;let r=e.match(/^https?:\/\/([^/]+)\/(.+)$/i);return r?`https://${r[1].toLowerCase()}/${r[2].toLowerCase()}`:e.toLowerCase()}function Hg(t){return _l(t)?.startsWith("https://github.com/")?"github":"unsupported"}function $n(t){let e=Ss(t,["rev-parse","--show-toplevel"]);if(!e)return;let n=Ss(e,["remote","get-url","origin"])??Ss(e,["remote","get-url","upstream"]),r=_l(n),o=Hg(r);return{key:r?`${e}|${r}`:e,repoRoot:e,remoteUrl:r,provider:o}}function $l(t){if(t?.remoteUrl)return t.remoteUrl==="https://github.com/goldmar/openclaw-code-agent"?"pr-required":void 0}function Ps(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 bs(t){return t.provider==="github"&&he()}function El(t){let e=t.requestedStrategy,n=ws(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 Rs(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(`
114
- `)}function zg(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
+ ℹ️ 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&&Eg(t,n),u)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let m=ue(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${m}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let k=ue(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: "${k}"`,p,"Use agent_output to see the response."].filter(Boolean).join(`
113
+ `)}}catch(d){return{text:`Error sending message to session ${n.name} [${n.id}]: ${ys(d)}`,isError:!0}}}function Ng(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.message=="string"&&(e.approval_rationale===void 0||typeof e.approval_rationale=="string")}function bl(t){return{name:"agent_respond",description:"Send a follow-up message to a running coding agent session. The session must be running. All sessions are multi-turn.",parameters:g.Object({session:g.String({description:"Session name or ID to respond to"}),message:g.String({description:"The message to send to the session"}),interrupt:g.Optional(g.Boolean({description:"If true, interrupt the current turn before sending the message. Useful to redirect the session mid-response."})),userInitiated:g.Optional(g.Boolean({description:"Set to true when the message comes from the user (not auto-generated). Resets the auto-respond counter and bypasses the auto-respond limit."})),approve:g.Optional(g.Boolean({description:"Set to true to escalate session permissions to bypassPermissions. Works in two scenarios: (1) approve a pending plan in plan mode, or (2) escalate a default-mode session to skip remaining OpenClaw approval checkpoints. No-op if already in bypassPermissions mode. In plan mode without a pending plan, this flag is ignored."})),approval_rationale:g.Optional(g.String({description:"Optional structured rationale for a direct delegated plan approval. Use this instead of embedding the rationale in message text when approve=true for a pending plan."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Ng(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}]}}}}se();V();function Wg(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Rl(t){return{name:"agent_request_plan_approval",description:"Send a plan-approval decision prompt to the user for a session that is already waiting on plan approval. Reuses the plugin's Approve/Revise/Reject buttons so the user can decide directly from the message.",parameters:g.Object({session:g.String({description:"Session name or ID awaiting plan approval"}),summary:g.String({description:"Concise user-facing summary of scope, risk, and any concerns that should accompany the approval buttons"})}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Wg(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}]}}}}se();V();function Lg(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Al(t){return{name:"agent_request_worktree_decision",description:"Send a worktree Merge/Open PR/Later/Discard decision prompt to the user for a delegated worktree session that is awaiting human choice.",parameters:g.Object({session:g.String({description:"Delegated session name or ID awaiting a worktree decision"}),summary:g.String({description:"Concise user-facing summary of scope, risk, and why human choice is needed"})}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Lg(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}]}}}}se();V();ae();var vs=["off","manual","ask","delegate","auto-merge","auto-pr"],ro=new Set(vs),Bg=["pr-required","pr-allowed","never-pr","manual"],Il=new Set(Bg),Fg=["low","medium","high","xhigh","max"],xl=new Set(Fg);function qg(t){return typeof t=="string"&&ro.has(t)}var Ug=g.Union(vs.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 Kg(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||qg(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 Vg(t,e){let n=Lt(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 jg(t,e){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=Vg(t,e);return!n?.provider||!n.target?{content:[{type:"text",text:"Error: Could not resolve a direct delivery route for the plan offer."}]}:(v.sendPlanOffer({offerId:e.offer_id,route:n,text:e.offer_text,planName:e.plan_name??e.offer_id,planPrompt:e.plan_prompt,planWorkdir:e.plan_workdir,planWorktreeStrategy:e.plan_worktree_strategy}),{content:[{type:"text",text:`Interactive plan offer queued for ${n.provider}|${n.target}${n.threadId?`#${n.threadId}`:""}.`}]})}function Tl(t){return{name:"agent_send_plan_offer",description:"Post a user-facing message to the current or explicit chat route with human-gated Start Plan and Dismiss inline buttons. Use this when an external workflow wants the user to open a plan-only code-agent session from the message.",parameters:g.Object({offer_id:g.String({description:"Stable offer identifier, for example 'plugin-readiness-v2026.5.5'."}),offer_text:g.String({description:"Final user-facing text to deliver."}),plan_prompt:g.String({description:"Prompt to seed into the plan-only session when the user clicks Start Plan."}),plan_workdir:g.String({description:"Working directory for the planning session."}),plan_worktree_strategy:g.Optional(Ug),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 Kg(n)?jg(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}se();V();function Cl(t){return{name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics: session counts by status, average duration, and notable sessions.",parameters:g.Object({}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=v.getMetrics(),o=v.list("running").length;return{content:[{type:"text",text:Ar(r,o)}]}}}}se();V();Jt();import{execFileSync as Gg}from"child_process";var Ps=[{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."}],Hg=new Map(Ps.map(t=>[t.policy,t]));function _n(t){return t?Ps:Ps.filter(e=>e.policy==="never-pr"||e.policy==="manual")}function Ml(t){return Hg.get(t)??{policy:t,label:t,title:t,description:"Custom repo integration policy."}}function Xt(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 bs(t){let{policy:e,prAvailable:n}=t;return{merge:e!=="pr-required"&&e!=="manual",pr:e!=="never-pr"&&e!=="manual"&&n}}function ws(t,e){try{return Gg("git",e,{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function _l(t){if(!t)return;let e=t.trim().replace(/\/+$/,"").replace(/\.git$/i,""),n=e.match(/^git@([^:]+):(.+)$/);if(n)return`https://${n[1].toLowerCase()}/${n[2].toLowerCase()}`;let r=e.match(/^https?:\/\/([^/]+)\/(.+)$/i);return r?`https://${r[1].toLowerCase()}/${r[2].toLowerCase()}`:e.toLowerCase()}function zg(t){return _l(t)?.startsWith("https://github.com/")?"github":"unsupported"}function $n(t){let e=ws(t,["rev-parse","--show-toplevel"]);if(!e)return;let n=ws(e,["remote","get-url","origin"])??ws(e,["remote","get-url","upstream"]),r=_l(n),o=zg(r);return{key:r?`${e}|${r}`:e,repoRoot:e,remoteUrl:r,provider:o}}function $l(t){if(t?.remoteUrl)return t.remoteUrl==="https://github.com/goldmar/openclaw-code-agent"?"pr-required":void 0}function Rs(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 As(t){return t.provider==="github"&&he()}function El(t){let e=t.requestedStrategy,n=bs(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 Is(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(`
114
+ `)}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(`
115
115
  `):"No stored repo policy found."}function Dl(t){return{name:"agent_repo_policy",description:"Inspect or set the repository integration policy that governs OCA worktree merge/PR follow-through.",parameters:g.Object({workdir:g.Optional(g.String({description:"Repository workdir. Defaults to the current workspace directory."})),policy:g.Optional(g.Union([g.Literal("pr-required"),g.Literal("pr-allowed"),g.Literal("never-pr"),g.Literal("manual")],{description:"Policy to set for this repo."})),reset:g.Optional(g.Boolean({description:"Remove the stored policy for this repo."})),list:g.Optional(g.Boolean({description:"List all stored repo policies."})),cleanup:g.Optional(g.Boolean({description:"Remove stored repo policies whose repoRoot no longer exists on disk."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=n&&typeof n=="object"?n:{};if(r.cleanup===!0){let a=v.cleanupRepoPolicies();return{content:[{type:"text",text:a.length===0?"No stale repo policies found.":[`Removed ${a.length} stale repo ${a.length===1?"policy":"policies"}.`,...a.map(l=>`${l.policy} | ${l.provider} | ${l.repoRoot}`)].join(`
116
116
  `)}]}}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(`
117
- `)}]}}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(!zg(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=Xt(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(`
117
+ `)}]}}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=Xt(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(`
118
118
  `)}]}}return d.kind==="launched"?{content:[{type:"text",text:[En(a),"",d.text].join(`
119
119
  `)}]}: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(`
120
120
  `)}]}:{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(`
121
- `)}]}}}}se();ae();V();Re();Dn();Nn();import{existsSync as co}from"fs";function Zg(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Xg(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 eh(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 po(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(!Zg(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=tn(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.`}]};co(s)||`${s}${a}`;let l=a;if(!co(a))return{content:[{type:"text",text:`Error: originalWorkdir "${a}" does not exist.`}]};let u=n.base_branch??Le(l),f=u,p=n.strategy??"merge",k=n.push===!0,m=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((co(s)?xn(l,d,f):void 0)===0&&Pt(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${d} has no commits ahead of ${f}.`,`Worktree: ${s}`,"Resume or inspect the session, then commit real task changes or clean temporary files before retrying agent_merge."].join(`
122
- `)}]};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 x=He(l,d,u),T=zr(l,d,f,p,s),A=Zt(T);if(T.success){let h=Xg({mergeResult:T,repoDir:l,baseBranch:f});if(k&&!Hr(l,f)){let N=`⚠️ Merged ${d} → ${f} locally, but failed to push ${f}`;v.notifyWorktreeOutcome(r.notificationTarget,N,{detailLines:[`Branch ${d} was merged into ${f} in the local repository.`,`Pushing ${f} failed; remote state may not include the merge.`,"Cleanup was skipped so the branch/worktree remains available for follow-up.",...h,...A]}),S={content:[{type:"text",text:Be(N,T)}]};return}let w=!1,L=!1,K=!co(s);L=K?!0:ce(l,s),jr(l),m&&(w=Pe(l,d));let W=eh({deleteBranchRequested:m,branchDeleted:w,worktreeCleanedUp:L,worktreeAlreadyAbsent:K});if(b){let N=new Date().toISOString();for(let B of On({...r,persistedSession:b}))v.updatePersistedSession(B,{...en({worktreeBaseBranch:u,worktreePrTargetRepo:b.worktreePrTargetRepo,worktreePushRemote:b.worktreePushRemote},{mergedAt:N,updatedAt:N,resolvedAt:N,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let I=bt({kind:"merge",branch:d,base:u,filesChanged:x?.filesChanged,insertions:x?.insertions,deletions:x?.deletions});v.notifyWorktreeOutcome(r.notificationTarget,I,{detailLines:[T.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",k?`Pushed ${f}.`:`Did not push ${f}; push was not requested.`,W.detailLine,...h,...A]});let F=`✅ ${T.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${d} → ${f}.${k?" Pushed.":""}${W.summaryFragment}`;T.stashPopConflict?F+=`
121
+ `)}]}}}}se();ae();V();Re();Dn();Nn();import{existsSync as co}from"fs";function Xg(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function eh(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 th(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 po(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(!Xg(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=tn(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.`}]};co(s)||`${s}${a}`;let l=a;if(!co(a))return{content:[{type:"text",text:`Error: originalWorkdir "${a}" does not exist.`}]};let u=n.base_branch??Le(l),f=u,p=n.strategy??"merge",k=n.push===!0,m=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((co(s)?xn(l,d,f):void 0)===0&&Pt(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${d} has no commits ahead of ${f}.`,`Worktree: ${s}`,"Resume or inspect the session, then commit real task changes or clean temporary files before retrying agent_merge."].join(`
122
+ `)}]};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 x=He(l,d,u),T=zr(l,d,f,p,s),A=Zt(T);if(T.success){let h=eh({mergeResult:T,repoDir:l,baseBranch:f});if(k&&!Hr(l,f)){let N=`⚠️ Merged ${d} → ${f} locally, but failed to push ${f}`;v.notifyWorktreeOutcome(r.notificationTarget,N,{detailLines:[`Branch ${d} was merged into ${f} in the local repository.`,`Pushing ${f} failed; remote state may not include the merge.`,"Cleanup was skipped so the branch/worktree remains available for follow-up.",...h,...A]}),S={content:[{type:"text",text:Be(N,T)}]};return}let w=!1,L=!1,K=!co(s);L=K?!0:ce(l,s),jr(l),m&&(w=Pe(l,d));let W=th({deleteBranchRequested:m,branchDeleted:w,worktreeCleanedUp:L,worktreeAlreadyAbsent:K});if(b){let N=new Date().toISOString();for(let B of On({...r,persistedSession:b}))v.updatePersistedSession(B,{...en({worktreeBaseBranch:u,worktreePrTargetRepo:b.worktreePrTargetRepo,worktreePushRemote:b.worktreePushRemote},{mergedAt:N,updatedAt:N,resolvedAt:N,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let I=bt({kind:"merge",branch:d,base:u,filesChanged:x?.filesChanged,insertions:x?.insertions,deletions:x?.deletions});v.notifyWorktreeOutcome(r.notificationTarget,I,{detailLines:[T.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",k?`Pushed ${f}.`:`Did not push ${f}; push was not requested.`,W.detailLine,...h,...A]});let F=`✅ ${T.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${d} → ${f}.${k?" Pushed.":""}${W.summaryFragment}`;T.stashPopConflict?F+=`
123
123
  ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${T.stashRef??"stash@{0}"}\` in ${l} to review stashed changes.`:T.stashed&&(F+=`
124
124
  (Pre-existing changes on ${f} were auto-stashed and restored.)`),F=Be(F,T),S={content:[{type:"text",text:F}]}}else if(T.rebaseConflict)S={content:[{type:"text",text:Be(`⚠️ Rebase conflicts — manual resolution required:
125
125
 
126
126
  ${T.error}`,T)}]};else if(T.conflictFiles&&T.conflictFiles.length>0){let h=["Resolve merge conflicts in the following files and commit the resolution:","",...T.conflictFiles.map(w=>`- ${w}`),"",`After resolving, commit with message: "Resolve merge conflicts from ${d}"`].join(`
127
- `);try{let w=v.spawn({prompt:h,workdir:l,name:`${n.session}-conflict-resolver`,harness:me(),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:Be(`⚠️ Merge conflicts in ${T.conflictFiles.length} file(s) — spawned conflict resolver session: ${w.name}`,T)}]}}catch(w){S={content:[{type:"text",text:Be(`❌ Merge conflicts detected, but failed to spawn resolver: ${w instanceof Error?w.message:String(w)}`,T)}]}}}else{let h=T.dirtyError?`❌ Merge blocked: ${T.error}`:`❌ Merge failed: ${T.error??"unknown error"}`;S={content:[{type:"text",text:Be(h,T)}]}}}),S}}}So();se();V();ne();Re();Nn();function mh(t){return!!t&&typeof t=="object"}function Yl(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(!mh(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=ao(v);if(r&&(a=a.filter(k=>lo(k,r)),a.length===0)){let k=tn(v,r);if(!k.persistedSession&&!k.activeSession)return{content:[{type:"text",text:`Error: Session "${r}" not found.`}]}}if(n.workdir&&(a=a.filter(k=>k.workdir===n.workdir)),a.length===0)return{content:[{type:"text",text:"No managed worktrees matched the requested scope."}]};let d=[],l=[],u=[],f=[];for(let k of a){let{persistedSession:m,activeSession:c,resolvedLifecycle:y}=so(v,k,{baseBranch:n.base_branch});if(!y.cleanupSafe){if(s){let S=y.reasons.length>0?y.reasons.map(uo).join(", "):At(y.derivedState);l.push(`${k.name} [kept: ${S}]`)}continue}if(d.push(`${k.name} (${At(y.derivedState)})`),!i)try{let S=k.workdir;if(!((m??c)&&le(m??c))&&k.worktreePath&&ce(S,k.worktreePath,{destructive:!1}),k.worktreeBranch&&Pe(S,k.worktreeBranch),m){let x=y.derivedState==="merged"||y.derivedState==="released"?y.derivedState:y.lifecycle.state,T=new Date().toISOString(),A=x==="merged"?m.worktreeMergedAt:x==="dismissed"?m.worktreeDismissedAt:void 0;v.updatePersistedSession(k.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeMerged:x==="merged"?!0:m.worktreeMerged,worktreeMergedAt:x==="merged"?m.worktreeMergedAt??T:m.worktreeMergedAt,worktreeLifecycle:{...m.worktreeLifecycle??y.lifecycle,state:x,updatedAt:T,resolvedAt:m.worktreeLifecycle?.resolvedAt??A??T,resolutionSource:m.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??y.lifecycle.baseBranch??m.worktreeBaseBranch,targetRepo:m.worktreePrTargetRepo,pushRemote:m.worktreePushRemote,notes:y.reasons}})}u.push(`${k.name} (${At(y.derivedState)})`)}catch(S){f.push(`${k.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 (${f.length}): ${f.join(", ")||"(none)"}`)),{content:[{type:"text",text:p.join(`
128
- `)}]}}}}se();V();Nn();function fh(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 Zl(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(!fh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n&&typeof n=="object"?n.session:void 0,o=ao(v);if(r&&(o=o.filter(s=>lo(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}=so(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:${At(d.lifecycle.state)}`),d.derivedState!==d.lifecycle.state&&i.push(` Derived: ${At(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(uo).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
129
- `).trim()}]}}}}se();V();ae();hr();import{existsSync as gh}from"fs";function hh(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function vo(t,e){let n=t.goal.trim();if(!n)return{kind:"error",text:"Error: goal must not be empty."};let r=t.workdir||e.workspaceDir||D.defaultWorkdir||process.cwd();if(!gh(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=hh(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??me(),a=t.model??Nt(s),d=je(s,a),l=tr(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&&!Gt(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&&!fr(s,d,l))return{kind:"error",text:`Error: Model "${a}" is not allowed. Permitted models: ${l?.join(", ")}`};let u=gr(s,d,l),f=e.sessionKey||void 0,p=nr(e),k=yn(e,p||gt(r)),m=Lt(e,k,f);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:u,reasoningEffort:rt(s),fastMode:Wt(s),systemPrompt:t.systemPrompt,allowedTools:t.allowedTools,maxIterations:t.maxIterations,permissionMode:t.permissionMode??"bypassPermissions",harness:s,loopMode:i,completionPromise:t.completionPromise,originChannel:k,originThreadId:m?.threadId,originAgentId:e.agentId||void 0,originSessionKey:f,route:m,verifierCommands:o}}function wo(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(`
130
- `)}function yh(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function Xl(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(!Z)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!yh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=vo({goal:n.goal,verifierCommands:n.verifier_commands,name:n.name,workdir:n.workdir,model:n.model,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,maxIterations:n.max_iterations,permissionMode:n.permission_mode,harness:n.harness,goalMode:n.goal_mode,completionPromise:n.completion_promise},t);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};try{let o=await Z.launchTask({goal:r.goal,name:r.name,workdir:r.workdir,model:r.model,reasoningEffort:r.reasoningEffort,fastMode:r.fastMode,systemPrompt:r.systemPrompt,allowedTools:r.allowedTools,maxIterations:r.maxIterations,permissionMode:r.permissionMode,loopMode:r.loopMode,completionPromise:r.completionPromise,originChannel:r.originChannel,originThreadId:r.originThreadId,originAgentId:r.originAgentId,originSessionKey:r.originSessionKey,route:r.route,harness:r.harness,verifierCommands:r.verifierCommands});return{content:[{type:"text",text:wo(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}se();function Ns(t,e){return t.split(`
131
- `).map(n=>`${e}${n}`)}function eu(t,e){return t.length<=e?t:`${t.slice(0,e-3).trimEnd()}...`}function kh(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(`
132
- `);return o.length<=n?o:`...${o.slice(-(n-3))}`}function Sh(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=>eu(o,180))}function vh(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=>eu(n,180))}function Po(t){let e=[],n=vh(t.verifierSummary),r=Sh(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(`
133
- `)}function Ws(t){if(t)return{phase:t.phase,awaitingInput:t.isAwaitingInput??!!t.pendingInputState,latestOutput:kh(t.getOutput(20))}}function Ls(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(...Ns(n," ")),t.lastVerifierSummary&&(o.push(" Last verifier:"),o.push(...Ns(t.lastVerifierSummary," "))),e?.latestOutput&&(o.push(" Latest activity:"),o.push(...Ns(e.latestOutput," "))),t.waitingForUserReason&&o.push(` Waiting on user: ${t.waitingForUserReason}`),t.failureReason&&o.push(` Failure: ${t.failureReason}`),o.join(`
134
- `)}var Me="Error: GoalController not initialized. The code-agent service must be running.";function bo(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 Ls(i,Ws(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 Ls(i,Ws(s))}).join(`
127
+ `);try{let w=v.spawn({prompt:h,workdir:l,name:`${n.session}-conflict-resolver`,harness:me(),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:Be(`⚠️ Merge conflicts in ${T.conflictFiles.length} file(s) — spawned conflict resolver session: ${w.name}`,T)}]}}catch(w){S={content:[{type:"text",text:Be(`❌ Merge conflicts detected, but failed to spawn resolver: ${w instanceof Error?w.message:String(w)}`,T)}]}}}else{let h=T.dirtyError?`❌ Merge blocked: ${T.error}`:`❌ Merge failed: ${T.error??"unknown error"}`;S={content:[{type:"text",text:Be(h,T)}]}}}),S}}}So();se();V();ne();Re();Nn();function fh(t){return!!t&&typeof t=="object"}function Yl(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(!fh(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=ao(v);if(r&&(a=a.filter(k=>lo(k,r)),a.length===0)){let k=tn(v,r);if(!k.persistedSession&&!k.activeSession)return{content:[{type:"text",text:`Error: Session "${r}" not found.`}]}}if(n.workdir&&(a=a.filter(k=>k.workdir===n.workdir)),a.length===0)return{content:[{type:"text",text:"No managed worktrees matched the requested scope."}]};let d=[],l=[],u=[],f=[];for(let k of a){let{persistedSession:m,activeSession:c,resolvedLifecycle:y}=so(v,k,{baseBranch:n.base_branch});if(!y.cleanupSafe){if(s){let S=y.reasons.length>0?y.reasons.map(uo).join(", "):At(y.derivedState);l.push(`${k.name} [kept: ${S}]`)}continue}if(d.push(`${k.name} (${At(y.derivedState)})`),!i)try{let S=k.workdir;if(!((m??c)&&le(m??c))&&k.worktreePath&&ce(S,k.worktreePath,{destructive:!1}),k.worktreeBranch&&Pe(S,k.worktreeBranch),m){let x=y.derivedState==="merged"||y.derivedState==="released"?y.derivedState:y.lifecycle.state,T=new Date().toISOString(),A=x==="merged"?m.worktreeMergedAt:x==="dismissed"?m.worktreeDismissedAt:void 0;v.updatePersistedSession(k.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeMerged:x==="merged"?!0:m.worktreeMerged,worktreeMergedAt:x==="merged"?m.worktreeMergedAt??T:m.worktreeMergedAt,worktreeLifecycle:{...m.worktreeLifecycle??y.lifecycle,state:x,updatedAt:T,resolvedAt:m.worktreeLifecycle?.resolvedAt??A??T,resolutionSource:m.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??y.lifecycle.baseBranch??m.worktreeBaseBranch,targetRepo:m.worktreePrTargetRepo,pushRemote:m.worktreePushRemote,notes:y.reasons}})}u.push(`${k.name} (${At(y.derivedState)})`)}catch(S){f.push(`${k.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 (${f.length}): ${f.join(", ")||"(none)"}`)),{content:[{type:"text",text:p.join(`
128
+ `)}]}}}}se();V();Nn();function gh(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 Zl(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(!gh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n&&typeof n=="object"?n.session:void 0,o=ao(v);if(r&&(o=o.filter(s=>lo(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}=so(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:${At(d.lifecycle.state)}`),d.derivedState!==d.lifecycle.state&&i.push(` Derived: ${At(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(uo).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
129
+ `).trim()}]}}}}se();V();ae();hr();import{existsSync as hh}from"fs";function yh(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function vo(t,e){let n=t.goal.trim();if(!n)return{kind:"error",text:"Error: goal must not be empty."};let r=t.workdir||e.workspaceDir||D.defaultWorkdir||process.cwd();if(!hh(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=yh(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??me(),a=t.model??Nt(s),d=je(s,a),l=tr(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&&!Gt(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&&!fr(s,d,l))return{kind:"error",text:`Error: Model "${a}" is not allowed. Permitted models: ${l?.join(", ")}`};let u=gr(s,d,l),f=e.sessionKey||void 0,p=nr(e),k=yn(e,p||gt(r)),m=Lt(e,k,f);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:u,reasoningEffort:rt(s),fastMode:Wt(s),systemPrompt:t.systemPrompt,allowedTools:t.allowedTools,maxIterations:t.maxIterations,permissionMode:t.permissionMode??"bypassPermissions",harness:s,loopMode:i,completionPromise:t.completionPromise,originChannel:k,originThreadId:m?.threadId,originAgentId:e.agentId||void 0,originSessionKey:f,route:m,verifierCommands:o}}function wo(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(`
130
+ `)}function kh(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function Xl(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(!Z)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!kh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=vo({goal:n.goal,verifierCommands:n.verifier_commands,name:n.name,workdir:n.workdir,model:n.model,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,maxIterations:n.max_iterations,permissionMode:n.permission_mode,harness:n.harness,goalMode:n.goal_mode,completionPromise:n.completion_promise},t);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};try{let o=await Z.launchTask({goal:r.goal,name:r.name,workdir:r.workdir,model:r.model,reasoningEffort:r.reasoningEffort,fastMode:r.fastMode,systemPrompt:r.systemPrompt,allowedTools:r.allowedTools,maxIterations:r.maxIterations,permissionMode:r.permissionMode,loopMode:r.loopMode,completionPromise:r.completionPromise,originChannel:r.originChannel,originThreadId:r.originThreadId,originAgentId:r.originAgentId,originSessionKey:r.originSessionKey,route:r.route,harness:r.harness,verifierCommands:r.verifierCommands});return{content:[{type:"text",text:wo(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}se();function Ls(t,e){return t.split(`
131
+ `).map(n=>`${e}${n}`)}function eu(t,e){return t.length<=e?t:`${t.slice(0,e-3).trimEnd()}...`}function Sh(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(`
132
+ `);return o.length<=n?o:`...${o.slice(-(n-3))}`}function vh(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=>eu(o,180))}function wh(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=>eu(n,180))}function Po(t){let e=[],n=wh(t.verifierSummary),r=vh(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(`
133
+ `)}function Bs(t){if(t)return{phase:t.phase,awaitingInput:t.isAwaitingInput??!!t.pendingInputState,latestOutput:Sh(t.getOutput(20))}}function Fs(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(...Ls(n," ")),t.lastVerifierSummary&&(o.push(" Last verifier:"),o.push(...Ls(t.lastVerifierSummary," "))),e?.latestOutput&&(o.push(" Latest activity:"),o.push(...Ls(e.latestOutput," "))),t.waitingForUserReason&&o.push(` Waiting on user: ${t.waitingForUserReason}`),t.failureReason&&o.push(` Failure: ${t.failureReason}`),o.join(`
134
+ `)}var Me="Error: GoalController not initialized. The code-agent service must be running.";function bo(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 Fs(i,Bs(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 Fs(i,Bs(s))}).join(`
135
135
 
136
- `)}function Ro(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 Ao(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.`}}V();function tu(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(!Z)return{content:[{type:"text",text:Me}]};let r=n&&typeof n=="object"&&typeof n.task=="string"?n.task:void 0;return{content:[{type:"text",text:bo(Z,o=>v?.resolve(o),r)}]}}}}se();V();function wh(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function nu(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(!Z)return{content:[{type:"text",text:Me}]};if(!wh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=Z.stopTask(n.task);return{content:[{type:"text",text:Ro(r,n.task)}]}}}}se();V();function Ph(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function ru(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(!Z)return{content:[{type:"text",text:Me}]};if(!Ph(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=Z.editTask(n.task,n.goal);return{content:[{type:"text",text:Ao(r,n.task)}]}}}}V();So();var Bs=new Set,ou="⚠️ Could not submit that answer. The question prompt is still active; try again or reply with the answer.",Kn=new Map;function bh(t){return`${t.sessionId}:${t.pendingInputRequestId??t.id}`}function Rh(t){return!!(t&&t.status!=="running"&&kt(t).kind==="resume")}function Ah(t){return t.label?.trim()?["[SYSTEM: The gateway restarted while a user question was pending. Treat the user's selection below as the answer to that interrupted question and continue without asking it again.]","",t.pendingInputQuestionId?`Question ID: ${t.pendingInputQuestionId}`:"Question: the interrupted pending question",`Selected answer: ${t.label.trim()}`].join(`
137
- `):void 0}async function du(t){try{await t}catch(e){let n=e instanceof Error?e.message:String(e);`${n}`}}async function iu(t,e,n){if(!t)return n();for(;;){let o=Kn.get(t)?.operation;if(!o)break;await du(o)}let r=Promise.resolve().then(n);Kn.set(t,{operation:r,tokenId:e});try{return await r}finally{Kn.get(t)?.operation===r&&Kn.delete(t)}}function Ih(t){let e=t.trim().replace(new RegExp(`^${re}:`),"");return e||null}function xh(t){return t.trim().startsWith(`${re}:`)}async function Io(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(Tt(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 To(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 su(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return Us(To(t))}function Us(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function Co(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function Th(t){if(Co(t.kind))return`${t.sessionId}:v${t.planDecisionVersion??"unknown"}`}function Ch(t){return t?t.approvalState==="approved"||!t.pendingPlanApproval:!1}function Mh(...t){let e;for(let n of t)n!=null&&(e=e==null?n:Math.max(e,n));return e}function _h(t){if(t.actionablePlanDecisionVersion!=null)return t.actionablePlanDecisionVersion;let e=Mh(t.approvalPromptRequiredVersion,t.approvalPromptVersion);return e??t.canonicalPlanPromptVersion??t.planDecisionVersion}function Fs(t,e){if(!Co(t.kind))return;if(!e)return"This plan decision is stale because the session is no longer available.";let n=_h(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 lu(t,...e){return e.find(n=>typeof n=="string"&&t(n))}function xo(...t){return lu(e=>e.trim().length>0,...t)}function au(...t){return lu(xh,...t)}function $h(t){let e="callback"in t?au(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=au(n?.data,n?.callback_data,n?.callbackData);if(r)return r;let o="callback"in t?xo(t.callback?.payload):void 0;if(o)return o;let i=xo(n?.payload);return i||(("callback"in t?xo(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0)??xo(n?.data,n?.callback_data,n?.callbackData)??"")}function Vn(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,Vn(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,Vn(n.cause,e),Vn(n.response,e),Vn(n.payload,e)].filter(Boolean).join(" ")}function Tt(t){return/message is not modified/i.test(Vn(t))}function Eh(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function xt(t){if(typeof t.clearButtons=="function")try{await t.clearButtons()}catch(e){if(Tt(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 xt(n),{textDelivered:!0}}catch(a){if(Tt(a))return await xt(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 xt(n),{textDelivered:!1}}catch(a){if(Tt(a))return await xt(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 xt(n),{textDelivered:!1}}catch(a){if(Tt(a))return await xt(n),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}return await xt(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(Tt(s))return{textDelivered:typeof i=="string"};if(Eh(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(Tt(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 Dh(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 $(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}var qs=["plan-approve","plan-request-changes","plan-reject"];function Oh(t){switch(t){case"plan-approve":return"Approve";case"plan-request-changes":return"Revise";case"plan-reject":return"Reject";default:return"Continue"}}function Nh(t){switch(t){case"plan-approve":return"primary";case"plan-reject":return"danger";default:return"secondary"}}function Wh(t,e){let n=t,o=(typeof n?.listActiveActionTokens=="function"?qs.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)=>qs.indexOf(a.kind)-qs.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:Oh(a.kind),callbackData:`${re}:${a.id}`,style:Nh(a.kind)}));return s.length>0?[s]:void 0}async function Lh(t,e,n,r){if(t.channel!=="telegram"){await $(t,e);return}let o=Wh(n,r);await t.respond.reply({text:o?`${e}
136
+ `)}function Ro(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 Ao(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.`}}V();function tu(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(!Z)return{content:[{type:"text",text:Me}]};let r=n&&typeof n=="object"&&typeof n.task=="string"?n.task:void 0;return{content:[{type:"text",text:bo(Z,o=>v?.resolve(o),r)}]}}}}se();V();function Ph(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function nu(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(!Z)return{content:[{type:"text",text:Me}]};if(!Ph(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=Z.stopTask(n.task);return{content:[{type:"text",text:Ro(r,n.task)}]}}}}se();V();function bh(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function ru(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(!Z)return{content:[{type:"text",text:Me}]};if(!bh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=Z.editTask(n.task,n.goal);return{content:[{type:"text",text:Ao(r,n.task)}]}}}}V();So();var qs=new Set,ou="⚠️ Could not submit that answer. The question prompt is still active; try again or reply with the answer.",Kn=new Map;function Rh(t){return`${t.sessionId}:${t.pendingInputRequestId??t.id}`}function Ah(t){return!!(t&&t.status!=="running"&&kt(t).kind==="resume")}function Ih(t){return t.label?.trim()?["[SYSTEM: The gateway restarted while a user question was pending. Treat the user's selection below as the answer to that interrupted question and continue without asking it again.]","",t.pendingInputQuestionId?`Question ID: ${t.pendingInputQuestionId}`:"Question: the interrupted pending question",`Selected answer: ${t.label.trim()}`].join(`
137
+ `):void 0}async function du(t){try{await t}catch(e){let n=e instanceof Error?e.message:String(e);`${n}`}}async function iu(t,e,n){if(!t)return n();for(;;){let o=Kn.get(t)?.operation;if(!o)break;await du(o)}let r=Promise.resolve().then(n);Kn.set(t,{operation:r,tokenId:e});try{return await r}finally{Kn.get(t)?.operation===r&&Kn.delete(t)}}function xh(t){let e=t.trim().replace(new RegExp(`^${re}:`),"");return e||null}function Th(t){return t.trim().startsWith(`${re}:`)}async function Io(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(Tt(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 To(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 su(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return Vs(To(t))}function Vs(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function Co(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function Ch(t){if(Co(t.kind))return`${t.sessionId}:v${t.planDecisionVersion??"unknown"}`}function Mh(t){return t?t.approvalState==="approved"||!t.pendingPlanApproval:!1}function _h(...t){let e;for(let n of t)n!=null&&(e=e==null?n:Math.max(e,n));return e}function $h(t){if(t.actionablePlanDecisionVersion!=null)return t.actionablePlanDecisionVersion;let e=_h(t.approvalPromptRequiredVersion,t.approvalPromptVersion);return e??t.canonicalPlanPromptVersion??t.planDecisionVersion}function Us(t,e){if(!Co(t.kind))return;if(!e)return"This plan decision is stale because the session is no longer available.";let n=$h(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 lu(t,...e){return e.find(n=>typeof n=="string"&&t(n))}function xo(...t){return lu(e=>e.trim().length>0,...t)}function au(...t){return lu(Th,...t)}function Eh(t){let e="callback"in t?au(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=au(n?.data,n?.callback_data,n?.callbackData);if(r)return r;let o="callback"in t?xo(t.callback?.payload):void 0;if(o)return o;let i=xo(n?.payload);return i||(("callback"in t?xo(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0)??xo(n?.data,n?.callback_data,n?.callbackData)??"")}function Vn(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,Vn(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,Vn(n.cause,e),Vn(n.response,e),Vn(n.payload,e)].filter(Boolean).join(" ")}function Tt(t){return/message is not modified/i.test(Vn(t))}function Dh(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function xt(t){if(typeof t.clearButtons=="function")try{await t.clearButtons()}catch(e){if(Tt(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 xt(n),{textDelivered:!0}}catch(a){if(Tt(a))return await xt(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 xt(n),{textDelivered:!1}}catch(a){if(Tt(a))return await xt(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 xt(n),{textDelivered:!1}}catch(a){if(Tt(a))return await xt(n),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}return await xt(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(Tt(s))return{textDelivered:typeof i=="string"};if(Dh(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(Tt(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 Oh(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 $(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}var Ks=["plan-approve","plan-request-changes","plan-reject"];function Nh(t){switch(t){case"plan-approve":return"Approve";case"plan-request-changes":return"Revise";case"plan-reject":return"Reject";default:return"Continue"}}function Wh(t){switch(t){case"plan-approve":return"primary";case"plan-reject":return"danger";default:return"secondary"}}function Lh(t,e){let n=t,o=(typeof n?.listActiveActionTokens=="function"?Ks.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)=>Ks.indexOf(a.kind)-Ks.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:Nh(a.kind),callbackData:`${re}:${a.id}`,style:Wh(a.kind)}));return s.length>0?[s]:void 0}async function Bh(t,e,n,r){if(t.channel!=="telegram"){await $(t,e);return}let o=Lh(n,r);await t.respond.reply({text:o?`${e}
138
138
 
139
- Approval is still pending. Try again below.`:e,...o?{buttons:o}:{}})}function uu(t="telegram",e={}){let n=e.makeAgentMergeTool??po,r=e.makeAgentPrTool??Un;return U("callback_handler_registered",{channel:t,namespace:re}),{channel:t,namespace:re,handler:async o=>{let i=await Dh(o);if(!o.auth.isAuthorizedSender)return await $(o,"⛔ Unauthorized."),{handled:!0};let s=$h(o),a=Ih(s);if(U("callback_received",{channel:o.channel,namespace:re,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:Ie(a),isAuthorizedSender:o.auth.isAuthorizedSender}),!a)return await $(o,"⚠️ Unrecognized callback payload."),{handled:!0};if(!v)return await $(o,"⚠️ Code agent service not running."),{handled:!0};let d=v.getActionToken(a);if(U("callback_token_lookup_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),tokenFound:!!d,actionKind:d?.kind,sessionId:d?.sessionId,planDecisionVersion:d?.planDecisionVersion}),!d)return await z(o,{alreadyAcknowledged:i}),o.channel!=="telegram"&&await $(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,"⚠️ 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),f=u?.name??l,p=Fs(d,u);if(U("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),actionKind:d.kind,sessionId:l,sessionName:f,planDecisionVersion:d.planDecisionVersion,valid:!p}),p)return Co(d.kind)?await Je(o,i):await z(o,{alreadyAcknowledged:i}),await $(o,`⚠️ ${p}`),{handled:!0};if(d.kind==="question-answer"){if(d.optionIndex==null)return await z(o,{alreadyAcknowledged:i}),await $(o,"⚠️ Invalid question-answer action."),{handled:!0};let c=bh(d);if(Bs.has(c))return await $(o,"⚠️ That answer is already being submitted. If the question remains active, try again."),{handled:!0};Bs.add(c);let y=!1,S=!1;try{if(y=await v.resolvePendingInputOption(l,d.optionIndex,{requestId:d.pendingInputRequestId,questionId:d.pendingInputQuestionId}),!y&&!(v.canSubmitPendingInputOption?.(l)??!1)){let T=v.getPersistedSession?.(l),A=Ah(d);A&&Rh(T)&&(y=!(await Ae(v,{session:l,message:A,userInitiated:!0})).isError,S=y)}}catch(T){let A=T instanceof Error?T.message:String(T);return`${A}`,await $(o,ou),{handled:!0}}finally{Bs.delete(c)}if(!y)return await $(o,ou),{handled:!0};let x=(d.pendingInputRequestId?v.consumeQuestionAnswerTokens(l,d.pendingInputRequestId):[]).find(T=>T.id===a)??v.consumeActionToken(a);return U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!x,actionKind:x?.kind,sessionId:x?.sessionId,planDecisionVersion:x?.planDecisionVersion}),x?(await z(o,{alreadyAcknowledged:i}),await $(o,S?"✅ Answer forwarded to the resumed session.":"✅ Answer submitted."),{handled:!0}):(await z(o,{alreadyAcknowledged:i}),await $(o,S?"✅ Answer forwarded to the resumed session.":"✅ Answer submitted."),{handled:!0})}let k=Th(d);if(k)for(;;){let c=Kn.get(k);if(!c)break;if(c.tokenId===a)return await Je(o,i),await $(o,"⚠️ This plan decision is already being processed."),{handled:!0};await du(c.operation);let y=v.getActionToken(a);if(!y)return await Je(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(l=y.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l,p=Fs(y,u),U("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),actionKind:y.kind,sessionId:l,sessionName:f,planDecisionVersion:y.planDecisionVersion,valid:!p,afterPlanDecisionLock:!0}),p)return await Je(o,i),await $(o,`⚠️ ${p}`),{handled:!0};d=y}if(d.kind==="plan-approve"){let c=d,y=!1,S=async(T=!1)=>{y||!T&&o.channel!=="telegram"||(await Je(o,i),y=!0)},b=await iu(k,a,async()=>(await S(),Ae(v,{session:c.sessionId,message:"Approved. Go ahead.",approve:!0,userInitiated:!0})));if(b.isError){let T=v.resolve?.(c.sessionId)??v.getPersistedSession?.(c.sessionId),A=Ch(T);if(A){let h=v.consumeActionToken(a);U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!h,actionKind:h?.kind,sessionId:h?.sessionId??c.sessionId,planDecisionVersion:h?.planDecisionVersion,approvalAppliedAfterError:!0}),await S(!0)}return A?await $(o,`⚠️ ${b.text}`):await Lh(o,`⚠️ ${b.text}`,v,c),{handled:!0}}let x=v.consumeActionToken(a);return U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!x,actionKind:x?.kind,sessionId:x?.sessionId??c.sessionId,planDecisionVersion:x?.planDecisionVersion}),x?(await S(!0),{handled:!0}):(await S(!0),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0})}if(d.kind==="plan-reject"||d.kind==="plan-request-changes")return await iu(k,a,async()=>{let c=v.getActionToken(a);if(!c)return await Je(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};l=c.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l;let y=Fs(c,u);if(U("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),actionKind:c.kind,sessionId:l,sessionName:f,planDecisionVersion:c.planDecisionVersion,valid:!y,afterPlanDecisionLock:!0}),y)return await Je(o,i),await $(o,`⚠️ ${y}`),{handled:!0};let S=v.consumeActionToken(a);if(U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!S,actionKind:S?.kind,sessionId:S?.sessionId,planDecisionVersion:S?.planDecisionVersion}),!S)return await Je(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(await Je(o,i),S.kind==="plan-reject"){let b=hs(v,l);await $(o,`❌ ${b.text}`)}else{let b=ys(v,l);await $(o,`✏️ ${b.text}`)}return{handled:!0}});let m=v.consumeActionToken(a);if(U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!m,actionKind:m?.kind,sessionId:m?.sessionId,planDecisionVersion:m?.planDecisionVersion}),!m)return await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:d.kind==="plan-offer-start"||d.kind==="plan-offer-dismiss"}),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};switch(m.kind){case"plugin-update-install":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),!Oe){await $(o,"⚠️ OCA update service is not running.");break}try{let c=await Oe.installConfirmed(m.pluginUpdateVersion,{route:m.route});await $(o,`✅ ${c}`)}catch(c){await $(o,`⚠️ OCA update failed: ${c instanceof Error?c.message:String(c)}`)}break}case"plugin-update-restart":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),!Oe){await $(o,"⚠️ OCA update service is not running.");break}try{let c=await Oe.restartConfirmed(m.pluginUpdateVersion);await $(o,`▶️ ${c}`)}catch(c){await $(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=Oe?Oe.dismiss(m.pluginUpdateVersion):"Dismissed OCA update reminder.";await $(o,`✅ ${c}`);break}case"plugin-update-remind-later":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0});let c=Oe?Oe.remindLater(m.pluginUpdateVersion):"Will remind later about OCA update reminder.";await $(o,`✅ ${c}`);break}case"worktree-merge":{let c=await n().execute("callback",{session:l}),y=To(c);if(su(c)){await Io(o,i);break}await $(o,y);break}case"worktree-decide-later":{let c=v.snoozeWorktreeDecision(l,{notifyUser:!1});if(Us(c)){let S=`⏭️ Snoozed 24h for [${f}]`;await Io(o,i),await $(o,S)}else await $(o,c);break}case"worktree-dismiss":{let c=await v.dismissWorktree(l),y=Us(c);y&&await Io(o,i),await $(o,y?"✅ Discarded":c);break}case"worktree-create-pr":case"worktree-update-pr":{let c=await r().execute("callback",{session:l}),y=To(c);if(su(c)){await Io(o,i);break}await $(o,y);break}case"worktree-view-pr":{await z(o,{alreadyAcknowledged:i});let c=v.getPersistedSession?.(l),y=d.targetUrl??c?.worktreePrUrl;await $(o,y?`PR: ${y}`:"⚠️ PR URL is no longer available.");break}case"plan-offer-start":{if(!m.launchPrompt||!m.launchWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the plan launch context.");break}let c;try{c=v.launchPlanOffer({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,worktreeStrategy:m.launchWorktreeStrategy})}catch(y){let S=y instanceof Error?y.message:String(y);await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Failed to start planning session: ${S}`);break}await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`▶️ Planning session started: ${c.name} [${c.id}]`);break}case"plan-offer-dismiss":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!m.repoPolicy||!m.repoPolicyWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the repo policy context.");break}if(!m.launchPrompt||!m.launchWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(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=Xt(m.repoPolicy,S.prAvailable);if(b){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ ${b}`);break}}}let c=v.setRepoPolicy(m.repoPolicyWorkdir,m.repoPolicy);if(!c){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Could not resolve a git repository for ${m.repoPolicyWorkdir}.`);break}v.clearRepoPolicyChoiceTokens(m.sessionId);let y;try{y=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,resumedFromSessionName:m.launchResumedFromSessionName,resumeWorktreeFrom:m.launchResumeWorktreeFrom,sessionIdOverride:m.launchSessionIdOverride,clearedPersistedCodexResume:m.launchClearedPersistedCodexResume,forkSession:m.launchForkSession,forceNewSession:m.launchForceNewSession,permissionMode:m.launchPermissionMode,planApproval:m.launchPlanApproval,harness:m.launchHarness,worktreeStrategy:m.launchWorktreeStrategy,worktreeBaseBranch:m.launchWorktreeBaseBranch,worktreePrTargetRepo:m.launchWorktreePrTargetRepo,originAgentId:m.launchOriginAgentId}).text}catch(S){let b=S instanceof Error?S.message:String(S);await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Repo policy saved, but launch failed: ${b}`);break}await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,[`✅ Repo policy saved: ${Ml(c.policy).title}.`,"",y].join(`
140
- `));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,c.isError?`⚠️ ${c.text}`:`▶️ ${c.text}`);break}case"view-output":{await z(o,{alreadyAcknowledged:i});let c=await to().execute("callback",{session:l,lines:50});await $(o,To(c));break}default:{await z(o,{alreadyAcknowledged:i}),await $(o,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}V();ae();function nn(t){return cu(t).map(e=>e.value)}function cu(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:Bh(n),raw:n,start:r,end:r+n.length}})}function Ct(t){let[e]=cu(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function Bh(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function Fh(t){return t instanceof Error?t.message:String(t)}function qh(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 pu(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}=qh(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=Rr({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:_r(e)});return{text:v.formatLaunchResult({prompt:o,workdir:i.workdir,harness:i.harness,permissionMode:i.permissionMode??D.permissionMode,planApproval:i.planApproval},s)}}catch(i){let s=Fh(i),a=s.includes("Max sessions")?"":`
139
+ Approval is still pending. Try again below.`:e,...o?{buttons:o}:{}})}function uu(t="telegram",e={}){let n=e.makeAgentMergeTool??po,r=e.makeAgentPrTool??Un;return U("callback_handler_registered",{channel:t,namespace:re}),{channel:t,namespace:re,handler:async o=>{let i=await Oh(o);if(!o.auth.isAuthorizedSender)return await $(o,"⛔ Unauthorized."),{handled:!0};let s=Eh(o),a=xh(s);if(U("callback_received",{channel:o.channel,namespace:re,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:Ie(a),isAuthorizedSender:o.auth.isAuthorizedSender}),!a)return await $(o,"⚠️ Unrecognized callback payload."),{handled:!0};if(!v)return await $(o,"⚠️ Code agent service not running."),{handled:!0};let d=v.getActionToken(a);if(U("callback_token_lookup_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),tokenFound:!!d,actionKind:d?.kind,sessionId:d?.sessionId,planDecisionVersion:d?.planDecisionVersion}),!d)return await z(o,{alreadyAcknowledged:i}),o.channel!=="telegram"&&await $(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,"⚠️ 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),f=u?.name??l,p=Us(d,u);if(U("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),actionKind:d.kind,sessionId:l,sessionName:f,planDecisionVersion:d.planDecisionVersion,valid:!p}),p)return Co(d.kind)?await Je(o,i):await z(o,{alreadyAcknowledged:i}),await $(o,`⚠️ ${p}`),{handled:!0};if(d.kind==="question-answer"){if(d.optionIndex==null)return await z(o,{alreadyAcknowledged:i}),await $(o,"⚠️ Invalid question-answer action."),{handled:!0};let c=Rh(d);if(qs.has(c))return await $(o,"⚠️ That answer is already being submitted. If the question remains active, try again."),{handled:!0};qs.add(c);let y=!1,S=!1;try{if(y=await v.resolvePendingInputOption(l,d.optionIndex,{requestId:d.pendingInputRequestId,questionId:d.pendingInputQuestionId}),!y&&!(v.canSubmitPendingInputOption?.(l)??!1)){let T=v.getPersistedSession?.(l),A=Ih(d);A&&Ah(T)&&(y=!(await Ae(v,{session:l,message:A,userInitiated:!0})).isError,S=y)}}catch(T){let A=T instanceof Error?T.message:String(T);return`${A}`,await $(o,ou),{handled:!0}}finally{qs.delete(c)}if(!y)return await $(o,ou),{handled:!0};let x=(d.pendingInputRequestId?v.consumeQuestionAnswerTokens(l,d.pendingInputRequestId):[]).find(T=>T.id===a)??v.consumeActionToken(a);return U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!x,actionKind:x?.kind,sessionId:x?.sessionId,planDecisionVersion:x?.planDecisionVersion}),x?(await z(o,{alreadyAcknowledged:i}),await $(o,S?"✅ Answer forwarded to the resumed session.":"✅ Answer submitted."),{handled:!0}):(await z(o,{alreadyAcknowledged:i}),await $(o,S?"✅ Answer forwarded to the resumed session.":"✅ Answer submitted."),{handled:!0})}let k=Ch(d);if(k)for(;;){let c=Kn.get(k);if(!c)break;if(c.tokenId===a)return await Je(o,i),await $(o,"⚠️ This plan decision is already being processed."),{handled:!0};await du(c.operation);let y=v.getActionToken(a);if(!y)return await Je(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(l=y.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l,p=Us(y,u),U("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),actionKind:y.kind,sessionId:l,sessionName:f,planDecisionVersion:y.planDecisionVersion,valid:!p,afterPlanDecisionLock:!0}),p)return await Je(o,i),await $(o,`⚠️ ${p}`),{handled:!0};d=y}if(d.kind==="plan-approve"){let c=d,y=!1,S=async(T=!1)=>{y||!T&&o.channel!=="telegram"||(await Je(o,i),y=!0)},b=await iu(k,a,async()=>(await S(),Ae(v,{session:c.sessionId,message:"Approved. Go ahead.",approve:!0,userInitiated:!0})));if(b.isError){let T=v.resolve?.(c.sessionId)??v.getPersistedSession?.(c.sessionId),A=Mh(T);if(A){let h=v.consumeActionToken(a);U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!h,actionKind:h?.kind,sessionId:h?.sessionId??c.sessionId,planDecisionVersion:h?.planDecisionVersion,approvalAppliedAfterError:!0}),await S(!0)}return A?await $(o,`⚠️ ${b.text}`):await Bh(o,`⚠️ ${b.text}`,v,c),{handled:!0}}let x=v.consumeActionToken(a);return U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!x,actionKind:x?.kind,sessionId:x?.sessionId??c.sessionId,planDecisionVersion:x?.planDecisionVersion}),x?(await S(!0),{handled:!0}):(await S(!0),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0})}if(d.kind==="plan-reject"||d.kind==="plan-request-changes")return await iu(k,a,async()=>{let c=v.getActionToken(a);if(!c)return await Je(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};l=c.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l;let y=Us(c,u);if(U("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),actionKind:c.kind,sessionId:l,sessionName:f,planDecisionVersion:c.planDecisionVersion,valid:!y,afterPlanDecisionLock:!0}),y)return await Je(o,i),await $(o,`⚠️ ${y}`),{handled:!0};let S=v.consumeActionToken(a);if(U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!S,actionKind:S?.kind,sessionId:S?.sessionId,planDecisionVersion:S?.planDecisionVersion}),!S)return await Je(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(await Je(o,i),S.kind==="plan-reject"){let b=ks(v,l);await $(o,`❌ ${b.text}`)}else{let b=Ss(v,l);await $(o,`✏️ ${b.text}`)}return{handled:!0}});let m=v.consumeActionToken(a);if(U("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:Ie(a),consumed:!!m,actionKind:m?.kind,sessionId:m?.sessionId,planDecisionVersion:m?.planDecisionVersion}),!m)return await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:d.kind==="plan-offer-start"||d.kind==="plan-offer-dismiss"}),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};switch(m.kind){case"plugin-update-install":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),!Oe){await $(o,"⚠️ OCA update service is not running.");break}try{let c=await Oe.installConfirmed(m.pluginUpdateVersion,{route:m.route});await $(o,`✅ ${c}`)}catch(c){await $(o,`⚠️ OCA update failed: ${c instanceof Error?c.message:String(c)}`)}break}case"plugin-update-restart":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),!Oe){await $(o,"⚠️ OCA update service is not running.");break}try{let c=await Oe.restartConfirmed(m.pluginUpdateVersion);await $(o,`▶️ ${c}`)}catch(c){await $(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=Oe?Oe.dismiss(m.pluginUpdateVersion):"Dismissed OCA update reminder.";await $(o,`✅ ${c}`);break}case"plugin-update-remind-later":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0});let c=Oe?Oe.remindLater(m.pluginUpdateVersion):"Will remind later about OCA update reminder.";await $(o,`✅ ${c}`);break}case"worktree-merge":{let c=await n().execute("callback",{session:l}),y=To(c);if(su(c)){await Io(o,i);break}await $(o,y);break}case"worktree-decide-later":{let c=v.snoozeWorktreeDecision(l,{notifyUser:!1});if(Vs(c)){let S=`⏭️ Snoozed 24h for [${f}]`;await Io(o,i),await $(o,S)}else await $(o,c);break}case"worktree-dismiss":{let c=await v.dismissWorktree(l),y=Vs(c);y&&await Io(o,i),await $(o,y?"✅ Discarded":c);break}case"worktree-create-pr":case"worktree-update-pr":{let c=await r().execute("callback",{session:l}),y=To(c);if(su(c)){await Io(o,i);break}await $(o,y);break}case"worktree-view-pr":{await z(o,{alreadyAcknowledged:i});let c=v.getPersistedSession?.(l),y=d.targetUrl??c?.worktreePrUrl;await $(o,y?`PR: ${y}`:"⚠️ PR URL is no longer available.");break}case"plan-offer-start":{if(!m.launchPrompt||!m.launchWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the plan launch context.");break}let c;try{c=v.launchPlanOffer({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,worktreeStrategy:m.launchWorktreeStrategy})}catch(y){let S=y instanceof Error?y.message:String(y);await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Failed to start planning session: ${S}`);break}await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`▶️ Planning session started: ${c.name} [${c.id}]`);break}case"plan-offer-dismiss":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!m.repoPolicy||!m.repoPolicyWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the repo policy context.");break}if(!m.launchPrompt||!m.launchWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(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=Xt(m.repoPolicy,S.prAvailable);if(b){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ ${b}`);break}}}let c=v.setRepoPolicy(m.repoPolicyWorkdir,m.repoPolicy);if(!c){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Could not resolve a git repository for ${m.repoPolicyWorkdir}.`);break}v.clearRepoPolicyChoiceTokens(m.sessionId);let y;try{y=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,resumedFromSessionName:m.launchResumedFromSessionName,resumeWorktreeFrom:m.launchResumeWorktreeFrom,sessionIdOverride:m.launchSessionIdOverride,clearedPersistedCodexResume:m.launchClearedPersistedCodexResume,forkSession:m.launchForkSession,forceNewSession:m.launchForceNewSession,permissionMode:m.launchPermissionMode,planApproval:m.launchPlanApproval,harness:m.launchHarness,worktreeStrategy:m.launchWorktreeStrategy,worktreeBaseBranch:m.launchWorktreeBaseBranch,worktreePrTargetRepo:m.launchWorktreePrTargetRepo,originAgentId:m.launchOriginAgentId}).text}catch(S){let b=S instanceof Error?S.message:String(S);await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Repo policy saved, but launch failed: ${b}`);break}await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,[`✅ Repo policy saved: ${Ml(c.policy).title}.`,"",y].join(`
140
+ `));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,c.isError?`⚠️ ${c.text}`:`▶️ ${c.text}`);break}case"view-output":{await z(o,{alreadyAcknowledged:i});let c=await to().execute("callback",{session:l,lines:50});await $(o,To(c));break}default:{await z(o,{alreadyAcknowledged:i}),await $(o,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}V();ae();function nn(t){return cu(t).map(e=>e.value)}function cu(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:Fh(n),raw:n,start:r,end:r+n.length}})}function Ct(t){let[e]=cu(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function Fh(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function qh(t){return t instanceof Error?t.message:String(t)}function Uh(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 pu(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}=Uh(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=Rr({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:_r(e)});return{text:v.formatLaunchResult({prompt:o,workdir:i.workdir,harness:i.harness,permissionMode:i.permissionMode??D.permissionMode,planApproval:i.planApproval},s)}}catch(i){let s=qh(i),a=s.includes("Max sessions")?"":`
141
141
 
142
142
  Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${a}`}}}})}V();function mu(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:Xr(v,"all",void 0,{full:n})}}})}V();function fu(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:eo(v,n,"killed")}:{text:"Usage: /agent_kill <name-or-id>"}}})}V();function gu(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>
143
- /agent_respond --interrupt <id-or-name> <message>`};let r=!1,o=n,i=Ct(o);i?.value==="--interrupt"&&(r=!0,o=i.rest);let s=Ct(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>"}}})}V();function hu(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:Ar(e,n)}}})}V();function Uh(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function yu(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=Ct((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(`
143
+ /agent_respond --interrupt <id-or-name> <message>`};let r=!1,o=n,i=Ct(o);i?.value==="--interrupt"&&(r=!0,o=i.rest);let s=Ct(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>"}}})}V();function hu(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:Ar(e,n)}}})}V();function Kh(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function yu(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=Ct((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(`
144
144
  `)}}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(`
145
- `)}}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&&Uh(r)){if(typeof v.resolveRepoPolicy=="function"){let l=v.resolveRepoPolicy(o);if(l.identity){let u=Xt(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(`
145
+ `)}}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&&Kh(r)){if(typeof v.resolveRepoPolicy=="function"){let l=v.resolveRepoPolicy(o);if(l.identity){let u=Xt(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(`
146
146
  `)};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(`
147
147
  `)}}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(`
148
148
  `)}}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(`
149
- `)}}})}V();var Kh=50;function ku(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=Kh;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:Zr(v,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}V();var Su="Usage: /agent_goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function vu(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(!Z)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:Su};let r=nn(n),o,i,s,a,d="bypassPermissions",l,u,f,p=[],k=[];for(let y=0;y<r.length;y++){let S=r[y];if(S==="--name"&&y+1<r.length)o=r[++y];else if(S==="--workdir"&&y+1<r.length)i=r[++y];else if(S==="--model"&&y+1<r.length)s=r[++y];else if(S==="--max-iterations"&&y+1<r.length){let b=parseInt(r[++y],10);!Number.isNaN(b)&&b>0&&(a=b)}else if(S==="--permission-mode"&&y+1<r.length){let b=r[++y];if(b==="default"||b==="plan"||b==="bypassPermissions")d=b;else return{text:`Error: Invalid permission mode "${b}".`}}else if(S==="--harness"&&y+1<r.length)l=r[++y];else if(S==="--mode"&&y+1<r.length){let b=r[++y];if(b==="ralph"||b==="verifier")u=b;else return{text:`Error: Invalid goal mode "${b}". Use ralph or verifier.`}}else if(S==="--completion-promise"&&y+1<r.length)f=r[++y];else if(S==="--verify"&&y+1<r.length){let b=r[++y].trim();if(!b)return{text:"Error: --verify commands must not be empty."};p.push(b)}else k.push(S)}let m=k.join(" ").trim();if(!m)return{text:Su};let c=vo({goal:m,verifierCommands:p,name:o,workdir:i,model:s,maxIterations:a,permissionMode:d,harness:l,goalMode:u,completionPromise:f},e);if(c.kind!=="resolved")return{text:c.text};try{let y=await Z.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:wo(y,c)}}catch(y){return{text:`Error launching goal task: ${y instanceof Error?y.message:String(y)}`}}}})}V();function wu(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(!Z)return{text:Me};let n=(e.args??"").trim();return{text:bo(Z,r=>v?.resolve(r),n)}}})}V();function Pu(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(!Z)return{text:Me};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent_goal_stop <task-id-or-name>"};let r=Z.stopTask(n);return{text:Ro(r,n)}}})}V();var bu="Usage: /agent_goal_edit <task-id-or-name> <replacement-goal>";function Ru(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(!Z)return{text:Me};let n=(e.args??"").trim();if(!n)return{text:bu};let r=Ct(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:bu};let s=Z.editTask(o,i);return{text:Ao(s,o)}}})}import{execFile as ry}from"child_process";import{createHash as Bu}from"crypto";import{existsSync as jn,mkdirSync as Vh,readFileSync as jh,renameSync as xu,writeFileSync as Gh}from"fs";import{homedir as Hh}from"os";import{dirname as zh,join as Tu}from"path";var Qh=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function Jh(t){let e=t.OPENCLAW_HOME?.trim();return e||Tu(Hh(),".openclaw")}function Yh(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||Tu(Jh(t),"code-agent-goal-tasks.json")}function Cu(t){return t instanceof Error?t.message:String(t)}function Mu(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var Zh=100;function Au(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function Xh(t){if(!jn(t))return;let e=Date.now(),n=Au(t,e);if(!jn(n))return n;for(let r=1;r<=Zh;r+=1){let o=Au(t,e,r);if(!jn(o))return o}}function Iu(t,e){try{let n=Xh(t);return n?(xu(t,n),`${e}${n}`,!0):(jn(t),!1)}catch(n){return`${Cu(n)}`,!1}}function ey(t){if(!Mu(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 ty(t){if(!Mu(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"||!Qh.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:ey(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 ny(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=ty(n);if(!r)return;e.push(r)}return e}var Mo=class{path;tasks=new Map;constructor(e=process.env){this.path=Yh(e),this.load()}load(){try{if(!jn(this.path))return;let e=jh(this.path,"utf8"),n=JSON.parse(e),r=ny(n);if(!r){Iu(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;Iu(this.path,"corrupt or unreadable")&&this.save()}}save(){try{Vh(zh(this.path),{recursive:!0});let e=`${this.path}.tmp`;Gh(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),xu(e,this.path)}catch(e){`${this.path}${Cu(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)}};ye();var oy=8,Fu=600*1e3,iy=4e3,Ks=1200,sy="DONE",ay=["BASH_ENV","ENV"];function dy(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(`
149
+ `)}}})}V();var Vh=50;function ku(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=Vh;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:Zr(v,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}V();var Su="Usage: /agent_goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function vu(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(!Z)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:Su};let r=nn(n),o,i,s,a,d="bypassPermissions",l,u,f,p=[],k=[];for(let y=0;y<r.length;y++){let S=r[y];if(S==="--name"&&y+1<r.length)o=r[++y];else if(S==="--workdir"&&y+1<r.length)i=r[++y];else if(S==="--model"&&y+1<r.length)s=r[++y];else if(S==="--max-iterations"&&y+1<r.length){let b=parseInt(r[++y],10);!Number.isNaN(b)&&b>0&&(a=b)}else if(S==="--permission-mode"&&y+1<r.length){let b=r[++y];if(b==="default"||b==="plan"||b==="bypassPermissions")d=b;else return{text:`Error: Invalid permission mode "${b}".`}}else if(S==="--harness"&&y+1<r.length)l=r[++y];else if(S==="--mode"&&y+1<r.length){let b=r[++y];if(b==="ralph"||b==="verifier")u=b;else return{text:`Error: Invalid goal mode "${b}". Use ralph or verifier.`}}else if(S==="--completion-promise"&&y+1<r.length)f=r[++y];else if(S==="--verify"&&y+1<r.length){let b=r[++y].trim();if(!b)return{text:"Error: --verify commands must not be empty."};p.push(b)}else k.push(S)}let m=k.join(" ").trim();if(!m)return{text:Su};let c=vo({goal:m,verifierCommands:p,name:o,workdir:i,model:s,maxIterations:a,permissionMode:d,harness:l,goalMode:u,completionPromise:f},e);if(c.kind!=="resolved")return{text:c.text};try{let y=await Z.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:wo(y,c)}}catch(y){return{text:`Error launching goal task: ${y instanceof Error?y.message:String(y)}`}}}})}V();function wu(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(!Z)return{text:Me};let n=(e.args??"").trim();return{text:bo(Z,r=>v?.resolve(r),n)}}})}V();function Pu(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(!Z)return{text:Me};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent_goal_stop <task-id-or-name>"};let r=Z.stopTask(n);return{text:Ro(r,n)}}})}V();var bu="Usage: /agent_goal_edit <task-id-or-name> <replacement-goal>";function Ru(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(!Z)return{text:Me};let n=(e.args??"").trim();if(!n)return{text:bu};let r=Ct(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:bu};let s=Z.editTask(o,i);return{text:Ao(s,o)}}})}import{execFile as oy}from"child_process";import{createHash as Bu}from"crypto";import{existsSync as jn,mkdirSync as jh,readFileSync as Gh,renameSync as xu,writeFileSync as Hh}from"fs";import{homedir as zh}from"os";import{dirname as Qh,join as Tu}from"path";var Jh=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function Yh(t){let e=t.OPENCLAW_HOME?.trim();return e||Tu(zh(),".openclaw")}function Zh(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||Tu(Yh(t),"code-agent-goal-tasks.json")}function Cu(t){return t instanceof Error?t.message:String(t)}function Mu(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var Xh=100;function Au(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function ey(t){if(!jn(t))return;let e=Date.now(),n=Au(t,e);if(!jn(n))return n;for(let r=1;r<=Xh;r+=1){let o=Au(t,e,r);if(!jn(o))return o}}function Iu(t,e){try{let n=ey(t);return n?(xu(t,n),`${e}${n}`,!0):(jn(t),!1)}catch(n){return`${Cu(n)}`,!1}}function ty(t){if(!Mu(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 ny(t){if(!Mu(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"||!Jh.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:ty(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 ry(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=ny(n);if(!r)return;e.push(r)}return e}var Mo=class{path;tasks=new Map;constructor(e=process.env){this.path=Zh(e),this.load()}load(){try{if(!jn(this.path))return;let e=Gh(this.path,"utf8"),n=JSON.parse(e),r=ry(n);if(!r){Iu(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;Iu(this.path,"corrupt or unreadable")&&this.save()}}save(){try{jh(Qh(this.path),{recursive:!0});let e=`${this.path}.tmp`;Hh(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),xu(e,this.path)}catch(e){`${this.path}${Cu(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)}};ye();var iy=8,Fu=600*1e3,sy=4e3,js=1200,ay="DONE",dy=["BASH_ENV","ENV"];function ly(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(`
150
150
  `):n.slice(-e).join(`
151
- `)}function ly(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(`
152
- `):void 0}function _u(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function $u(t){let e=t?.trim();return e&&e.length>0?e:sy}function uy(t){return t.route??_e(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??Fu})).filter(e=>e.command.length>0)}function cy(t){return t.loopMode==="verifier"}function py(t){return Vs(t.verifierCommands).length>0}function Eu(t){return cy(t)&&!py(t)}function _o(){return"Verifier-mode goal tasks require at least one verifier command."}function Du(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${ut(n.output,12)}`).join(`
153
- `);return Bu("sha1").update(e).digest("hex")}function my(t){return Bu("sha1").update(ut(t,24)).digest("hex")}function Ou(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 fy(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(`
151
+ `)}function uy(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(`
152
+ `):void 0}function _u(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function $u(t){let e=t?.trim();return e&&e.length>0?e:ay}function cy(t){return t.route??_e(t.originChannel,t.originThreadId,t.originSessionKey)}function Gs(t){return t.map((e,n)=>({label:e.label.trim()||`check-${n+1}`,command:e.command.trim(),timeoutMs:e.timeoutMs??Fu})).filter(e=>e.command.length>0)}function py(t){return t.loopMode==="verifier"}function my(t){return Gs(t.verifierCommands).length>0}function Eu(t){return py(t)&&!my(t)}function _o(){return"Verifier-mode goal tasks require at least one verifier command."}function Du(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${ut(n.output,12)}`).join(`
153
+ `);return Bu("sha1").update(e).digest("hex")}function fy(t){return Bu("sha1").update(ut(t,24)).digest("hex")}function Ou(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 gy(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(`
154
154
  `);let e=t.verifierCommands.map(n=>`- ${n.label}: ${n.command}`).join(`
155
155
  `);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(`
156
156
  `)}function Nu(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(`
157
157
  `):["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(`
158
- `)}function gy(t,e){let n=e.steps.filter(o=>!o.ok).map(o=>[`- ${o.label} failed (exit ${o.exitCode})`,ut(o.output,18)].join(`
158
+ `)}function hy(t,e){let n=e.steps.filter(o=>!o.ok).map(o=>[`- ${o.label} failed (exit ${o.exitCode})`,ut(o.output,18)].join(`
159
159
  `)).join(`
160
160
 
161
161
  `);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(`
162
- `)}function hy(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(`
163
- `)}function yy(t,e){let n=e.steps.filter(r=>!r.ok).map(r=>[`- ${r.label} failed (exit ${r.exitCode})`,ut(r.output,18)].join(`
162
+ `)}function yy(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(`
163
+ `)}function ky(t,e){let n=e.steps.filter(r=>!r.ok).map(r=>[`- ${r.label} failed (exit ${r.exitCode})`,ut(r.output,18)].join(`
164
164
  `)).join(`
165
165
 
166
166
  `);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(`
167
- `)}function ky(t,e){let n=e.trim();if(!n)return!1;let r=new RegExp(`(^|\\n)\\s*${_u(n)}\\s*(\\n|$)`,"i"),o=new RegExp(`<promise>\\s*${_u(n)}\\s*<\\/promise>`,"i");return r.test(t)||o.test(t)}function Wu(t){return t.steps.map(e=>`${e.ok?"PASS":"FAIL"} ${e.label} (exit ${e.exitCode}, ${Math.round(e.durationMs)}ms)`).join(`
168
- `)}function Mt(t){return t instanceof Error?t.message:String(t)}function Lu(t){return t==="succeeded"||t==="failed"||t==="stopped"}function Sy(t){return rn(t.error?.trim()||"Underlying session failed.",Ks)}function vy(t=process.env){let e={...t};for(let n of ay)delete e[n];return e}function wy(t,e){return new Promise(n=>{let r=Date.now();ry("bash",["-lc",e.command],{cwd:t,timeout:e.timeoutMs??Fu,maxBuffer:1024*1024,env:vy()},(o,i,s)=>{let a=Date.now()-r,d=typeof o?.code=="number"?o.code:o?1:0,l=`${i??""}${s?`
169
- ${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!o,exitCode:d,durationMs:a,output:rn(l||"(no output)",iy)})})})}var $o=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 Mo}start(){this.started||(this.started=!0,!this.restorePromise&&(this.restorePromise=this.restoreRecoverableTasks().catch(e=>{`${Mt(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(_o());let i={id:$r(8),name:dy(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??oy,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:$u(e.completionPromise),verifierCommands:r,repeatedFailureCount:0},s=await this.spawnTaskSession(i,fy(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
167
+ `)}function Sy(t,e){let n=e.trim();if(!n)return!1;let r=new RegExp(`(^|\\n)\\s*${_u(n)}\\s*(\\n|$)`,"i"),o=new RegExp(`<promise>\\s*${_u(n)}\\s*<\\/promise>`,"i");return r.test(t)||o.test(t)}function Wu(t){return t.steps.map(e=>`${e.ok?"PASS":"FAIL"} ${e.label} (exit ${e.exitCode}, ${Math.round(e.durationMs)}ms)`).join(`
168
+ `)}function Mt(t){return t instanceof Error?t.message:String(t)}function Lu(t){return t==="succeeded"||t==="failed"||t==="stopped"}function vy(t){return rn(t.error?.trim()||"Underlying session failed.",js)}function wy(t=process.env){let e={...t};for(let n of dy)delete e[n];return e}function Py(t,e){return new Promise(n=>{let r=Date.now();oy("bash",["-lc",e.command],{cwd:t,timeout:e.timeoutMs??Fu,maxBuffer:1024*1024,env:wy()},(o,i,s)=>{let a=Date.now()-r,d=typeof o?.code=="number"?o.code:o?1:0,l=`${i??""}${s?`
169
+ ${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!o,exitCode:d,durationMs:a,output:rn(l||"(no output)",sy)})})})}var $o=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 Mo}start(){this.started||(this.started=!0,!this.restorePromise&&(this.restorePromise=this.restoreRecoverableTasks().catch(e=>{`${Mt(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=Gs(e.verifierCommands);if(n==="verifier"&&r.length===0)throw new Error(_o());let i={id:$r(8),name:ly(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??iy,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:$u(e.completionPromise),verifierCommands:r,repeatedFailureCount:0},s=await this.spawnTaskSession(i,gy(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
170
170
 
171
171
  Goal:
172
172
  ${rn(i.goal,500)}`,"goal-task-started"),i}stopTask(e){let n=this.store.get(e);if(n)return Lu(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(Lu(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
173
173
 
174
174
  Goal:
175
- ${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}=Ft({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:uy(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(`
176
- `));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(Eu(e)){this.markTaskFailed(e,_o());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,Nu(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: ${Mt(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:_o()}],summary:"",fingerprint:""};return s.fingerprint=Du(s),s.summary=Wu(s),s}let r=[];for(let s of n)r.push(await wy(e.workdir,s));let i={status:r.every(s=>s.ok)?"pass":"fail",steps:r,summary:"",fingerprint:""};return i.fingerprint=Du(i),i.summary=Wu(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=ly(o),d=a?`${s}
175
+ ${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}=Ft({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:cy(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(`
176
+ `));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(Eu(e)){this.markTaskFailed(e,_o());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,Nu(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: ${Mt(r)}`)}}}async runVerifiers(e){let n=Gs(e.verifierCommands);if(n.length===0){let s={status:"fail",steps:[{label:"verifier-config",command:"(none configured)",ok:!1,exitCode:1,durationMs:0,output:_o()}],summary:"",fingerprint:""};return s.fingerprint=Du(s),s.summary=Wu(s),s}let r=[];for(let s of n)r.push(await Py(e.workdir,s));let i={status:r.every(s=>s.ok)?"pass":"fail",steps:r,summary:"",fingerprint:""};return i.fingerprint=Du(i),i.summary=Wu(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=uy(o),d=a?`${s}
177
177
 
178
- ${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}${Mt(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,Ks),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`❌ [${e.name}] Goal task failed
178
+ ${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}${Mt(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,js),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`❌ [${e.name}] Goal task failed
179
179
 
180
180
  ${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
181
181
 
182
- ${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=rn(n,Ks),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`⛔ [${e.name}] Goal task stopped
182
+ ${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=rn(n,js),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`⛔ [${e.name}] Goal task stopped
183
183
 
184
184
  ${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(`
185
- `),o=Ou(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: ${Mt(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(`
185
+ `),o=Ou(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: ${Mt(o)}`)}}async handleTerminalSession(e,n){if(n.status==="failed"){this.markTaskFailed(e,vy(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(`
186
186
  `);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=Ou(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(`
187
187
 
188
188
  `));return}await this.resumeAfterIdleTimeout(e,n,Nu(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(`
189
- `),a=$u(e.completionPromise);if(ky(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(`
189
+ `),a=$u(e.completionPromise);if(Sy(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(`
190
190
  `));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(`
191
- `));return}e.iteration+=1;let k=yy(e,p),m=Po({output:s,verifierSummary:p.summary,completionPromise:a,completionDetected:!0});try{let c=await this.resumeTaskSession(e,k,n);this.setTaskRunningWithSession(e,c),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,m),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",c.id)}catch(c){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${Mt(c)}`)}return}let l=my(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(`
192
- `));return}e.iteration+=1;let u=hy(e,s),f=Po({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,f),this.scheduleTaskEvaluation(e.id,"ralph-continue",p.id)}catch(p){this.markTaskFailed(e,`Failed to continue the Ralph goal task: ${Mt(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(`
193
- `));return}e.iteration+=1;let o=gy(e,r),i=Po({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: ${Mt(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(Eu(e)){this.markTaskFailed(e,_o());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 Kc}from"crypto";ae();import{existsSync as Py,realpathSync as by}from"fs";import{resolve as Ry}from"path";function qu(t){if(!t)return;let e=Ry(t);try{if(Py(e))return by.native(e)}catch{}return e}function Eo(t,e){return!t||!e?!1:qu(t)===qu(e)}ne();ae();import{existsSync as Ay}from"fs";ye();ne();Re();function Iy(t){if(!(!t.provider||!t.target))return t.accountId?`${t.provider}|${t.accountId}|${t.target}`:`${t.provider}|${t.target}`}function xy(t){return mn(De({route:t.route,originChannel:t.originChannel,originThreadId:t.originThreadId,originSessionKey:t.originSessionKey}))}function Ty(t,e){if(xy(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=De({route:o.route,originChannel:o.originChannel,originThreadId:o.originThreadId,originSessionKey:o.originSessionKey});if(mn(i)){t.route={...i},t.originChannel=o.originChannel??Iy(i),t.originThreadId=o.originThreadId??i.threadId,t.originSessionKey=o.originSessionKey??i.sessionKey,t.originAgentId??=o.originAgentId;return}}}function Uu(t){return t instanceof Error?t.message:String(t)}function Cy(t){let e=t.worktreeStrategy??D.defaultWorktreeStrategy;return!!e&&e!=="off"&&es(An({harnessName:t.harness??me(),backendRef:t.backendRef}))}function My(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(`
194
- `);return(t??"")+o}function _y(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=qr(r.worktreePath);return r.workdir&&a&&Eo(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&&Pr(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=Pr(An({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(Ay(r.worktreePath))return`${r.worktreePath}`,{actualWorkdir:r.worktreePath,originalWorkdir:i??r.worktreePath,worktreePath:r.worktreePath,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch};if(!i)return`${r.worktreePath}`,{clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom};if(s)return`${r.worktreePath}`,{actualWorkdir:i,originalWorkdir:i,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,restoredMissingNativeBackendWorktree:!0};try{jr(i);let a=as(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:i,worktreePath:a,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch}}catch(a){return`${Uu(a)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function Ku(t,e,n){Ty(t,n);let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,worktreeParentBranch:a,clearedResumeSessionId:d,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:u,canCreateManagedWorktreeForResumeWithoutPersistedPath:f,failedResumeWorktreeRestore:p}=_y(t,n);d&&(t.resumeSessionId=void 0),l&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,o??=t.workdir;let k=!!(t.resumeSessionId??t.resumeWorktreeFrom),m=t.worktreeStrategy??D.defaultWorktreeStrategy;m&&(t.worktreeStrategy=m),!k&&m&&m!=="off"&&Ur(o)&&(a??=ke(o));let c=Cy(t),S=(!k||!!f)&&!u&&!i&&m&&m!=="off"&&!c;if(p&&m&&m!=="off")throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);if(c&&!Ur(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" requires a git worktree, but "${o}" is not a git repository.`);if(S&&Ur(o)){if(!Gd(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=as(o,e),r=i,s=ke(i),!s)throw new Error(`created worktree at ${i} but failed to resolve branch name`);`${i}`}catch(b){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${Uu(b)}`)}}else if(S)throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" requires a git worktree, but "${o}" is not a git repository.`);if(k&&i&&(r=i),m&&m!=="off"&&!i)throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" 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?My(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,worktreeParentBranch:a,clearedResumeSessionId:d,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:u,failedResumeWorktreeRestore:p}}var Do=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return Ku(e,n,this.getPersistedSession)}hydrateSpawnedSession(e,n,r){r.worktreeStrategy&&r.worktreeStrategy!=="off"&&(e.originalWorkdir=n.originalWorkdir),e.worktreeParentBranch=n.worktreeParentBranch,n.worktreePath&&(e.worktreePath=n.worktreePath,e.worktreeBranch=n.worktreeBranchName,e.worktreeState="provisioned"),r.worktreePrTargetRepo&&(e.worktreePrTargetRepo=r.worktreePrTargetRepo)}};ne();var Oo=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(G(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])}};ne();var $y=new Set(["starting","running"]),No=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),$y.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};ne();ne();Re();import{existsSync as Ey}from"fs";var Vu=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),Wo=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=Vu.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&Vu.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=le(e);if(d&&!Ey(i))return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};let l=e.worktreeBaseBranch??Le(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 f=He(s,a,l);if(!f)return`${a}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let p=e.repoIntegrationPolicy?void 0:this.deps.resolveRepoPolicy?.(s),k=e.repoIntegrationPolicy??p?.policy,m=e.repoIntegrationPolicy?this.deps.isPrAvailable(s):p?.prAvailable??this.deps.isPrAvailable(s),c=El({requestedStrategy:o,policy:k,prAvailable:m,existingOpenPr:!1});return c.strategy?{kind:"decision",strategy:c.strategy,policy:k,policyReason:c.reason,policyBlocked:c.blocked,allowedActions:c.allowedActions,repoDir:s,worktreePath:i,branchName:a,baseBranch:l,diffSummary:f,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=Dy(t);n!==void 0&&e.push(We(n));let r=at({harness:t.harnessName??t.harness,model:t.model});return r&&e.push(...r.split(" | ")),e.length>0?` | ${e.join(" | ")}`:""}function Dy(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 Oy(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 Ny(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function Wy(){return/https?:\/\/\S+/gi}function Lo(t){let e=Oy(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function js(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 Ly(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function By(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function Fy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function Gs(t){let{sessionId:e,canonicalStatusDetail:n,canonicalStatusDelivered:r=!0,hasOriginRouteBlock:o=!1}=t,i=o?["7. Before sending that follow-up, honor the Session origin route block above. If originRoute differs from the current chat, do NOT use a plain final assistant reply; use a routed send path that preserves provider/target/threadId."]:[],s=o?8:7,a=o?9:8;return["[ACTION REQUIRED] Follow your autonomy rules for session completion:",`1. Use agent_output(session='${e}', full=true) to read the full result.`,"2. If this is part of a multi-phase pipeline, launch the next phase NOW — do not wait for user input.",`3. ${n??(r?"The plugin already sent the canonical completion status to the user.":"The plugin did not confirm delivery of the canonical completion status to the user.")}`,"4. Treat the completed session output as source material, not visible delivery. A meaningful final summary inside agent_output is not enough to skip, because the user may only have seen the plugin's terse status line.","5. If the visible result is only the plugin's terse status line, use the full output to send the user one short factual completion summary for this completed session. Do this even when agent_output already contains a good final summary.","6. This requirement applies to ordinary terminal/manual completions too, not just delegated worktree decisions.",...i,`${s}. That follow-up belongs to you alone; keep it brief, concrete, and grounded in reliable result data. Send at most one orchestrator-owned human summary for this terminal/worktree outcome.`,...r?[`${a}. Do NOT repeat the plugin's status line, and do NOT rely on the plugin to summarize the completed work for you.`]:[`${a}. Because canonical status delivery was not confirmed, account for that gap yourself when you follow up; do NOT assume the plugin already reached the user.`],`${a+1}. Send a normal concise final response after any routed follow-up is visibly sent. Do not use marker text, do not answer NO_REPLY, and do not ask the user whether they want the summary.`]}function qy(t){let{contract:e,canonicalStatusDelivered:n}=t;return["Completion diagnostics:",`- Canonical completion status delivered to user: ${n?"yes":"no"}`,`- Plugin requested short factual follow-up summary: ${e.requiresShortFactualSummary?"yes":"no"}`,`- Contract applies to ordinary terminal/manual completions: ${e.appliesToOrdinaryTerminalCompletions?"yes":"no"}`]}function Hs(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=Ly(),s=a=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...Lo(e),"","Output preview:",r,"",...qy({contract:i,canonicalStatusDelivered:a}),"",...Gs({sessionId:e.id,canonicalStatusDelivered:a,hasOriginRouteBlock:o})].join(`
195
- `);return{userMessage:`✅ [${e.name}] Completed${ct(e)}`,wakeMessageOnNotifySuccess:s(!0),wakeMessageOnNotifyFailed:s(!1),followupContract:i}}function on(t){let e=By(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>ju(i).trim()).filter(i=>i.length>0),o=ju(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(`
196
- `)}function zs(t){let e=Fy(),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(`
197
- `)}function ju(t){return t.replace(Ny(),"PR #$1").replace(Wy(),"[link omitted]")}function Qs(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(`
191
+ `));return}e.iteration+=1;let k=ky(e,p),m=Po({output:s,verifierSummary:p.summary,completionPromise:a,completionDetected:!0});try{let c=await this.resumeTaskSession(e,k,n);this.setTaskRunningWithSession(e,c),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,m),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",c.id)}catch(c){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${Mt(c)}`)}return}let l=fy(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(`
192
+ `));return}e.iteration+=1;let u=yy(e,s),f=Po({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,f),this.scheduleTaskEvaluation(e.id,"ralph-continue",p.id)}catch(p){this.markTaskFailed(e,`Failed to continue the Ralph goal task: ${Mt(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(`
193
+ `));return}e.iteration+=1;let o=hy(e,r),i=Po({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: ${Mt(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(Eu(e)){this.markTaskFailed(e,_o());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 Kc}from"crypto";ae();import{existsSync as by,realpathSync as Ry}from"fs";import{resolve as Ay}from"path";function qu(t){if(!t)return;let e=Ay(t);try{if(by(e))return Ry.native(e)}catch{}return e}function Eo(t,e){return!t||!e?!1:qu(t)===qu(e)}ne();ae();import{existsSync as Iy}from"fs";ye();ne();Re();function xy(t){if(!(!t.provider||!t.target))return t.accountId?`${t.provider}|${t.accountId}|${t.target}`:`${t.provider}|${t.target}`}function Ty(t){return mn(De({route:t.route,originChannel:t.originChannel,originThreadId:t.originThreadId,originSessionKey:t.originSessionKey}))}function Cy(t,e){if(Ty(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=De({route:o.route,originChannel:o.originChannel,originThreadId:o.originThreadId,originSessionKey:o.originSessionKey});if(mn(i)){t.route={...i},t.originChannel=o.originChannel??xy(i),t.originThreadId=o.originThreadId??i.threadId,t.originSessionKey=o.originSessionKey??i.sessionKey,t.originAgentId??=o.originAgentId;return}}}function Uu(t){return t instanceof Error?t.message:String(t)}function My(t){let e=t.worktreeStrategy??D.defaultWorktreeStrategy;return!!e&&e!=="off"&&ns(An({harnessName:t.harness??me(),backendRef:t.backendRef}))}function _y(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(`
194
+ `);return(t??"")+o}function $y(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=qr(r.worktreePath);return r.workdir&&a&&Eo(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&&Pr(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=Pr(An({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(Iy(r.worktreePath))return`${r.worktreePath}`,{actualWorkdir:r.worktreePath,originalWorkdir:i??r.worktreePath,worktreePath:r.worktreePath,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch};if(!i)return`${r.worktreePath}`,{clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom};if(s)return`${r.worktreePath}`,{actualWorkdir:i,originalWorkdir:i,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,restoredMissingNativeBackendWorktree:!0};try{jr(i);let a=ls(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:i,worktreePath:a,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch}}catch(a){return`${Uu(a)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function Ku(t,e,n){Cy(t,n);let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,worktreeParentBranch:a,clearedResumeSessionId:d,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:u,canCreateManagedWorktreeForResumeWithoutPersistedPath:f,failedResumeWorktreeRestore:p}=$y(t,n);d&&(t.resumeSessionId=void 0),l&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,o??=t.workdir;let k=!!(t.resumeSessionId??t.resumeWorktreeFrom),m=t.worktreeStrategy??D.defaultWorktreeStrategy;m&&(t.worktreeStrategy=m),!k&&m&&m!=="off"&&Ur(o)&&(a??=ke(o));let c=My(t),S=(!k||!!f)&&!u&&!i&&m&&m!=="off"&&!c;if(p&&m&&m!=="off")throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);if(c&&!Ur(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" requires a git worktree, but "${o}" is not a git repository.`);if(S&&Ur(o)){if(!Gd(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=ls(o,e),r=i,s=ke(i),!s)throw new Error(`created worktree at ${i} but failed to resolve branch name`);`${i}`}catch(b){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${Uu(b)}`)}}else if(S)throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" requires a git worktree, but "${o}" is not a git repository.`);if(k&&i&&(r=i),m&&m!=="off"&&!i)throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" 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?_y(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,worktreeParentBranch:a,clearedResumeSessionId:d,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:u,failedResumeWorktreeRestore:p}}var Do=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return Ku(e,n,this.getPersistedSession)}hydrateSpawnedSession(e,n,r){r.worktreeStrategy&&r.worktreeStrategy!=="off"&&(e.originalWorkdir=n.originalWorkdir),e.worktreeParentBranch=n.worktreeParentBranch,n.worktreePath&&(e.worktreePath=n.worktreePath,e.worktreeBranch=n.worktreeBranchName,e.worktreeState="provisioned"),r.worktreePrTargetRepo&&(e.worktreePrTargetRepo=r.worktreePrTargetRepo)}};ne();var Oo=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(G(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])}};ne();var Ey=new Set(["starting","running"]),No=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),Ey.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};ne();ne();Re();import{existsSync as Dy}from"fs";var Vu=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),Wo=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=Vu.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&Vu.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=le(e);if(d&&!Dy(i))return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};let l=e.worktreeBaseBranch??Le(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 f=He(s,a,l);if(!f)return`${a}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let p=e.repoIntegrationPolicy?void 0:this.deps.resolveRepoPolicy?.(s),k=e.repoIntegrationPolicy??p?.policy,m=e.repoIntegrationPolicy?this.deps.isPrAvailable(s):p?.prAvailable??this.deps.isPrAvailable(s),c=El({requestedStrategy:o,policy:k,prAvailable:m,existingOpenPr:!1});return c.strategy?{kind:"decision",strategy:c.strategy,policy:k,policyReason:c.reason,policyBlocked:c.blocked,allowedActions:c.allowedActions,repoDir:s,worktreePath:i,branchName:a,baseBranch:l,diffSummary:f,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=Oy(t);n!==void 0&&e.push(We(n));let r=at({harness:t.harnessName??t.harness,model:t.model});return r&&e.push(...r.split(" | ")),e.length>0?` | ${e.join(" | ")}`:""}function Oy(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 Ny(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 Wy(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function Ly(){return/https?:\/\/\S+/gi}function Lo(t){let e=Ny(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function Hs(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 By(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function Fy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function qy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function zs(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 Uy(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 Qs(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=By(),s=a=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...Lo(e),"","Output preview:",r,"",...Uy({contract:i,canonicalStatusDelivered:a}),"",...zs({sessionId:e.id,canonicalStatusDelivered:a,hasOriginRouteBlock:o})].join(`
195
+ `);return{userMessage:`✅ [${e.name}] Completed${ct(e)}`,wakeMessageOnNotifySuccess:s(!0),wakeMessageOnNotifyFailed:s(!1),followupContract:i}}function on(t){let e=Fy(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>ju(i).trim()).filter(i=>i.length>0),o=ju(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(`
196
+ `)}function Js(t){let e=qy(),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(`
197
+ `)}function ju(t){return t.replace(Wy(),"PR #$1").replace(Ly(),"[link omitted]")}function Ys(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(`
198
198
  `),wakeMessage:["Coding agent session failed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,n,...Lo(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(`
199
- `),buttons:s}}function Js(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(`
200
- `)}}function Ys(t){let{sessionName:e,sessionId:n,branchName:r,baseBranch:o,promptSnippet:i,commitLines:s,moreNote:a,originThreadLine:d,diffSummary:l,allowedActions:u,policyReason:f}=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,"",...f?[`Policy constraint: ${f}`,""]:[],"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(`
201
- `)}function Zs(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(`
202
- `)}function Xs(t){let{sessionName:e,sessionId:n,headline:r,cleanupSummary:o,preview:i,originThreadLine:s,requestedPermissionMode:a,currentPermissionMode:d,approvalExecutionState:l,approvalState:u,planApproval:f,approvalPromptStatus:p,approvalPromptMessageKind:k,approvalPromptDeliveredAt:m}=t,c=i.trim()?["","Output preview:",i]:[],y=!!s?.trim();return[r??"Coding agent session completed with no worktree changes to merge.",`Name: ${e} | ID: ${n}`,`Worktree outcome: ${o}`,...y?[s]:[],...Lo({requestedPermissionMode:a,currentPermissionMode:d,approvalExecutionState:l,approvalState:u,planApproval:f,approvalPromptStatus:p,approvalPromptMessageKind:k,approvalPromptDeliveredAt:m}),...c,"",...Gs({sessionId:n,canonicalStatusDetail:"The plugin already sent the canonical completion status to the user, including the no-worktree-changes outcome.",hasOriginRouteBlock:y})].join(`
203
- `)}var zu=3200,ea=3e3,Uy=2400,Ky=120,Vy=5,jy=280,Gu=1400,Hu="- Additional plan details omitted for brevity.";function Qu(t){return t.replace(/^#{1,6}\s+/,"").replace(/^[-*+]\s+/,"").replace(/^\d+[.)]\s+/,"").replace(/^`([^`]+)`$/,"$1").trim()}function Gy(t){return t.split(`
204
- `).map(e=>e.trim()).filter(Boolean).map(Qu).map(e=>ue(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 Hy(t){return t.split(`
205
- `).map(e=>e.trim()).filter(Boolean).map(Qu).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 ta(t){let e=Gy(t);return e.length===0?`Review summary:
199
+ `),buttons:s}}function Zs(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(`
200
+ `)}}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:f}=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,"",...f?[`Policy constraint: ${f}`,""]:[],"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(`
201
+ `)}function ea(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(`
202
+ `)}function ta(t){let{sessionName:e,sessionId:n,headline:r,cleanupSummary:o,preview:i,originThreadLine:s,requestedPermissionMode:a,currentPermissionMode:d,approvalExecutionState:l,approvalState:u,planApproval:f,approvalPromptStatus:p,approvalPromptMessageKind:k,approvalPromptDeliveredAt:m}=t,c=i.trim()?["","Output preview:",i]:[],y=!!s?.trim();return[r??"Coding agent session completed with no worktree changes to merge.",`Name: ${e} | ID: ${n}`,`Worktree outcome: ${o}`,...y?[s]:[],...Lo({requestedPermissionMode:a,currentPermissionMode:d,approvalExecutionState:l,approvalState:u,planApproval:f,approvalPromptStatus:p,approvalPromptMessageKind:k,approvalPromptDeliveredAt:m}),...c,"",...zs({sessionId:n,canonicalStatusDetail:"The plugin already sent the canonical completion status to the user, including the no-worktree-changes outcome.",hasOriginRouteBlock:y})].join(`
203
+ `)}var zu=3200,na=3e3,Ky=2400,Vy=120,jy=5,Gy=280,Gu=1400,Hu="- Additional plan details omitted for brevity.";function Qu(t){return t.replace(/^#{1,6}\s+/,"").replace(/^[-*+]\s+/,"").replace(/^\d+[.)]\s+/,"").replace(/^`([^`]+)`$/,"$1").trim()}function Hy(t){return t.split(`
204
+ `).map(e=>e.trim()).filter(Boolean).map(Qu).map(e=>ue(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 zy(t){return t.split(`
205
+ `).map(e=>e.trim()).filter(Boolean).map(Qu).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 ra(t){let e=Hy(t);return e.length===0?`Review summary:
206
206
  - Plan details are available in the full session output.`:["Review summary:",...e.slice(0,6).map(n=>`- ${n}`)].join(`
207
- `)}function zy(t){let e=[],n=!1;for(let o of t){let i=o.replace(/\s+/g," ").trim();if(!i)continue;let s=ue(i,jy);s.length<i.length&&(n=!0);let a=`- ${s}`;if(e.length>=Vy||[...e,a].join(`
207
+ `)}function Qy(t){let e=[],n=!1;for(let o of t){let i=o.replace(/\s+/g," ").trim();if(!i)continue;let s=ue(i,Gy);s.length<i.length&&(n=!0);let a=`- ${s}`;if(e.length>=jy||[...e,a].join(`
208
208
  `).length>Gu){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,Hu].join(`
209
- `).length>Gu;)r.pop();return[...r,Hu]}function na(t){return zy(Hy(t)).join(`
210
- `)}function Qy(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 Jy(t,e){let n=t.split(`
211
- `),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 Qy(s,e))r.push(d);continue}let a=o.length>0?`${o}
212
- ${s}`:s;if(a.length>e){i(),o=s;continue}o=a}return i(),r}function Ju(t){return ue(t.trim(),Ky)}function Yu(t,e){return e?t?`
209
+ `).length>Gu;)r.pop();return[...r,Hu]}function oa(t){return Qy(zy(t)).join(`
210
+ `)}function Jy(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 Yy(t,e){let n=t.split(`
211
+ `),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 Jy(s,e))r.push(d);continue}let a=o.length>0?`${o}
212
+ ${s}`:s;if(a.length>e){i(),o=s;continue}o=a}return i(),r}function Ju(t){return ue(t.trim(),Vy)}function Yu(t,e){return e?t?`
213
213
 
214
214
  Choose Approve, Revise, or Reject below.`:`
215
215
 
216
216
  Approval is still pending for this plan version.`:`
217
217
 
218
- Continued in next message.`}function Yy(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=`📋 [${e}] Plan v${n??"?"} ready for approval:`,s=`
218
+ Continued in next message.`}function Zy(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=`📋 [${e}] Plan v${n??"?"} ready for approval:`,s=`
219
219
 
220
220
  Full plan (truncated):
221
- `,a=Yu(o,!0),d=Math.max(0,ea-i.length-s.length-a.length);return`${i}${s}${ue(r,d)}${a}`}function Zy(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=Ju(e),s=Uy;for(;s>0;){let a=Jy(r,s),d=a.map((f,p)=>{let k=a.length,m=[`📋 [${i}] Plan v${n??"?"} ready for approval (${p+1}/${k}):`,"",p===0?"Full plan:":""].filter(Boolean).join(`
221
+ `,a=Yu(o,!0),d=Math.max(0,na-i.length-s.length-a.length);return`${i}${s}${ue(r,d)}${a}`}function Xy(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=Ju(e),s=Ky;for(;s>0;){let a=Yy(r,s),d=a.map((f,p)=>{let k=a.length,m=[`📋 [${i}] Plan v${n??"?"} ready for approval (${p+1}/${k}):`,"",p===0?"Full plan:":""].filter(Boolean).join(`
222
222
  `),c=Yu(o,p===k-1);return`${m}
223
- ${f}${c}`}),l=d.reduce((f,p)=>Math.max(f,p.length),0);if(l<=ea)return d;let u=l-ea;s-=Math.max(u,50)}return[Yy({sessionName:i,actionableVersion:n,fullPlanText:r,hasButtons:o})]}function ra(t){let{preview:e,artifact:n}=t,r=n?.markdown?.trim();return r&&r.length<=zu?`Full plan:
224
- ${r}`:ta(r||e)}function Zu(t){let{sessionName:e,actionableVersion:n,preview:r,artifact:o,hasButtons:i}=t,s=o?.markdown?.trim(),a=Ju(e);if(s){let l=`📋 [${a}] Plan v${n??"?"} ready for approval:
223
+ ${f}${c}`}),l=d.reduce((f,p)=>Math.max(f,p.length),0);if(l<=na)return d;let u=l-na;s-=Math.max(u,50)}return[Zy({sessionName:i,actionableVersion:n,fullPlanText:r,hasButtons:o})]}function ia(t){let{preview:e,artifact:n}=t,r=n?.markdown?.trim();return r&&r.length<=zu?`Full plan:
224
+ ${r}`:ra(r||e)}function Zu(t){let{sessionName:e,actionableVersion:n,preview:r,artifact:o,hasButtons:i}=t,s=o?.markdown?.trim(),a=Ju(e);if(s){let l=`📋 [${a}] Plan v${n??"?"} ready for approval:
225
225
 
226
226
  Full plan:
227
227
  ${s}
228
228
 
229
229
  ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`;return l.length<=zu?{displayMode:"single-full-plan",userMessages:[l],reviewSummary:`Full plan:
230
- ${s}`}:{displayMode:"chunked-full-plan",userMessages:Zy({sessionName:e,actionableVersion:n,fullPlanText:s,hasButtons:i}),reviewSummary:ta(s)}}let d=ta(r);return{displayMode:"summary",userMessages:[`📋 [${a}] Plan v${n??"?"} ready for approval:
230
+ ${s}`}:{displayMode:"chunked-full-plan",userMessages:Xy({sessionName:e,actionableVersion:n,fullPlanText:s,hasButtons:i}),reviewSummary:ra(s)}}let d=ra(r);return{displayMode:"summary",userMessages:[`📋 [${a}] Plan v${n??"?"} ready for approval:
231
231
 
232
232
  ${d}
233
233
 
234
- ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`],reviewSummary:d}}function Xu(t){let e=t?.trim();return e||void 0}function Xy(t){let e=Xu(t.questionText)??"The session is waiting for your reply.",n=Xu(t.contextSummary);return n?[`❓ [${t.sessionName}] Question waiting for reply:`,"",e,"",`Why: ${n}`].join(`
234
+ ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`],reviewSummary:d}}function Xu(t){let e=t?.trim();return e||void 0}function ek(t){let e=Xu(t.questionText)??"The session is waiting for your reply.",n=Xu(t.contextSummary);return n?[`❓ [${t.sessionName}] Question waiting for reply:`,"",e,"",`Why: ${n}`].join(`
235
235
  `):`❓ [${t.sessionName}] Question waiting for reply:
236
236
 
237
- ${e}`}function ek(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function Gn(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(`
238
- `)}function oa(t){let{session:e,preview:n,questionText:r,questionContextSummary:o,planArtifact:i,originThreadLine:s,planApprovalMode:a,planApprovalButtons:d,questionButtons:l}=t,u=e.pendingPlanApproval,f=e.actionablePlanDecisionVersion??e.planDecisionVersion,p=ek(e,f),k=a??"delegate",m=u&&k==="ask"&&!p?Zu({sessionName:e.name,actionableVersion:f,preview:n,artifact:i,hasButtons:!!d}):void 0,c=u?m?.reviewSummary??ra({preview:n,artifact:i}):void 0,y=u?m&&m.userMessages.length===1?m.userMessages[0]:void 0:Xy({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!l}),S=u&&m&&m.userMessages.length>1?m.userMessages.map((x,T,A)=>({text:x,buttons:T===A.length-1?d:void 0})):void 0;if(u){let x=k,T="Permission mode: plan → will switch to bypassPermissions on approval";return x==="delegate"?{label:"plan-approval",userMessage:y,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${f??"?"}`,s,T,"","⚠️ 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(`
237
+ ${e}`}function tk(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function Gn(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(`
238
+ `)}function sa(t){let{session:e,preview:n,questionText:r,questionContextSummary:o,planArtifact:i,originThreadLine:s,planApprovalMode:a,planApprovalButtons:d,questionButtons:l}=t,u=e.pendingPlanApproval,f=e.actionablePlanDecisionVersion??e.planDecisionVersion,p=tk(e,f),k=a??"delegate",m=u&&k==="ask"&&!p?Zu({sessionName:e.name,actionableVersion:f,preview:n,artifact:i,hasButtons:!!d}):void 0,c=u?m?.reviewSummary??ia({preview:n,artifact:i}):void 0,y=u?m&&m.userMessages.length===1?m.userMessages[0]:void 0:ek({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!l}),S=u&&m&&m.userMessages.length>1?m.userMessages.map((x,T,A)=>({text:x,buttons:T===A.length-1?d:void 0})):void 0;if(u){let x=k,T="Permission mode: plan → will switch to bypassPermissions on approval";return x==="delegate"?{label:"plan-approval",userMessage:y,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${f??"?"}`,s,T,"","⚠️ 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(`
239
239
  `)}:x==="ask"?{label:"plan-approval",userMessage:y,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${f??"?"}`,s,T,"","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(`
240
240
  `),buttons:S?void 0:d}:{label:"plan-approval",userMessage:y,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(`
241
241
  `)}}let b=e.multiTurn?"Multi-turn session":"Session";return{label:"waiting",userMessage:y,wakeMessage:[`[SYSTEM INSTRUCTION: Follow your auto-respond rules strictly. If this is a permission request or "should I continue?" → auto-respond. For ALL other questions → forward the agent's EXACT question to the user. Do NOT add your own analysis, commentary, or interpretation. Do NOT "nudge" or "poke" the session.]`,"",`${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(`
242
- `),buttons:l}}ft();var Bo=3,ia=180,tk=4e3,ec=32;function tc(){let t=tt(),e=lk(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=uk(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 nk(t,e){let n=ck(e);if(n.length>0)return n;let r=rk(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 rk(t){let e=new Set,n=t.commitMessages.length===1?t.changedFiles:[];return t.commitMessages.map(r=>ok(r.message,n)).filter(r=>!!r).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Bo)}function ok(t,e){let n=ik(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 sa(`${n}${r}.`,ia)}function ik(t){let e=Fo(qo(t)).replace(/^(?:feat|fix|docs|style|refactor|perf|test|tests|build|ci|chore|revert)(?:\([^)]+\))?!?:\s*/i,"").replace(/\.$/,"").trim();if(!e||aa(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 nc(t){let e=sk(t),n=nk(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=ak(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 sk(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:fk(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=>Fo(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:sa(qo(t.outputPreview??""),tk)}}function ak(t){let e=dk(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>Bo)return[];let r=n.map(o=>typeof o=="string"?Fo(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>ia)?[]:r.some(aa)?[]:r}function dk(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
243
- `).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,Bo)}}}function lk(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 uk(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(`
244
- `)}function ck(t){let e=new Set;return qo(t??"").replace(/\r\n/g,`
242
+ `),buttons:l}}ft();var Bo=3,aa=180,nk=4e3,ec=32;function tc(){let t=tt(),e=uk(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=ck(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 rk(t,e){let n=pk(e);if(n.length>0)return n;let r=ok(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 ok(t){let e=new Set,n=t.commitMessages.length===1?t.changedFiles:[];return t.commitMessages.map(r=>ik(r.message,n)).filter(r=>!!r).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Bo)}function ik(t,e){let n=sk(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 da(`${n}${r}.`,aa)}function sk(t){let e=Fo(qo(t)).replace(/^(?:feat|fix|docs|style|refactor|perf|test|tests|build|ci|chore|revert)(?:\([^)]+\))?!?:\s*/i,"").replace(/\.$/,"").trim();if(!e||la(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 nc(t){let e=ak(t),n=rk(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=dk(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 ak(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:gk(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=>Fo(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:da(qo(t.outputPreview??""),nk)}}function dk(t){let e=lk(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>Bo)return[];let r=n.map(o=>typeof o=="string"?Fo(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>aa)?[]:r.some(la)?[]:r}function lk(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
243
+ `).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,Bo)}}}function uk(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 ck(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(`
244
+ `)}function pk(t){let e=new Set;return qo(t??"").replace(/\r\n/g,`
245
245
  `).split(`
246
- `).map(r=>Fo(r)).map(r=>pk(r)).filter(mk).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Bo)}function pk(t){return t.replace(/^(?:summary|done|completed|changes|validation|verified)\s*:\s*/i,"").trim()}function mk(t){return t.length<12||t.length>ia||aa(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 fk(t){let e=t?.replace(/\r\n/g,`
246
+ `).map(r=>Fo(r)).map(r=>mk(r)).filter(fk).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Bo)}function mk(t){return t.replace(/^(?:summary|done|completed|changes|validation|verified)\s*:\s*/i,"").trim()}function fk(t){return t.length<12||t.length>aa||la(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 gk(t){let e=t?.replace(/\r\n/g,`
247
247
  `).split(`
248
- `).map(o=>o.trim()).filter(Boolean).join(" ");if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=qo(n).replace(/\s+/g," ").trim();return r?sa(r,180):void 0}function Fo(t){return t.replace(/^[-*•]\s+/,"").replace(/\s+/g," ").trim()}function sa(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function qo(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_-]{${ec},}\\b`,"g"),"[redacted token]")}function aa(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_-]{${ec},}\\b`).test(t)}Re();function $e(t){return[t.startedAt,t.worktreeBranch??"unknown-branch",t.worktreePath??"unknown-worktree"].join(":")}var Uo=class{constructor(e){this.deps=e;this.actions=new Wo({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(`
248
+ `).map(o=>o.trim()).filter(Boolean).join(" ");if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=qo(n).replace(/\s+/g," ").trim();return r?da(r,180):void 0}function Fo(t){return t.replace(/^[-*•]\s+/,"").replace(/\s+/g," ").trim()}function da(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function qo(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_-]{${ec},}\\b`,"g"),"[redacted token]")}function la(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_-]{${ec},}\\b`).test(t)}Re();function $e(t){return[t.startedAt,t.worktreeBranch??"unknown-branch",t.worktreePath??"unknown-worktree"].join(":")}var Uo=class{constructor(e){this.deps=e;this.actions=new Wo({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(`
249
249
  `)}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(`
250
250
  `),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,io(e,n))}markAutoMergeConflictResolving(e,n,r){this.updatePersistedSessionFor(e,Ol(e,n,r,{notes:[`resolver_session:${n}`]}))}markMerged(e){this.updatePersistedSessionFor(e,en(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:ce(n.repoDir,n.worktreePath);return Pe(n.repoDir,n.branchName),this.markMerged(e),{notificationSent:!1,worktreeRemoved:r}}if(n.kind==="released"){let r=n.nativeBackendWorktree?!0:ce(n.repoDir,n.worktreePath);return Pe(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"?{notificationSent:!0,worktreeRemoved:await this.handleAutoMergeStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.diffSummary,n.sessionRef,n.allowedActions)}: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=le(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:ce(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 fe(e).map(r=>this.deps.getPersistedSession?.(r)).find(r=>r?.worktreeRemoteOutcome==="pr-updated"||r?.worktreeRemoteOutcome==="pr-opened")?.worktreeRemoteOutcome}resolveExistingTargetPr(e,n,r,o){let i=Tn(n,e.worktreePrTargetRepo);if(e.worktreePrUrl){let d=this.getPrStatusForUrl(n,e.worktreePrUrl,i);if(d.exists&&d.baseRefName===o)return d}let s=e.worktreeParentBranch;if(!s||ke(n)!==s||s===r||s===o)return;let a=this.deps.getPrStatusForBranch?.(n,s,i)??be(n,s,i);return a.exists&&a.state==="open"&&a.headRefName===s&&(!a.baseRefName||a.baseRefName===o)?a:void 0}shouldUpdateExistingOpenPr(e,n,r,o){return e.worktreeStrategy==="auto-pr"&&(this.hasCurrentlyOpenPrForBranch(e,n,r)||this.resolveExistingTargetPr(e,n,r,o)?.state==="open")}async handleAskStrategy(e,n,r,o,i,s){let a=await nc({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=wt(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(`
251
251
  `)}),{notificationSent:!0,worktreeRemoved:!1}}handleAutoMergeSuccess(e,n,r,o,i,s,a){let d=le(e),l=d||!Jd(r)||ce(n,r);l&&(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0}),d||Pe(n,o)),this.markMerged(e);let u=bt({kind:"merge",branch:o,base:i,filesChanged:s.filesChanged,insertions:s.insertions,deletions:s.deletions}),f=u;a.stashPopConflict?f+=`
@@ -253,33 +253,33 @@ ${e}`}function ek(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.a
253
253
  (Pre-existing changes on ${i} were auto-stashed and restored.)`),f=Be(f,a);let p=Zt(a),k=[a.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",`Auto-merge landed ${o} into ${i}.`,"Local worktree branch cleanup was requested.",...a.stashPopConflict?[`Pre-merge stash pop conflicted; run git stash show ${a.stashRef??"stash@{0}"} in ${n} to review stashed changes.`]:[],...!a.stashPopConflict&&a.stashed?[`Pre-existing changes on ${i} were auto-stashed and restored.`]:[],...p];return this.deps.dispatchSessionNotification(e,{label:"worktree-merge-success",idempotencyKey:`worktree-merge-success:${e.id}:${o}:${i}:${$e(e)}`,userMessage:f,notifyUser:"always",completionSummary:{required:!0,producer:"worktree",outcomeKey:`worktree-merge:${e.id}:${o}:${i}:${$e(e)}`},completionWakeSummaryRequired:!0,completionWakeOutcomeKey:`worktree-merge:${e.id}:${o}:${i}:${$e(e)}`,deferConditionalWakeUntilNextTick:!0,wakeMessageOnNotifySuccess:on({sessionId:e.id,sessionName:e.name,outcomeLine:u,originThreadLine:this.deps.originThreadLine(e),detailLines:k,canonicalStatusDelivered:!0}),wakeMessageOnNotifyFailed:on({sessionId:e.id,sessionName:e.name,outcomeLine:u,originThreadLine:this.deps.originThreadLine(e),detailLines:k,canonicalStatusDelivered:!1})}),l}async handleInitialAutoMergeConflict(e,n,r,o,i,s,a,d){let l=d?Zt(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 f=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:f});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(k=>`⚠️ ${k}`)].join(`
254
254
  `)})}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(k=>`⚠️ ${k}`)].join(`
255
255
  `),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(`
256
- `),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}){if(this.deps.isAlreadyMerged(a)||e.autoMergeResolverSessionId)return!1;let l=!1;return await this.deps.enqueueMerge(n,async()=>{if(this.deps.isAlreadyMerged(a))return;let u=this.deps.mergeBranch(n,o,i,"merge",r);if(u.success){l=this.handleAutoMergeSuccess(e,n,r,o,i,s,u);return}if(u.rebaseConflict){await this.handleInitialAutoMergeConflict(e,n,r,o,i,d,u.error,u);return}let f=Be(u.dirtyError?`❌ [${e.name}] Merge blocked: ${u.error}`:`❌ [${e.name}] Merge failed: ${u.error??"unknown error"}`,u);if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,o,r,f,d);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${o}:${$e(e)}`,userMessage:f})},()=>{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.`})}),l}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)??Qe(e,n,r)}releaseIfRepresentedByTargetPrBranch(e,n,r,o,i){if(wt(r).length>0)return;let s=this.resolveExistingTargetPr(e,n,o,i),a=s?.headRefName;if(!a||a===o||a===i)return;let d=this.deps.fetchRemoteBranch?this.deps.fetchRemoteBranch(n,a):Kr(n,a);if(!d||!!!((s?.state==="open"||s?.state==="merged")&&s?.baseRefName===i&&Se(n,o,d)))return;let u=le(e)?!0:ce(n,r);return u?(e.worktreePath=void 0,e.worktreePrUrl=s.url,e.worktreePrNumber=s.number,e.worktreePrTargetRepo=Tn(n,e.worktreePrTargetRepo),this.updatePersistedSessionFor(e,{worktreePath:void 0,worktreePrUrl:s.url,worktreePrNumber:s.number,worktreePrTargetRepo:e.worktreePrTargetRepo,worktreeRemoteOutcome:"pr-updated"}),Pe(n,o),this.markReleased(e,[`released_by_branch:${a}`]),{notificationSent:!1,worktreeRemoved:u}):(this.markPendingDecision(e,{notes:[`represented_by_branch:${a}`,"represented_worktree_cleanup_failed"]}),{notificationSent:!1,worktreeRemoved:!1})}};import{existsSync as eS,statSync as tS,writeFileSync as nS}from"fs";ye();import{randomUUID as gk}from"crypto";function hk(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var Ko=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:gk(),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}consumeQuestionAnswerTokens(e,n){let r=[],o=Date.now();for(let i of this.tokens.values())i.sessionId!==e||i.kind!=="question-answer"||i.pendingInputRequestId!==n||i.consumedAt!=null||(i.consumedAt=o,r.push(i));return r.length>0&&this.notifyChanged(),r}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||!hk(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?.()}};ne();ne();var Vo=class{constructor(e){this.indexes=e}indexes;hasRecordedSession(e){return this.indexes.idIndex.has(e)}getLatestPersistedByName(e){let n,r=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,s=0;for(let a of this.indexes.persisted.values()){if(a.name!==e){s++;continue}let 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 mc,mkdirSync as Vk,readFileSync as jk,readdirSync as Gk,renameSync as fc,statSync as gc,unlinkSync as hc,writeFileSync as yc}from"fs";import{tmpdir as Hk}from"os";import{dirname as zk,join as kc}from"path";import{homedir as yk}from"node:os";import{join as kk}from"node:path";function jo(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||yk();return kk(n,".openclaw")}ye();var Go=7,Sk=new Set(["running","completed","failed","killed"]),vk=new Set(["queued","running","waiting","blocked","succeeded","failed","cancelled","lost"]);function qe(t){return!!t&&typeof t=="object"}function sn(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 pe(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function wk(t){if(!qe(t))return;let e=P(t.flowId),n=pe(t.revision);if(!e||n===void 0)return;let r=typeof t.status=="string"&&vk.has(t.status)?t.status:void 0;return{flowId:e,revision:n,...r?{status:r}:{}}}function rc(t){return typeof t=="string"&&xl.has(t)?t:void 0}function da(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function Pk(t){return t==="never"||t==="on-request"?"never":void 0}function oc(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function bk(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function ic(t){return typeof t=="string"&&ro.has(t)?t:void 0}function la(t){return typeof t=="string"&&Il.has(t)?t:void 0}function sc(t){return t==="github"||t==="unsupported"?t:void 0}function Rk(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function Ak(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function ac(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 Ik(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function xk(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 Tk(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 dc(t){return t==="live"||t==="stopped"?t:void 0}function Ck(t){if(!qe(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:pe(t.rawCompletedAt),rawOutputPath:P(t.rawOutputPath),normalizedStatus:n,normalizedLifecycle:ac(t.normalizedLifecycle),normalizedRuntimeState:dc(t.normalizedRuntimeState)}}function Mk(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:pe(t.completedAt),rawOutputPath:P(t.outputPath),normalizedStatus:"killed",normalizedLifecycle:"suspended",normalizedRuntimeState:"stopped"}}function _k(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function $k(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function Ek(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function Dk(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function Ok(t){return t==="in_flight"||t==="delivered"?t:void 0}function Nk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!qe(n))return;let r=P(n.key),o=Ok(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 Wk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!qe(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 Lk(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 Bk(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 lc(t){if(!qe(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 Fk(t,e,n){if(qe(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 qk(t){if(!qe(t))return;let e=Tk(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 Uk(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 Kk(t){if(typeof t=="string"&&Sk.has(t))return t==="running"?"killed":t}function uc(t){if(!qe(t))return;let e=sn(t.harnessSessionId);if(!e)return;let n=Kk(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=lc(t.route);if(!l)return;let u=De({route:l,originChannel:s,originThreadId:a,originSessionKey:d});if(!u||o&&!i)return;let f=P(t.harness),p=Fk(t.backendRef,f,e),k=qk(t.worktreeLifecycle)??Uk(t),m=P(t.completionWakeSucceededAt),c=P(t.completionWakeSkippedAt),y=t.completionWakeSummaryRequired===!0&&!c?!0:void 0;return{sessionId:P(t.sessionId),harnessSessionId:e,backendRef:p,name:sn(t.name,e),prompt:sn(t.prompt),workdir:sn(t.workdir,"(unknown)"),model:P(t.model),reasoningEffort:rc(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:pe(t.createdAt),completedAt:pe(t.completedAt),status:n,lifecycle:r?"suspended":ac(t.lifecycle),approvalState:Ik(t.approvalState),worktreeState:xk(t.worktreeState),runtimeState:r?"stopped":dc(t.runtimeState),runtimeRecovery:r?Mk(t):Ck(t.runtimeRecovery),taskFlowMirror:wk(t.taskFlowMirror),deliveryState:Dk(t.deliveryState),notificationDedupe:Nk(t.notificationDedupe),completionSummaryDedupe:Wk(t.completionSummaryDedupe),completionWakeIssuedAt:P(t.completionWakeIssuedAt),completionWakeSucceededAt:m,completionWakeFailedAt:P(t.completionWakeFailedAt),completionWakeSkippedAt:c,completionWakeSkipReason:P(t.completionWakeSkipReason),completionWakeSummaryRequired:y,killReason:Ak(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:f,resumedFromSessionName:P(t.resumedFromSessionName),goalTaskId:P(t.goalTaskId),requestedPermissionMode:da(t.requestedPermissionMode),currentPermissionMode:da(t.currentPermissionMode),approvalExecutionState:Lk(t.approvalExecutionState),approvalRationale:P(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:bk(t.planApprovalContext),planDecisionVersion:pe(t.planDecisionVersion),actionablePlanDecisionVersion:pe(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:pe(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:pe(t.approvalPromptRequiredVersion),approvalPromptVersion:pe(t.approvalPromptVersion),approvalPromptStatus:_k(t.approvalPromptStatus),approvalPromptTransport:$k(t.approvalPromptTransport),approvalPromptMessageKind:Ek(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:P(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:P(t.approvalPromptDeliveredAt),approvalPromptFailedAt:P(t.approvalPromptFailedAt),planApproval:oc(t.planApproval),codexApprovalPolicy:Pk(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:ic(t.worktreeStrategy),repoIntegrationPolicy:la(t.repoIntegrationPolicy),repoIntegrationPolicySource:Rk(t.repoIntegrationPolicySource),repoProvider:sc(t.repoProvider),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:P(t.worktreeMergedAt),worktreePrUrl:P(t.worktreePrUrl),worktreePrNumber:pe(t.worktreePrNumber),pendingWorktreeDecisionSince:P(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:P(t.lastWorktreeReminderAt),worktreeBaseBranch:P(t.worktreeBaseBranch),worktreeParentBranch:P(t.worktreeParentBranch),worktreePrTargetRepo:P(t.worktreePrTargetRepo),autoMergeParentSessionId:P(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:pe(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,worktreeRemoteOutcome:t.worktreeRemoteOutcome==="pr-opened"||t.worktreeRemoteOutcome==="pr-updated"?t.worktreeRemoteOutcome:void 0,worktreeDismissedAt:P(t.worktreeDismissedAt),worktreeLifecycle:k,resumable:r?!0:t.resumable===!0}}function cc(t){if(!qe(t))return;let e=P(t.key),n=P(t.repoRoot),r=la(t.policy),o=sc(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 pc(t){if(!qe(t))return;let e=Bk(t.kind),n=sn(t.id),r=sn(t.sessionId),o=pe(t.createdAt);if(!(!n||!r||!e||o==null))return{id:n,sessionId:r,kind:e,createdAt:o,planDecisionVersion:pe(t.planDecisionVersion),expiresAt:pe(t.expiresAt),consumedAt:pe(t.consumedAt),optionIndex:pe(t.optionIndex),pendingInputRequestId:P(t.pendingInputRequestId),pendingInputQuestionId:P(t.pendingInputQuestionId),label:P(t.label),targetUrl:P(t.targetUrl),route:lc(t.route),launchName:P(t.launchName),launchPrompt:P(t.launchPrompt),launchWorkdir:P(t.launchWorkdir),launchModel:P(t.launchModel),launchReasoningEffort:rc(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),launchResumedFromSessionName:P(t.launchResumedFromSessionName),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:da(t.launchPermissionMode),launchPlanApproval:oc(t.launchPlanApproval),launchHarness:P(t.launchHarness),launchWorktreeStrategy:ic(t.launchWorktreeStrategy),launchWorktreeBaseBranch:P(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:P(t.launchWorktreePrTargetRepo),launchOriginAgentId:P(t.launchOriginAgentId),repoPolicy:la(t.repoPolicy),repoPolicyWorkdir:P(t.repoPolicyWorkdir)}}function Ho(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 Hn(t){return!!t&&typeof t=="object"}function ua(t){return t instanceof Error?t.message:String(t)}function Qk(t,e){JSON.stringify({component:"SessionStore",event:t,at:new Date().toISOString(),...e})}function Jk(t){return Hn(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 Sc(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(!mc(s))return s}}function ca(){let t=Hk();return Gk(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>kc(t,e))}function vc(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||kc(jo(t),"code-agent-sessions.json")}function wc(t,e,n,r=[]){try{Vk(zk(t),{recursive:!0});let o=t+".tmp";yc(o,JSON.stringify({schemaVersion:Go,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),fc(o,t)}catch(o){`${ua(o)}`}}function Yk(t,e){try{if(!mc(t))return!1;let n=Sc(t,"legacy");return n?(fc(t,n),`${e}${n}`,!0):!1}catch(n){return`${ua(n)}`,!1}}var Zk={archiveLegacySessionIndex:Yk};function Xk(t,e){try{if(e.length===0)return;let n=Sc(t,"codex-sdk-legacy");if(!n)return;yc(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${ua(n)}`}}function Pc(t,e,n=[]){try{let r=new Set(n);for(let o of ca())if(!r.has(o))try{let i=gc(o).mtimeMs;t-i>e&&hc(o)}catch{}}catch{}}function bc(t,e,n=[]){try{let r=new Set(n),o;for(let i of ca())if(!r.has(i))try{let s=gc(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function Rc(t){try{let e=new Set(t);for(let n of ca())if(!e.has(n))try{hc(n)}catch{}}catch{}}function Ac(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:a}=t,d=l=>Zk.archiveLegacySessionIndex(e,l)?(n(),!0):!1;try{let l=jk(e,"utf-8"),u=JSON.parse(l);if(Array.isArray(u)){if(!d("legacy array store"))return;a();return}if(!Hn(u)||u.schemaVersion!==Go&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!d(`schema mismatch (expected v${Go})`))return;a();return}let f=(A,h)=>{if(!Object.prototype.hasOwnProperty.call(u,A))return[];let w=u[A];if(Array.isArray(w))return w;d(h)&&a()},p=f("sessions","invalid sessions collection");if(p===void 0)return;let k=[],m=[],c=!1;for(let A of p){if(Hn(A)&&A.harness==="codex"){let w=Hn(A.backendRef)?A.backendRef:void 0;if((typeof w?.kind=="string"?w.kind:void 0)!=="codex-app-server"){k.push(A);continue}}let h=uc(A);if(!h){if(!d("invalid v4 session entry"))return;a();return}Hn(A)&&A.status==="running"&&(c=!0,Qk("session.recovered_from_running_persisted_row",{sessionId:typeof A.sessionId=="string"?A.sessionId:void 0,hasHarnessSessionId:typeof A.harnessSessionId=="string"&&A.harnessSessionId.length>0,...Jk(A.backendRef),rawStatus:A.status,rawLifecycle:A.lifecycle,rawRuntimeState:A.runtimeState,normalizedStatus:h.status,normalizedLifecycle:h.lifecycle,normalizedRuntimeState:h.runtimeState,reason:h.runtimeRecovery?.reason})),m.push(h)}k.length>0&&Xk(e,k);let y=f("actionTokens","invalid action token collection");if(y===void 0)return;let S=[];for(let A of y){let h=pc(A);if(!h){if(!d("invalid v4 action token"))return;a();return}S.push(h)}let b=f("repoPolicies","invalid repo policy collection");if(b===void 0)return;let x=[],T=!1;for(let A of b){let h=cc(A);if(!h){T=!0;continue}x.push(h)}for(let A of m)r(A);for(let A of S)o(A);for(let A of x)i(A);(k.length>0||c)&&a(),T&&a(),s()}catch(l){if(l.code==="ENOENT"||!d("corrupt or unreadable"))return;a()}}var rS=new Set(["completed","failed","killed"]),pa=1440*60*1e3;function oS(t){return t instanceof Error?t.message:String(t)}var iS={statSync:tS};function sS(t){try{return iS.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var zo=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??vc(n),this.actionTokenStore=new Ko(()=>this.saveIndex(),pa),this.actionTokens=this.actionTokenStore.tokens,this.queries=new Vo({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Ac({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(){wc(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){Ho(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=Xi(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,worktreeParentBranch:e.worktreeParentBranch,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=De({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:St(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,worktreeParentBranch:o.worktreeParentBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Ho(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=De({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let d=St(e.id);if(eS(d))s=d;else{let l=e.getOutput().join(`
257
- `);l.length>0&&(nS(d,l,"utf-8"),s=d)}}catch(d){`${e.id}${oS(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,worktreeParentBranch:o.worktreeParentBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Ho(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)sS(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),Pc(e,pa,this.getReferencedOutputPaths())}getNextTmpOutputCleanupAt(e){return bc(e,pa,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||!rS.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(){Rc(this.getReferencedOutputPaths())}};var aS=new Set(["completed","failed","killed"]),Qo=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),aS.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:ue(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 Ic 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 ma=3e4,dS=2e3,lS=2e4,ve=4;function zn(t){return t instanceof Error?t.message:String(t)}function uS(){return new Error(`Dispatch timed out after ${ma}ms`)}function cS(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var pS={execFile:Ic.execFile},Jo=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:ve}),pS.execFile("openclaw",e,{timeout:ma,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:ve,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:ve,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:ve,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"&&cS(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:ve,elapsedMs:l,error:`${zn(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(o>=ve||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:ve,elapsedMs:l,error:`${zn(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:ve,elapsedMs:l,retryDelayMs:p,error:`${zn(s)}${u}`});let k={timer:setTimeout(()=>{let m=this.pendingRetryTimers.get(n.sessionId);if(m&&(m.delete(k),m.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executeNow(e,n,r,o+1)},p),onCleared:r};k.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(k)})}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:ve}),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:ve,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>=ve||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:ve,elapsedMs:a,error:zn(s),terminal:!0,...n.terminalOnFailure===!0&&o<ve?{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:ve,elapsedMs:a,retryDelayMs:d,error:zn(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(uS()))},ma);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=dS*2**n;return Math.min(r,lS)}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}}};ye();var Yo=class{resolve(e){let n=Ue(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 mS}from"crypto";var Zo=class{constructor(e={}){}buildChatSendArgs(e,n,r,o=mS()){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=er(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 fS(t){let e=gS(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 gS(t){let e=t.trim();if(!e)return"";try{return fa(JSON.parse(e)).trim()}catch{return e}}function fa(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>fa(r)).filter(Boolean).join(`
258
- `);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=fa(e[r]);if(o.trim())return o}return""}var Xo=class{routes=new Yo;transport;directNotifications;executor=new Jo;constructor(e={}){this.transport=e.transport??new Zo(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new Dt: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 f=this.routes.resolve(e),p=a;if(p?.()===!1)return;let k=f?.sessionKey?.trim();if(!k){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(k,n,!0,u),{label:r,sessionId:e.id,target:"chat.send",phase:o,routeSummary:`session:${k}`,messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:`session:${k}`,route:f,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);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,...X(o)});let f=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,...X(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:f,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,...X(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:f,onSuccess:s,onFinalFailure:i,shouldContinue:d})},k={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:f,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,...X(o)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,o),k);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,...X(o)}),this.executor.execute(this.transport.buildDirectNotificationArgs(u,n,o),k)}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,f)=>u.buttons?.some(p=>Array.isArray(p)&&p.length>0)?f+1:void 0).filter(u=>typeof u=="number"),requireDirectDelivery:s});let l=u=>{if(a?.()===!1)return;let f=d[u];if(!f){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:f.text.length,failureHandler:u===0?"all-failed":"sequence-success",...X(f.buttons)}),this.sendUserNotification(e,f.text,`${r}-part-${u+1}`,f.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?fS:void 0;if(o){let u=n.wakeMessageOnNotifySuccess?.trim(),f=n.wakeMessageOnNotifyFailed?.trim(),p=y=>{y&&d?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,y,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,d,l,r?.onWakeSkipped,n.idempotencyKey))},k=y=>{if(y){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let S=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>p(y),S).unref?.();return}p(y)}},m=()=>{d?.()!==!1&&(r?.onNotifySucceeded?.(),u&&k(u))},c=f?()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),k(f))}:()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,c,m,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 xc=36,Tc=2,Cc="...";function hS(t){let e=Array.from(t);return e.length<=xc?t:`${e.slice(0,xc-Cc.length).join("")}${Cc}`}var ei=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)}consumeQuestionAnswerTokens(e,n){return this.actionTokens.consumeQuestionAnswerTokens(e,n)}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,...X(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:hS(s.label),callbackData:d.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=Tc)i.push(o.slice(s,s+Tc));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,...X(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),...X(r)}),r}};ne();ye();import{createHash as vS}from"crypto";var yS="duplicate notification already delivered or in flight",ti=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:yS}:(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))}};ye();ne();ye();import{createHash as kS}from"crypto";var SS=1024,Qn="duplicate completion follow-up wake already handled",ni="prior human-visible summary already delivered",ri=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??Qn}:(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,ni);let f=this.deliveredRecords(i.claimKeys,s,o,ni);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:f}}finish(e,n,r=Qn){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=Qn){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=Qn){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===ni&&o!==ni||(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"),f=this.isTerminalLike(n,o),p=o.startsWith("worktree-pr:")?this.normalizeWorktreePrOutcome(n.outcomeKey?.trim()):void 0,k=p?.aliases.map(m=>`${this.buildVisibleScope(r,e)}:outcome:${this.digest(m)}`)??[];return{primary:a,explicit:!0,claimKeys:[...l,...d?u:[],...k,a],decisionKeys:[a,...p?.blocksAliases?k:[],...d||f?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=Ue(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 G(e)??O(e)??""}digest(e){return kS("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=Qn){let i=new Date().toISOString(),s=this.normalizeRecords(n),a=new Set(e),l=[...s.filter(u=>!a.has(u.key)&&!(u.linkedKeys??[]).some(f=>a.has(f))),...e.map(u=>{let f=e.filter(p=>p!==u);return{key:u,linkedKeys:f.length>0?f:void 0,recordedAt:i,label:r,skipReason:o}})];return l.slice(Math.max(0,l.length-this.maxCompletedKeys))}};var wS=2e3,PS=new Set(["1","true","yes","on"]);function bS(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&PS.has(t))||wi()}function RS(t){bS()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
259
- `)}function AS(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 oi=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new ri({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new ti({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 f=this.buildCompletionWakePatch(u),p=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifySuccess?.trim()),k=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifyFailed?.trim()),m=!1,c=!1,y=()=>{c||(c=!0,m||(this.releaseNotificationDedupe(r,i),m=!0),this.completionSummaries.finish(l.key,!1))},S=u.shouldDispatch?()=>{let x=u.shouldDispatch?.()!==!1;return x||y(),x}: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?f:void 0),p||this.completionSummaries.finish(l.key,!1),u.hooks?.onNotifySucceeded?.()},onNotifyFailed:()=>{this.applyNotifyDeliveryState(r,k?"wake_pending":"failed",k?f:void 0),k||(this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),m=!0),u.hooks?.onNotifyFailed?.()},onWakeStarted:()=>{this.applyPersistedPatchWithCompletionWake(r,"wake_pending",f,{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(f),{completionWakeSucceededAt:new Date().toISOString(),completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSucceeded?.()},onWakeSkipped:x=>{if(c){u.hooks?.onWakeSkipped?.(x);return}m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label,x),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(f),{completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:new Date().toISOString(),completionWakeSkipReason:x}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSkipped?.(x)},onWakeFailed:()=>{this.applyPersistedPatchWithCompletionWake(r,"failed",f,{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=AS(r.completionWakeOutcomeKey);o&&i&&this.applyPersistedPatch(o,{worktreeRemoteOutcome:i});let s=IS(n,e),a=f=>on({sessionId:o,sessionName:e.name,outcomeLine:s,originThreadLine:fn(e),detailLines:r.detailLines,canonicalStatusDelivered:f}),d=r.summaryWakeRequired??!0,l={required:d,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},u=r.completionSummaryOwner!=="foreground";if(d&&!u){let f=this.getDeliveryRef(e),p=this.completionSummaries.recordVisibleDelivery(e,l,f?this.getPersistedSession?.(f)?.completionSummaryDedupe:void 0,"worktree-outcome");p.records&&this.applyCompletionSummaryDedupePatch(f,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:wS,wakeMessageOnNotifySuccess:d&&u?a(!0):void 0,wakeMessageOnNotifyFailed:d&&u?a(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return G(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}
256
+ `),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}){if(this.deps.isAlreadyMerged(a)||e.autoMergeResolverSessionId)return!1;let l=!1;return await this.deps.enqueueMerge(n,async()=>{if(this.deps.isAlreadyMerged(a))return;let u=this.deps.mergeBranch(n,o,i,"merge",r);if(u.success){l=this.handleAutoMergeSuccess(e,n,r,o,i,s,u);return}if(u.rebaseConflict){await this.handleInitialAutoMergeConflict(e,n,r,o,i,d,u.error,u);return}let f=Be(u.dirtyError?`❌ [${e.name}] Merge blocked: ${u.error}`:`❌ [${e.name}] Merge failed: ${u.error??"unknown error"}`,u);if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,o,r,f,d);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${o}:${$e(e)}`,userMessage:f})},()=>{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.`})}),l}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)??Qe(e,n,r)}releaseIfRepresentedByTargetPrBranch(e,n,r,o,i){if(wt(r).length>0)return;let s=this.resolveExistingTargetPr(e,n,o,i),a=s?.headRefName;if(!a||a===o||a===i)return;let d=this.deps.fetchRemoteBranch?this.deps.fetchRemoteBranch(n,a):Kr(n,a);if(!d||!!!((s?.state==="open"||s?.state==="merged")&&s?.baseRefName===i&&Se(n,o,d)))return;let u=le(e)?!0:ce(n,r);return u?(e.worktreePath=void 0,e.worktreePrUrl=s.url,e.worktreePrNumber=s.number,e.worktreePrTargetRepo=Tn(n,e.worktreePrTargetRepo),this.updatePersistedSessionFor(e,{worktreePath:void 0,worktreePrUrl:s.url,worktreePrNumber:s.number,worktreePrTargetRepo:e.worktreePrTargetRepo,worktreeRemoteOutcome:"pr-updated"}),Pe(n,o),this.markReleased(e,[`released_by_branch:${a}`]),{notificationSent:!1,worktreeRemoved:u}):(this.markPendingDecision(e,{notes:[`represented_by_branch:${a}`,"represented_worktree_cleanup_failed"]}),{notificationSent:!1,worktreeRemoved:!1})}};import{existsSync as tS,statSync as nS,writeFileSync as rS}from"fs";ye();import{randomUUID as hk}from"crypto";function yk(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var Ko=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:hk(),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}consumeQuestionAnswerTokens(e,n){let r=[],o=Date.now();for(let i of this.tokens.values())i.sessionId!==e||i.kind!=="question-answer"||i.pendingInputRequestId!==n||i.consumedAt!=null||(i.consumedAt=o,r.push(i));return r.length>0&&this.notifyChanged(),r}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||!yk(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?.()}};ne();ne();var Vo=class{constructor(e){this.indexes=e}indexes;hasRecordedSession(e){return this.indexes.idIndex.has(e)}getLatestPersistedByName(e){let n,r=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,s=0;for(let a of this.indexes.persisted.values()){if(a.name!==e){s++;continue}let 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 mc,mkdirSync as jk,readFileSync as Gk,readdirSync as Hk,renameSync as fc,statSync as gc,unlinkSync as hc,writeFileSync as yc}from"fs";import{tmpdir as zk}from"os";import{dirname as Qk,join as kc}from"path";import{homedir as kk}from"node:os";import{join as Sk}from"node:path";function jo(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||kk();return Sk(n,".openclaw")}ye();var Go=7,vk=new Set(["running","completed","failed","killed"]),wk=new Set(["queued","running","waiting","blocked","succeeded","failed","cancelled","lost"]);function qe(t){return!!t&&typeof t=="object"}function sn(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 pe(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function Pk(t){if(!qe(t))return;let e=P(t.flowId),n=pe(t.revision);if(!e||n===void 0)return;let r=typeof t.status=="string"&&wk.has(t.status)?t.status:void 0;return{flowId:e,revision:n,...r?{status:r}:{}}}function rc(t){return typeof t=="string"&&xl.has(t)?t:void 0}function ua(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function bk(t){return t==="never"||t==="on-request"?"never":void 0}function oc(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function Rk(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function ic(t){return typeof t=="string"&&ro.has(t)?t:void 0}function ca(t){return typeof t=="string"&&Il.has(t)?t:void 0}function sc(t){return t==="github"||t==="unsupported"?t:void 0}function Ak(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function Ik(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function ac(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 xk(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function Tk(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 Ck(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 dc(t){return t==="live"||t==="stopped"?t:void 0}function Mk(t){if(!qe(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:pe(t.rawCompletedAt),rawOutputPath:P(t.rawOutputPath),normalizedStatus:n,normalizedLifecycle:ac(t.normalizedLifecycle),normalizedRuntimeState:dc(t.normalizedRuntimeState)}}function _k(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:pe(t.completedAt),rawOutputPath:P(t.outputPath),normalizedStatus:"killed",normalizedLifecycle:"suspended",normalizedRuntimeState:"stopped"}}function $k(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function Ek(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function Dk(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function Ok(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function Nk(t){return t==="in_flight"||t==="delivered"?t:void 0}function Wk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!qe(n))return;let r=P(n.key),o=Nk(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 Lk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!qe(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 Bk(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 Fk(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 lc(t){if(!qe(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 qk(t,e,n){if(qe(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 Uk(t){if(!qe(t))return;let e=Ck(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 Kk(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 Vk(t){if(typeof t=="string"&&vk.has(t))return t==="running"?"killed":t}function uc(t){if(!qe(t))return;let e=sn(t.harnessSessionId);if(!e)return;let n=Vk(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=lc(t.route);if(!l)return;let u=De({route:l,originChannel:s,originThreadId:a,originSessionKey:d});if(!u||o&&!i)return;let f=P(t.harness),p=qk(t.backendRef,f,e),k=Uk(t.worktreeLifecycle)??Kk(t),m=P(t.completionWakeSucceededAt),c=P(t.completionWakeSkippedAt),y=t.completionWakeSummaryRequired===!0&&!c?!0:void 0;return{sessionId:P(t.sessionId),harnessSessionId:e,backendRef:p,name:sn(t.name,e),prompt:sn(t.prompt),workdir:sn(t.workdir,"(unknown)"),model:P(t.model),reasoningEffort:rc(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:pe(t.createdAt),completedAt:pe(t.completedAt),status:n,lifecycle:r?"suspended":ac(t.lifecycle),approvalState:xk(t.approvalState),worktreeState:Tk(t.worktreeState),runtimeState:r?"stopped":dc(t.runtimeState),runtimeRecovery:r?_k(t):Mk(t.runtimeRecovery),taskFlowMirror:Pk(t.taskFlowMirror),deliveryState:Ok(t.deliveryState),notificationDedupe:Wk(t.notificationDedupe),completionSummaryDedupe:Lk(t.completionSummaryDedupe),completionWakeIssuedAt:P(t.completionWakeIssuedAt),completionWakeSucceededAt:m,completionWakeFailedAt:P(t.completionWakeFailedAt),completionWakeSkippedAt:c,completionWakeSkipReason:P(t.completionWakeSkipReason),completionWakeSummaryRequired:y,killReason:Ik(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:f,resumedFromSessionName:P(t.resumedFromSessionName),goalTaskId:P(t.goalTaskId),requestedPermissionMode:ua(t.requestedPermissionMode),currentPermissionMode:ua(t.currentPermissionMode),approvalExecutionState:Bk(t.approvalExecutionState),approvalRationale:P(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:Rk(t.planApprovalContext),planDecisionVersion:pe(t.planDecisionVersion),actionablePlanDecisionVersion:pe(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:pe(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:pe(t.approvalPromptRequiredVersion),approvalPromptVersion:pe(t.approvalPromptVersion),approvalPromptStatus:$k(t.approvalPromptStatus),approvalPromptTransport:Ek(t.approvalPromptTransport),approvalPromptMessageKind:Dk(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:P(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:P(t.approvalPromptDeliveredAt),approvalPromptFailedAt:P(t.approvalPromptFailedAt),planApproval:oc(t.planApproval),codexApprovalPolicy:bk(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:ic(t.worktreeStrategy),repoIntegrationPolicy:ca(t.repoIntegrationPolicy),repoIntegrationPolicySource:Ak(t.repoIntegrationPolicySource),repoProvider:sc(t.repoProvider),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:P(t.worktreeMergedAt),worktreePrUrl:P(t.worktreePrUrl),worktreePrNumber:pe(t.worktreePrNumber),pendingWorktreeDecisionSince:P(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:P(t.lastWorktreeReminderAt),worktreeBaseBranch:P(t.worktreeBaseBranch),worktreeParentBranch:P(t.worktreeParentBranch),worktreePrTargetRepo:P(t.worktreePrTargetRepo),autoMergeParentSessionId:P(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:pe(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,worktreeRemoteOutcome:t.worktreeRemoteOutcome==="pr-opened"||t.worktreeRemoteOutcome==="pr-updated"?t.worktreeRemoteOutcome:void 0,worktreeDismissedAt:P(t.worktreeDismissedAt),worktreeLifecycle:k,resumable:r?!0:t.resumable===!0}}function cc(t){if(!qe(t))return;let e=P(t.key),n=P(t.repoRoot),r=ca(t.policy),o=sc(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 pc(t){if(!qe(t))return;let e=Fk(t.kind),n=sn(t.id),r=sn(t.sessionId),o=pe(t.createdAt);if(!(!n||!r||!e||o==null))return{id:n,sessionId:r,kind:e,createdAt:o,planDecisionVersion:pe(t.planDecisionVersion),expiresAt:pe(t.expiresAt),consumedAt:pe(t.consumedAt),optionIndex:pe(t.optionIndex),pendingInputRequestId:P(t.pendingInputRequestId),pendingInputQuestionId:P(t.pendingInputQuestionId),label:P(t.label),targetUrl:P(t.targetUrl),route:lc(t.route),launchName:P(t.launchName),launchPrompt:P(t.launchPrompt),launchWorkdir:P(t.launchWorkdir),launchModel:P(t.launchModel),launchReasoningEffort:rc(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),launchResumedFromSessionName:P(t.launchResumedFromSessionName),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:ua(t.launchPermissionMode),launchPlanApproval:oc(t.launchPlanApproval),launchHarness:P(t.launchHarness),launchWorktreeStrategy:ic(t.launchWorktreeStrategy),launchWorktreeBaseBranch:P(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:P(t.launchWorktreePrTargetRepo),launchOriginAgentId:P(t.launchOriginAgentId),repoPolicy:ca(t.repoPolicy),repoPolicyWorkdir:P(t.repoPolicyWorkdir)}}function Ho(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 Hn(t){return!!t&&typeof t=="object"}function pa(t){return t instanceof Error?t.message:String(t)}function Jk(t,e){JSON.stringify({component:"SessionStore",event:t,at:new Date().toISOString(),...e})}function Yk(t){return Hn(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 Sc(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(!mc(s))return s}}function ma(){let t=zk();return Hk(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>kc(t,e))}function vc(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||kc(jo(t),"code-agent-sessions.json")}function wc(t,e,n,r=[]){try{jk(Qk(t),{recursive:!0});let o=t+".tmp";yc(o,JSON.stringify({schemaVersion:Go,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),fc(o,t)}catch(o){`${pa(o)}`}}function Zk(t,e){try{if(!mc(t))return!1;let n=Sc(t,"legacy");return n?(fc(t,n),`${e}${n}`,!0):!1}catch(n){return`${pa(n)}`,!1}}var Xk={archiveLegacySessionIndex:Zk};function eS(t,e){try{if(e.length===0)return;let n=Sc(t,"codex-sdk-legacy");if(!n)return;yc(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${pa(n)}`}}function Pc(t,e,n=[]){try{let r=new Set(n);for(let o of ma())if(!r.has(o))try{let i=gc(o).mtimeMs;t-i>e&&hc(o)}catch{}}catch{}}function bc(t,e,n=[]){try{let r=new Set(n),o;for(let i of ma())if(!r.has(i))try{let s=gc(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function Rc(t){try{let e=new Set(t);for(let n of ma())if(!e.has(n))try{hc(n)}catch{}}catch{}}function Ac(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:a}=t,d=l=>Xk.archiveLegacySessionIndex(e,l)?(n(),!0):!1;try{let l=Gk(e,"utf-8"),u=JSON.parse(l);if(Array.isArray(u)){if(!d("legacy array store"))return;a();return}if(!Hn(u)||u.schemaVersion!==Go&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!d(`schema mismatch (expected v${Go})`))return;a();return}let f=(A,h)=>{if(!Object.prototype.hasOwnProperty.call(u,A))return[];let w=u[A];if(Array.isArray(w))return w;d(h)&&a()},p=f("sessions","invalid sessions collection");if(p===void 0)return;let k=[],m=[],c=!1;for(let A of p){if(Hn(A)&&A.harness==="codex"){let w=Hn(A.backendRef)?A.backendRef:void 0;if((typeof w?.kind=="string"?w.kind:void 0)!=="codex-app-server"){k.push(A);continue}}let h=uc(A);if(!h){if(!d("invalid v4 session entry"))return;a();return}Hn(A)&&A.status==="running"&&(c=!0,Jk("session.recovered_from_running_persisted_row",{sessionId:typeof A.sessionId=="string"?A.sessionId:void 0,hasHarnessSessionId:typeof A.harnessSessionId=="string"&&A.harnessSessionId.length>0,...Yk(A.backendRef),rawStatus:A.status,rawLifecycle:A.lifecycle,rawRuntimeState:A.runtimeState,normalizedStatus:h.status,normalizedLifecycle:h.lifecycle,normalizedRuntimeState:h.runtimeState,reason:h.runtimeRecovery?.reason})),m.push(h)}k.length>0&&eS(e,k);let y=f("actionTokens","invalid action token collection");if(y===void 0)return;let S=[];for(let A of y){let h=pc(A);if(!h){if(!d("invalid v4 action token"))return;a();return}S.push(h)}let b=f("repoPolicies","invalid repo policy collection");if(b===void 0)return;let x=[],T=!1;for(let A of b){let h=cc(A);if(!h){T=!0;continue}x.push(h)}for(let A of m)r(A);for(let A of S)o(A);for(let A of x)i(A);(k.length>0||c)&&a(),T&&a(),s()}catch(l){if(l.code==="ENOENT"||!d("corrupt or unreadable"))return;a()}}var oS=new Set(["completed","failed","killed"]),fa=1440*60*1e3;function iS(t){return t instanceof Error?t.message:String(t)}var sS={statSync:nS};function aS(t){try{return sS.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var zo=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??vc(n),this.actionTokenStore=new Ko(()=>this.saveIndex(),fa),this.actionTokens=this.actionTokenStore.tokens,this.queries=new Vo({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Ac({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(){wc(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){Ho(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=ts(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,worktreeParentBranch:e.worktreeParentBranch,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=De({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:St(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,worktreeParentBranch:o.worktreeParentBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Ho(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=De({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let d=St(e.id);if(tS(d))s=d;else{let l=e.getOutput().join(`
257
+ `);l.length>0&&(rS(d,l,"utf-8"),s=d)}}catch(d){`${e.id}${iS(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,worktreeParentBranch:o.worktreeParentBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Ho(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)aS(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),Pc(e,fa,this.getReferencedOutputPaths())}getNextTmpOutputCleanupAt(e){return bc(e,fa,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||!oS.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(){Rc(this.getReferencedOutputPaths())}};var dS=new Set(["completed","failed","killed"]),Qo=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),dS.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:ue(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 Ic 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 ga=3e4,lS=2e3,uS=2e4,ve=4;function zn(t){return t instanceof Error?t.message:String(t)}function cS(){return new Error(`Dispatch timed out after ${ga}ms`)}function pS(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var mS={execFile:Ic.execFile},Jo=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:ve}),mS.execFile("openclaw",e,{timeout:ga,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:ve,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:ve,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:ve,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"&&pS(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:ve,elapsedMs:l,error:`${zn(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(o>=ve||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:ve,elapsedMs:l,error:`${zn(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:ve,elapsedMs:l,retryDelayMs:p,error:`${zn(s)}${u}`});let k={timer:setTimeout(()=>{let m=this.pendingRetryTimers.get(n.sessionId);if(m&&(m.delete(k),m.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executeNow(e,n,r,o+1)},p),onCleared:r};k.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(k)})}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:ve}),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:ve,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>=ve||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:ve,elapsedMs:a,error:zn(s),terminal:!0,...n.terminalOnFailure===!0&&o<ve?{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:ve,elapsedMs:a,retryDelayMs:d,error:zn(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(cS()))},ga);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=lS*2**n;return Math.min(r,uS)}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}}};ye();var Yo=class{resolve(e){let n=Ue(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 fS}from"crypto";var Zo=class{constructor(e={}){}buildChatSendArgs(e,n,r,o=fS()){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=er(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 gS(t){let e=hS(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 hS(t){let e=t.trim();if(!e)return"";try{return ha(JSON.parse(e)).trim()}catch{return e}}function ha(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>ha(r)).filter(Boolean).join(`
258
+ `);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=ha(e[r]);if(o.trim())return o}return""}var Xo=class{routes=new Yo;transport;directNotifications;executor=new Jo;constructor(e={}){this.transport=e.transport??new Zo(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new Dt: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 f=this.routes.resolve(e),p=a;if(p?.()===!1)return;let k=f?.sessionKey?.trim();if(!k){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(k,n,!0,u),{label:r,sessionId:e.id,target:"chat.send",phase:o,routeSummary:`session:${k}`,messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:`session:${k}`,route:f,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);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,...X(o)});let f=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,...X(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:f,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,...X(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:f,onSuccess:s,onFinalFailure:i,shouldContinue:d})},k={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:f,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,...X(o)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,o),k);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,...X(o)}),this.executor.execute(this.transport.buildDirectNotificationArgs(u,n,o),k)}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,f)=>u.buttons?.some(p=>Array.isArray(p)&&p.length>0)?f+1:void 0).filter(u=>typeof u=="number"),requireDirectDelivery:s});let l=u=>{if(a?.()===!1)return;let f=d[u];if(!f){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:f.text.length,failureHandler:u===0?"all-failed":"sequence-success",...X(f.buttons)}),this.sendUserNotification(e,f.text,`${r}-part-${u+1}`,f.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?gS:void 0;if(o){let u=n.wakeMessageOnNotifySuccess?.trim(),f=n.wakeMessageOnNotifyFailed?.trim(),p=y=>{y&&d?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,y,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,d,l,r?.onWakeSkipped,n.idempotencyKey))},k=y=>{if(y){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let S=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>p(y),S).unref?.();return}p(y)}},m=()=>{d?.()!==!1&&(r?.onNotifySucceeded?.(),u&&k(u))},c=f?()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),k(f))}:()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,c,m,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 xc=36,Tc=2,Cc="...";function yS(t){let e=Array.from(t);return e.length<=xc?t:`${e.slice(0,xc-Cc.length).join("")}${Cc}`}var ei=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)}consumeQuestionAnswerTokens(e,n){return this.actionTokens.consumeQuestionAnswerTokens(e,n)}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,...X(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:yS(s.label),callbackData:d.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=Tc)i.push(o.slice(s,s+Tc));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,...X(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),...X(r)}),r}};ne();ye();import{createHash as wS}from"crypto";var kS="duplicate notification already delivered or in flight",ti=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:kS}:(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))}};ye();ne();ye();import{createHash as SS}from"crypto";var vS=1024,Qn="duplicate completion follow-up wake already handled",ni="prior human-visible summary already delivered",ri=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??vS))}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??Qn}:(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,ni);let f=this.deliveredRecords(i.claimKeys,s,o,ni);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:f}}finish(e,n,r=Qn){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=Qn){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=Qn){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===ni&&o!==ni||(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"),f=this.isTerminalLike(n,o),p=o.startsWith("worktree-pr:")?this.normalizeWorktreePrOutcome(n.outcomeKey?.trim()):void 0,k=p?.aliases.map(m=>`${this.buildVisibleScope(r,e)}:outcome:${this.digest(m)}`)??[];return{primary:a,explicit:!0,claimKeys:[...l,...d?u:[],...k,a],decisionKeys:[a,...p?.blocksAliases?k:[],...d||f?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=Ue(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 G(e)??O(e)??""}digest(e){return SS("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=Qn){let i=new Date().toISOString(),s=this.normalizeRecords(n),a=new Set(e),l=[...s.filter(u=>!a.has(u.key)&&!(u.linkedKeys??[]).some(f=>a.has(f))),...e.map(u=>{let f=e.filter(p=>p!==u);return{key:u,linkedKeys:f.length>0?f:void 0,recordedAt:i,label:r,skipReason:o}})];return l.slice(Math.max(0,l.length-this.maxCompletedKeys))}};var PS=2e3,bS=new Set(["1","true","yes","on"]);function RS(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&bS.has(t))||wi()}function AS(t){RS()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
259
+ `)}function IS(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 oi=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new ri({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new ti({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 f=this.buildCompletionWakePatch(u),p=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifySuccess?.trim()),k=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifyFailed?.trim()),m=!1,c=!1,y=()=>{c||(c=!0,m||(this.releaseNotificationDedupe(r,i),m=!0),this.completionSummaries.finish(l.key,!1))},S=u.shouldDispatch?()=>{let x=u.shouldDispatch?.()!==!1;return x||y(),x}: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?f:void 0),p||this.completionSummaries.finish(l.key,!1),u.hooks?.onNotifySucceeded?.()},onNotifyFailed:()=>{this.applyNotifyDeliveryState(r,k?"wake_pending":"failed",k?f:void 0),k||(this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),m=!0),u.hooks?.onNotifyFailed?.()},onWakeStarted:()=>{this.applyPersistedPatchWithCompletionWake(r,"wake_pending",f,{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(f),{completionWakeSucceededAt:new Date().toISOString(),completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSucceeded?.()},onWakeSkipped:x=>{if(c){u.hooks?.onWakeSkipped?.(x);return}m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label,x),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(f),{completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:new Date().toISOString(),completionWakeSkipReason:x}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSkipped?.(x)},onWakeFailed:()=>{this.applyPersistedPatchWithCompletionWake(r,"failed",f,{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=IS(r.completionWakeOutcomeKey);o&&i&&this.applyPersistedPatch(o,{worktreeRemoteOutcome:i});let s=xS(n,e),a=f=>on({sessionId:o,sessionName:e.name,outcomeLine:s,originThreadLine:fn(e),detailLines:r.detailLines,canonicalStatusDelivered:f}),d=r.summaryWakeRequired??!0,l={required:d,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},u=r.completionSummaryOwner!=="foreground";if(d&&!u){let f=this.getDeliveryRef(e),p=this.completionSummaries.recordVisibleDelivery(e,l,f?this.getPersistedSession?.(f)?.completionSummaryDedupe:void 0,"worktree-outcome");p.records&&this.applyCompletionSummaryDedupePatch(f,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:PS,wakeMessageOnNotifySuccess:d&&u?a(!0):void 0,wakeMessageOnNotifyFailed:d&&u?a(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return G(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}
260
260
  ${n.join(`
261
261
  ---completion-wake---
262
- `)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=Ue(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=Ue(e.session);RS({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 vS("sha256").update(e).digest("hex").slice(0,16)}};function IS(t,e){let n=ct(e);return n?`${t}${n}`:t}Re();import{existsSync as xS}from"fs";var ii=class{getCompletionState(e,n,r,o){let i=xn(e,r,o);if(i===void 0)return"has-commits";if(i===0){let s=xn(e,o,r);return s===void 0?"has-commits":s>0?Se(e,r,o)?"merged":"base-advanced":Pt(n)?"dirty-uncommitted":"no-change"}return Pt(n)?"dirty-uncommitted":Vr(e,r,o)?"released":"has-commits"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!xS(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 TS}from"node:crypto";function CS(t){let e=t.pendingInputState,n=e?.activeQuestionIndex??0;return e?.questions?.[n]?.id??(e?.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:void 0)}var si=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=CS(e),u=e.pendingInputState?.requestId??`legacy:${TS()}`,f=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((k,m)=>` ${m+1}. ${k.label}`)]:[],"",`Send the question to the user and call agent_respond(session="${e.id}", message="<answer>") with their answer.`].join(`
262
+ `)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=Ue(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=Ue(e.session);AS({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 wS("sha256").update(e).digest("hex").slice(0,16)}};function xS(t,e){let n=ct(e);return n?`${t}${n}`:t}Re();import{existsSync as TS}from"fs";var ii=class{getCompletionState(e,n,r,o){let i=xn(e,r,o);if(i===void 0)return"has-commits";if(i===0){let s=xn(e,o,r);return s===void 0?"has-commits":s>0?Se(e,r,o)?"merged":"base-advanced":Pt(n)?"dirty-uncommitted":"no-change"}return Pt(n)?"dirty-uncommitted":Vr(e,r,o)?"released":"has-commits"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!TS(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 CS}from"node:crypto";function MS(t){let e=t.pendingInputState,n=e?.activeQuestionIndex??0;return e?.questions?.[n]?.id??(e?.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:void 0)}var si=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=MS(e),u=e.pendingInputState?.requestId??`legacy:${CS()}`,f=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((k,m)=>` ${m+1}. ${k.label}`)]:[],"",`Send the question to the user and call agent_respond(session="${e.id}", message="<answer>") with their answer.`].join(`
263
263
  `);return new Promise((k,m)=>{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 y=setTimeout(()=>{this.pendingQuestions.delete(e.id),m(new Error(`AskUserQuestion timed out after ${6e5/1e3}s for session "${e.name}"`))},6e5);y.unref?.(),this.pendingQuestions.set(e.id,{resolve:k,reject:m,questions:i,timeoutHandle:y,requestId:u,questionId:l}),this.dispatchSessionNotification(e,{label:"ask-user-question",idempotencyKey:`ask-user-question:${e.id}:${u}`,userMessage:d,notifyUser:"always",buttons:f,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(`
264
- `),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()}};ne();Cn();var MS=new Set(["merged","released","dismissed","none","cleanup_failed"]),_S=new Set(["merged","released","dismissed","no_change","none","cleanup_failed"]),ai=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:Zs(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(`
265
- `);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 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=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&&MS.has(e.worktreeState)||e.worktreeLifecycle?.state&&_S.has(e.worktreeLifecycle.state))}isResolvedDerivedWorktreeState(e){return e==="merged"||e==="released"||e==="no_change"||e==="cleanup_failed"}};Re();ne();ye();function Jn(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&$S(t.approvalPromptStatus)}function $S(t){return t==="delivered"||t==="fallback_delivered"}function Yn(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(`
264
+ `),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()}};ne();Cn();var _S=new Set(["merged","released","dismissed","none","cleanup_failed"]),$S=new Set(["merged","released","dismissed","no_change","none","cleanup_failed"]),ai=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:ea(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(`
265
+ `);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 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=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&&_S.has(e.worktreeState)||e.worktreeLifecycle?.state&&$S.has(e.worktreeLifecycle.state))}isResolvedDerivedWorktreeState(e){return e==="merged"||e==="released"||e==="no_change"||e==="cleanup_failed"}};Re();ne();ye();function Jn(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&ES(t.approvalPromptStatus)}function ES(t){return t==="delivered"||t==="fallback_delivered"}function Yn(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(`
266
266
  `)}function di(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(`
267
- `)}import{existsSync as US,readFileSync as KS}from"fs";ft();var ES=4e3,Mc=180,DS=300;function _c(){let t=tt(),e=WS(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=LS(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 $c(t){let e=li(t.question??""),n=li(BS(e,t.context??""));if(!t.provider||!e||!n)return;let r={sessionName:t.sessionName,question:e,context:FS(n,ES)};try{let o=await qS(t.provider.generateQuestionContextSummary(r),t.timeoutMs??DS);return OS(o)}catch(o){let i=o instanceof Error?o.message:String(o);i!=="question-context-summary timed out"&&`${i}`;return}}function OS(t){let e=NS(t),n=typeof e=="string"?e:e&&typeof e=="object"&&typeof e.summary=="string"?e.summary:void 0,r=li(n??"").replace(/^[-*•]\s+/,"").trim();if(!(!r||r.length>Mc)&&!(r.split(/[.!?]+/).filter(o=>o.trim()).length>1))return r}function NS(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return e}}function WS(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 LS(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 ${Mc} characters.`,"Do not answer the question. Do not invent choices. Do not alter option labels or semantics.","","Evidence:",JSON.stringify(t,null,2)].join(`
268
- `)}function BS(t,e){return t?e.split(/\r?\n/).filter(n=>li(n)!==t).join(`
269
- `):e}function li(t){return t.replace(/\s+/g," ").trim()}function FS(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function qS(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 VS=280;function jS(t,e){if(t.latestPlanArtifactVersion===e&&t.latestPlanArtifact)return t.latestPlanArtifact;let n=t.planFilePath?.trim();if(!(!n||!US(n)))try{let r=KS(n,"utf-8").trim();return r?{markdown:r,steps:[]}:void 0}catch{return}}function GS(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(`
270
- `)}function HS(t){return t.options.map(e=>({label:e.label,description:e.description?.trim()??""})).filter(e=>e.description&&e.description.length<=VS)}function Dc(t){let e=t?.activeQuestionIndex??0;return t?.questions?.[e]?.id??(t?.activeQuestionIndex!=null?`q${t.activeQuestionIndex}`:void 0)}function zS(t,e,n){let r=t.pendingInputState;return!!(r&&r.requestId===e&&Dc(r)===n)}function QS(t){return[t.startedAt??"unknown-started-at",t.result?.session_id??"unknown-backend-session",t.result?.num_turns??0].join(":")}function Ec(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 ui=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:Gn({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>Yn(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:di({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:!!Ue(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=le(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(a&&!l&&(u=ce(a,e.worktreePath)),a&&d&&!l&&u&&Pe(a,d),u){for(let f of fe(e))this.deps.updatePersistedSession(f,{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=le(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:a&&!d&&ce(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,ue(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=Jn(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(`
267
+ `)}import{existsSync as KS,readFileSync as VS}from"fs";ft();var DS=4e3,Mc=180,OS=300;function _c(){let t=tt(),e=LS(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=BS(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 $c(t){let e=li(t.question??""),n=li(FS(e,t.context??""));if(!t.provider||!e||!n)return;let r={sessionName:t.sessionName,question:e,context:qS(n,DS)};try{let o=await US(t.provider.generateQuestionContextSummary(r),t.timeoutMs??OS);return NS(o)}catch(o){let i=o instanceof Error?o.message:String(o);i!=="question-context-summary timed out"&&`${i}`;return}}function NS(t){let e=WS(t),n=typeof e=="string"?e:e&&typeof e=="object"&&typeof e.summary=="string"?e.summary:void 0,r=li(n??"").replace(/^[-*•]\s+/,"").trim();if(!(!r||r.length>Mc)&&!(r.split(/[.!?]+/).filter(o=>o.trim()).length>1))return r}function WS(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return e}}function LS(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 BS(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 ${Mc} characters.`,"Do not answer the question. Do not invent choices. Do not alter option labels or semantics.","","Evidence:",JSON.stringify(t,null,2)].join(`
268
+ `)}function FS(t,e){return t?e.split(/\r?\n/).filter(n=>li(n)!==t).join(`
269
+ `):e}function li(t){return t.replace(/\s+/g," ").trim()}function qS(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function US(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 jS=280;function GS(t,e){if(t.latestPlanArtifactVersion===e&&t.latestPlanArtifact)return t.latestPlanArtifact;let n=t.planFilePath?.trim();if(!(!n||!KS(n)))try{let r=VS(n,"utf-8").trim();return r?{markdown:r,steps:[]}:void 0}catch{return}}function HS(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(`
270
+ `)}function zS(t){return t.options.map(e=>({label:e.label,description:e.description?.trim()??""})).filter(e=>e.description&&e.description.length<=jS)}function Dc(t){let e=t?.activeQuestionIndex??0;return t?.questions?.[e]?.id??(t?.activeQuestionIndex!=null?`q${t.activeQuestionIndex}`:void 0)}function QS(t,e,n){let r=t.pendingInputState;return!!(r&&r.requestId===e&&Dc(r)===n)}function JS(t){return[t.startedAt??"unknown-started-at",t.result?.session_id??"unknown-backend-session",t.result?.num_turns??0].join(":")}function Ec(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 ui=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:Gn({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>Yn(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:di({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:!!Ue(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=le(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(a&&!l&&(u=ce(a,e.worktreePath)),a&&d&&!l&&u&&Pe(a,d),u){for(let f of fe(e))this.deps.updatePersistedSession(f,{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=le(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:a&&!d&&ce(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,ue(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=Jn(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(`
271
271
  `),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(`
272
272
  `)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${d??"unknown"}:user-prompt`,userMessage:[`📋 [${e.name}] Plan v${d??"?"} still awaiting approval after idle timeout | ${i} | ${We(s)}`,"","The agent already produced a plan and is waiting for your decision.","Approve resumes the session and starts implementation.","Revise resumes it in plan mode so it can update the plan first.","Reject keeps the session stopped."].join(`
273
- `),notifyUser:"always",buttons:a==="ask"&&!l?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:d}):void 0}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"suspended",idempotencyKey:`suspended:${e.id}:${e.killReason??"idle-timeout"}:${e.completedAt??"unknown"}`,userMessage:`💤 [${e.name}] Suspended after idle timeout | ${i} | ${We(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${js(e.killReason)} | ${i} | ${We(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=Dc(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"&&Jn(e,l),f=e.pendingInputState?.promptText?.trim()||void 0,p=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),k=!e.pendingPlanApproval&&f?f:!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}))??[],c=!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:[],y=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=jS(e,l),b=r?HS(r):[],x=r?GS({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:b}):f,T=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await $c({sessionName:e.name,question:x??k,context:p,provider:this.deps.questionContextSummaryProvider}):void 0,A=oa({session:e,preview:k,questionText:e.pendingPlanApproval?void 0:x,questionContextPreview:p,questionContextSummary:T,planArtifact:S,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:d,planApprovalButtons:y,questionButtons:e.pendingPlanApproval?void 0:y}),h=A.planReviewSummary??k;if(A.label==="plan-approval"&&d==="ask"&&u){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"never",buttons:A.buttons,wakeMessage:A.wakeMessage});return}if(A.label==="plan-approval"&&d==="ask"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"always",buttons:A.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:()=>Yn(e,l),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,l,h),wakeMessageOnNotifySuccess:dn(e,l)});return}if(A.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:wake-only`,userMessage:A.userMessage,wakeMessage:A.wakeMessage,notifyUser:"never",buttons:A.buttons});return}this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`waiting:${e.id}:${s??`${A.label}:${A.userMessage}`}`,userMessage:A.userMessage,notifyUser:"always",buttons:A.buttons,shouldDispatch:o?()=>zS(e,o,i):void 0,wakeMessageOnNotifyFailed:A.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=Js({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${QS(e)}`,userMessage:n.userMessage,wakeMessage:n.wakeMessage,notifyUser:"always",onUserNotifyFailed:()=>{`${e.id}`,this.deps.shouldEmitTerminalWake(e)&&this.emitCompleted(e)}})}emitCompleted(e){let n=this.deps.getOutputPreview(e),r=this.shouldRequestCompletionFollowup(e),o=Hs({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i=Ec(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=Qs({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}:${Ec(e)}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};ne();Re();import{existsSync as JS}from"fs";var ci=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=le(o);!l&&i&&JS(i)&&ce(s,i,{destructive:!0}),a&&Pe(s,a);for(let f of fe(r??n))this.deps.updatePersistedSession(f,{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 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:G(r)??O(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${G(r)??O(r)??r.harnessSessionId}:${i}`,userMessage:a,notifyUser:"always"}),a}};var Oc=new Set(["starting","running"]);function Nc(t,e){JSON.stringify({component:"SessionRuntimeRegistry",event:t,at:new Date().toISOString(),...e})}function Wc(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 pi=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>Oc.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>Oc.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"){Nc("runtime.add",{reason:n,...Wc(e),activeCountBefore:this.activeSessionCount()}),this.sessions.set(e.id,e)}remove(e,n="unknown"){let r=this.sessions.get(e);Nc("runtime.remove",{reason:n,sessionId:e,existed:!!r,...r?Wc(r):{},activeCountBefore:this.activeSessionCount()}),this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var mi=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:ir({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 fi=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,worktreeBranch:s,preview:a,originThreadLine:d,preservedSummary:l,remoteOutcome:u}=e,f=l?"preserved":o?"cleaned":"cleanup-failed",p=[s?.trim()||"unknown-branch",i.trim()||"unknown-worktree",n.startedAt].join(":"),k=l??(o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`),m=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",y=u==="pr-updated"?`PR updated; no local worktree changes remained to merge — ${k}`:u==="pr-opened"?`PR opened; no local worktree changes remained to merge — ${k}`: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}:${f}:${p}`,userMessage:l?`ℹ️ [${n.name}] ${c} — ${l}${m}`:o?r?`ℹ️ [${n.name}] ${c} — native backend worktree released for backend cleanup${m}`:`ℹ️ [${n.name}] ${c} — worktree cleaned up${m}`:`⚠️ [${n.name}] ${S}, but worktree cleanup failed. Worktree still exists at ${i}${m}`,wakeMessage:Xs({sessionName:n.name,sessionId:n.id,headline:b,cleanupSummary:y??k,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`:"",f=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}\``,"",f,`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(`
273
+ `),notifyUser:"always",buttons:a==="ask"&&!l?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:d}):void 0}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"suspended",idempotencyKey:`suspended:${e.id}:${e.killReason??"idle-timeout"}:${e.completedAt??"unknown"}`,userMessage:`💤 [${e.name}] Suspended after idle timeout | ${i} | ${We(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${Hs(e.killReason)} | ${i} | ${We(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=Dc(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"&&Jn(e,l),f=e.pendingInputState?.promptText?.trim()||void 0,p=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),k=!e.pendingPlanApproval&&f?f:!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}))??[],c=!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:[],y=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=GS(e,l),b=r?zS(r):[],x=r?HS({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:b}):f,T=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await $c({sessionName:e.name,question:x??k,context:p,provider:this.deps.questionContextSummaryProvider}):void 0,A=sa({session:e,preview:k,questionText:e.pendingPlanApproval?void 0:x,questionContextPreview:p,questionContextSummary:T,planArtifact:S,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:d,planApprovalButtons:y,questionButtons:e.pendingPlanApproval?void 0:y}),h=A.planReviewSummary??k;if(A.label==="plan-approval"&&d==="ask"&&u){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"never",buttons:A.buttons,wakeMessage:A.wakeMessage});return}if(A.label==="plan-approval"&&d==="ask"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"always",buttons:A.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:()=>Yn(e,l),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,l,h),wakeMessageOnNotifySuccess:dn(e,l)});return}if(A.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:wake-only`,userMessage:A.userMessage,wakeMessage:A.wakeMessage,notifyUser:"never",buttons:A.buttons});return}this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`waiting:${e.id}:${s??`${A.label}:${A.userMessage}`}`,userMessage:A.userMessage,notifyUser:"always",buttons:A.buttons,shouldDispatch:o?()=>QS(e,o,i):void 0,wakeMessageOnNotifyFailed:A.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=Zs({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${JS(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=Qs({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i=Ec(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=Ys({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}:${Ec(e)}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};ne();Re();import{existsSync as YS}from"fs";var ci=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=le(o);!l&&i&&YS(i)&&ce(s,i,{destructive:!0}),a&&Pe(s,a);for(let f of fe(r??n))this.deps.updatePersistedSession(f,{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 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:G(r)??O(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${G(r)??O(r)??r.harnessSessionId}:${i}`,userMessage:a,notifyUser:"always"}),a}};var Oc=new Set(["starting","running"]);function Nc(t,e){JSON.stringify({component:"SessionRuntimeRegistry",event:t,at:new Date().toISOString(),...e})}function Wc(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 pi=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>Oc.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>Oc.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"){Nc("runtime.add",{reason:n,...Wc(e),activeCountBefore:this.activeSessionCount()}),this.sessions.set(e.id,e)}remove(e,n="unknown"){let r=this.sessions.get(e);Nc("runtime.remove",{reason:n,sessionId:e,existed:!!r,...r?Wc(r):{},activeCountBefore:this.activeSessionCount()}),this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var mi=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:ir({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 fi=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,worktreeBranch:s,preview:a,originThreadLine:d,preservedSummary:l,remoteOutcome:u}=e,f=l?"preserved":o?"cleaned":"cleanup-failed",p=[s?.trim()||"unknown-branch",i.trim()||"unknown-worktree",n.startedAt].join(":"),k=l??(o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`),m=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",y=u==="pr-updated"?`PR updated; no local worktree changes remained to merge — ${k}`:u==="pr-opened"?`PR opened; no local worktree changes remained to merge — ${k}`: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}:${f}:${p}`,userMessage:l?`ℹ️ [${n.name}] ${c} — ${l}${m}`:o?r?`ℹ️ [${n.name}] ${c} — native backend worktree released for backend cleanup${m}`:`ℹ️ [${n.name}] ${c} — worktree cleaned up${m}`:`⚠️ [${n.name}] ${S}, but worktree cleanup failed. Worktree still exists at ${i}${m}`,wakeMessage:ta({sessionName:n.name,sessionId:n.id,headline:b,cleanupSummary:y??k,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`:"",f=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}\``,"",f,`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(`
274
274
  `),notifyUser:"always",buttons:s,wakeMessageOnNotifySuccess:["Worktree decision buttons delivered to the user.",`Session: ${n.name} | ID: ${n.id}`,f,"Wait for their button callback — do NOT act on this worktree yourself."].join(`
275
275
  `),wakeMessageOnNotifyFailed:[`🔀 Worktree decision required for session \`${n.name}\``,"",f,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`].join(`
276
- `)}}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,f=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:Ys({sessionName:n.name,sessionId:n.id,branchName:r,baseBranch:o,promptSnippet:f,commitLines:l,moreNote:u,originThreadLine:d,diffSummary:i,allowedActions:a,policyReason:s}),notifyUser:"never"}}};function Lc(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
277
- `):YS(t);return n?o:o.length>e?Bc(t)?Md(o,e):_d(o,e):o}function YS(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
278
- `).trim();return n?Bc(t)?ZS(n)??n:e.slice(-20).join(`
279
- `):""}function Bc(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 ZS(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(`
280
- `)?n:void 0}ye();Re();ae();import{unlinkSync as XS}from"fs";var gi=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()}};ne();Cn();Re();var Fc=10080*60*1e3,ev=300*1e3,qc="tmp-output:cleanup",tv=60*1e3;function nv(t){return t instanceof Error?t.message:String(t)}var hi=class{constructor(e){this.deps=e}deps;scheduler=new gi;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+Fc,()=>{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<Fc))try{if(!e.worktreePath&&!le(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let d=le(e)?!1:ce(a,e.worktreePath);if(!le(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}${nv(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(qc);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(qc,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(D.sessionGcAgeMinutes??1440)*6e4}runTmpOutputCleanup(e){this.lastTmpOutputCleanupAttemptAt=e,this.deps.store.cleanupTmpOutputFiles(e)}getTmpOutputCleanupScheduleAt(e,n){if(e>n||this.lastTmpOutputCleanupAttemptAt==null)return e;let r=this.lastTmpOutputCleanupAttemptAt+tv;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()+ev))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{XS(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 Uc=new Set(["completed","failed","killed"]),rv=new Set(["starting","running"]),ov=5e3;function iv(t,e){return Kc("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 sv(t){return Kc("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 yi=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 pi,o=r.sessions,i=new zo(n.store),s=new Qo,a=new Xo,d=new ei(i.actionTokenStore,he),l=new No(o,i),u=new Oo({store:i,sessions:o,resolveSession:h=>l.resolveActive(h)}),f=new oi(a,(h,w)=>u.applySessionPatch(h,w),{getPersistedSession:h=>i.getPersistedSession(h)}),p=new ii,k=new Do(h=>i.getPersistedSession(h)),m=new fi,c=new Uo({shouldRunWorktreeStrategy:h=>e.shouldRunWorktreeStrategy(h),isAlreadyMerged:h=>e.isAlreadyMerged(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),getWorktreeCompletionState:(h,w,L,K)=>e.getWorktreeCompletionState(h,w,L,K),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),getPersistedSession:h=>i.getPersistedSession(h),dispatchSessionNotification:(h,w)=>e.dispatchSessionNotification(h,w),getOutputPreview:(h,w)=>e.getOutputPreview(h,w),originThreadLine:h=>e.originThreadLine(h),getWorktreeDecisionButtons:h=>e.getWorktreeDecisionButtons(h),getPolicyAwareWorktreeDecisionButtons:(h,w,L)=>e.getWorktreeDecisionButtons(h,w,L),makeOpenPrButton:h=>e.makeActionButton(h,"worktree-create-pr","Open PR"),isPrAvailable:h=>e.resolveRepoPolicy(h).prAvailable,hasOpenPrForBranch:(h,w,L)=>{let K=be(h,w,L);return K.exists&&K.state==="open"},getPrStatusForBranch:(h,w,L)=>be(h,w,L),getPrStatusForUrl:(h,w,L)=>Qe(h,w,L),resolveRepoPolicy:h=>e.resolveRepoPolicy(h),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:m,enqueueMerge:(h,w,L)=>e.enqueueMerge(h,w,L),mergeBranch:zr,spawnConflictResolver:async({session:h,worktreePath:w,prompt:L})=>e.spawn({prompt:L,workdir:w,name:`${h.name}-conflict-resolver`,harness:h.harnessName||me(),model:h.model,reasoningEffort:h.reasoningEffort,fastMode:h.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:h.id,route:h.route,originChannel:h.originChannel,originThreadId:h.originThreadId,originAgentId:h.originAgentId,originSessionKey:h.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(h,w)=>{let{makeAgentPrTool:L}=await Promise.resolve().then(()=>(So(),Jl));return{success:(await L().execute("auto-pr",{session:h.id,base_branch:w}))?.meta?.success===!0}}}),y=new si(e.pendingAskUserQuestions,(h,w)=>e.dispatchSessionNotification(h,w),h=>{e.clearWaitingTimestampsForSession(h)},(h,w,L)=>d.getQuestionButtons(h,w,L)),S=new ai(h=>e.buildRoutingProxy(h),(h,w)=>f.dispatch(h,w),(h,w)=>e.updatePersistedSession(h,w),(h,w)=>e.getPolicyAwareWorktreeDecisionButtons(h,{},void 0,w)),b=new hi({store:i,sessions:o,reminders:S,removeRuntimeSession:(h,w)=>r.remove(h,w),persistSession:(h,w)=>e.persistSession(h,w),clearRuntimeSessionState:h=>{e.clearWaitingTimestampsForSession(h),e.lastTurnCompleteMarkers.delete(h),e.lastTerminalWakeMarkers.delete(h)},resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let x=new ui({persistSession:h=>e.persistSession(h),clearWaitingTimestamp:h=>{e.clearWaitingTimestampsForSession(h)},handleWorktreeStrategy:h=>e.handleWorktreeStrategy(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchSessionNotification:(h,w)=>e.dispatchSessionNotification(h,w),notifySession:(h,w,L,K)=>e.notifySession(h,w,L,K),clearRetryTimersForSession:h=>a.clearRetryTimersForSession(h),hasTurnCompleteWakeMarker:h=>e.lastTurnCompleteMarkers.has(h),shouldEmitTurnCompleteWake:h=>e.shouldEmitTurnCompleteWake(h),shouldEmitTerminalWake:h=>e.shouldEmitTerminalWake(h),resolvePlanApprovalMode:h=>e.resolvePlanApprovalMode(h),getPlanApprovalButtons:(h,w)=>d.getPlanApprovalButtons(h,w),getResumeButtons:(h,w)=>d.getResumeButtons(h,w),getQuestionButtons:(h,w,L)=>d.getQuestionButtons(h,w,L),extractLastOutputLine:h=>e.extractLastOutputLine(h),getOutputPreview:(h,w)=>e.getOutputPreview(h,w),originThreadLine:h=>e.originThreadLine(h),debounceWaitingEvent:(h,w)=>e.debounceWaitingEvent(h,w),isAlreadyMerged:h=>e.isAlreadyMerged(h),questionContextSummaryProvider:n.questionContextSummaryProvider??_c()}),T=new ci({getPersistedSession:h=>i.getPersistedSession(h),resolveActiveSession:h=>l.resolveActive(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchNotification:(h,w)=>f.dispatch(h,w),buildRoutingProxy:h=>e.buildRoutingProxy(h)}),A=new mi({hydrateSpawnedSession:(h,w,L)=>{k.hydrateSpawnedSession(h,w,L)},markRunning:h=>{i.markRunning(h),e.onPersistedSessionChanged(i.getPersistedSession(h.id))},handleTerminal:async h=>e.onSessionTerminal(h),handleTurnEnd:(h,w)=>x.handleTurnEnd(h,w),formatLaunchWorkdirLabel:h=>e.formatLaunchWorkdirLabel(h),notifySession:(h,w,L,K)=>e.notifySession(h,w,L,K)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:a,interactions:d,notifications:f,worktrees:p,questions:y,lifecycle:x,restore:k,stateSync:u,references:l,worktreeStrategy:c,worktreeDecisions:T,runtimeBootstrap:A,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 k=this.registry.get(e.sessionIdOverride);if(k?.status==="starting"||k?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${k.status}.`);k&&this.registry.remove(k.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||Td(e.prompt),i=this.uniqueName(o);i!==o&&`${o}${i}`;let s=this.checkRepoPolicyForLaunch(e.workdir,e.worktreeStrategy);if(!s.ok){let k=s;throw new Error(k.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,f=d==="claude-code"&&!e.canUseTool?async(k,m)=>{if(!u)throw new Error("canUseTool called before session ID was set");return l.handleAskUserQuestion(u,m)}:e.canUseTool,p=new Jr({...e,workdir:a.actualWorkdir,systemPrompt:a.effectiveSystemPrompt,canUseTool:f},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(Uc.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}Uc.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 or({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??D.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"&&he(),record:r};let o=$l(n);if(o){let i=Ps(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:bs({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:bs({provider:n.provider})}}checkRepoPolicyForLaunch(e,n){let r=n??D.defaultWorktreeStrategy??"off",o=this.resolveRepoPolicy(e);return r==="off"?{ok:!0,resolution:o}:o.source==="none"?{ok:!0,resolution:o}:o.source==="unknown"&&o.identity?{ok:!1,text:Rs(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(Ps(r,n,"stored"))}resetRepoPolicy(e){let n=$n(e);return n?this.store.resetRepoPolicy(n.key):!1}requestRepoPolicyForLaunch(e){let n=e.worktreeStrategy??D.defaultWorktreeStrategy??"off",r=this.resolveRepoPolicy(e.workdir);if(!r.identity)return`Error: ${e.workdir} is not a git repository.`;let o=Rs(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=iv(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(`
276
+ `)}}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,f=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:f,commitLines:l,moreNote:u,originThreadLine:d,diffSummary:i,allowedActions:a,policyReason:s}),notifyUser:"never"}}};function Lc(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
277
+ `):ZS(t);return n?o:o.length>e?Bc(t)?Md(o,e):_d(o,e):o}function ZS(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
278
+ `).trim();return n?Bc(t)?XS(n)??n:e.slice(-20).join(`
279
+ `):""}function Bc(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 XS(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(`
280
+ `)?n:void 0}ye();Re();ae();import{unlinkSync as ev}from"fs";var gi=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()}};ne();Cn();Re();var Fc=10080*60*1e3,tv=300*1e3,qc="tmp-output:cleanup",nv=60*1e3;function rv(t){return t instanceof Error?t.message:String(t)}var hi=class{constructor(e){this.deps=e}deps;scheduler=new gi;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+Fc,()=>{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<Fc))try{if(!e.worktreePath&&!le(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let d=le(e)?!1:ce(a,e.worktreePath);if(!le(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}${rv(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(qc);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(qc,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(D.sessionGcAgeMinutes??1440)*6e4}runTmpOutputCleanup(e){this.lastTmpOutputCleanupAttemptAt=e,this.deps.store.cleanupTmpOutputFiles(e)}getTmpOutputCleanupScheduleAt(e,n){if(e>n||this.lastTmpOutputCleanupAttemptAt==null)return e;let r=this.lastTmpOutputCleanupAttemptAt+nv;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()+tv))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{ev(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 Uc=new Set(["completed","failed","killed"]),ov=new Set(["starting","running"]),iv=5e3;function sv(t,e){return Kc("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 av(t){return Kc("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 yi=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 pi,o=r.sessions,i=new zo(n.store),s=new Qo,a=new Xo,d=new ei(i.actionTokenStore,he),l=new No(o,i),u=new Oo({store:i,sessions:o,resolveSession:h=>l.resolveActive(h)}),f=new oi(a,(h,w)=>u.applySessionPatch(h,w),{getPersistedSession:h=>i.getPersistedSession(h)}),p=new ii,k=new Do(h=>i.getPersistedSession(h)),m=new fi,c=new Uo({shouldRunWorktreeStrategy:h=>e.shouldRunWorktreeStrategy(h),isAlreadyMerged:h=>e.isAlreadyMerged(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),getWorktreeCompletionState:(h,w,L,K)=>e.getWorktreeCompletionState(h,w,L,K),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),getPersistedSession:h=>i.getPersistedSession(h),dispatchSessionNotification:(h,w)=>e.dispatchSessionNotification(h,w),getOutputPreview:(h,w)=>e.getOutputPreview(h,w),originThreadLine:h=>e.originThreadLine(h),getWorktreeDecisionButtons:h=>e.getWorktreeDecisionButtons(h),getPolicyAwareWorktreeDecisionButtons:(h,w,L)=>e.getWorktreeDecisionButtons(h,w,L),makeOpenPrButton:h=>e.makeActionButton(h,"worktree-create-pr","Open PR"),isPrAvailable:h=>e.resolveRepoPolicy(h).prAvailable,hasOpenPrForBranch:(h,w,L)=>{let K=be(h,w,L);return K.exists&&K.state==="open"},getPrStatusForBranch:(h,w,L)=>be(h,w,L),getPrStatusForUrl:(h,w,L)=>Qe(h,w,L),resolveRepoPolicy:h=>e.resolveRepoPolicy(h),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:m,enqueueMerge:(h,w,L)=>e.enqueueMerge(h,w,L),mergeBranch:zr,spawnConflictResolver:async({session:h,worktreePath:w,prompt:L})=>e.spawn({prompt:L,workdir:w,name:`${h.name}-conflict-resolver`,harness:h.harnessName||me(),model:h.model,reasoningEffort:h.reasoningEffort,fastMode:h.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:h.id,route:h.route,originChannel:h.originChannel,originThreadId:h.originThreadId,originAgentId:h.originAgentId,originSessionKey:h.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(h,w)=>{let{makeAgentPrTool:L}=await Promise.resolve().then(()=>(So(),Jl));return{success:(await L().execute("auto-pr",{session:h.id,base_branch:w}))?.meta?.success===!0}}}),y=new si(e.pendingAskUserQuestions,(h,w)=>e.dispatchSessionNotification(h,w),h=>{e.clearWaitingTimestampsForSession(h)},(h,w,L)=>d.getQuestionButtons(h,w,L)),S=new ai(h=>e.buildRoutingProxy(h),(h,w)=>f.dispatch(h,w),(h,w)=>e.updatePersistedSession(h,w),(h,w)=>e.getPolicyAwareWorktreeDecisionButtons(h,{},void 0,w)),b=new hi({store:i,sessions:o,reminders:S,removeRuntimeSession:(h,w)=>r.remove(h,w),persistSession:(h,w)=>e.persistSession(h,w),clearRuntimeSessionState:h=>{e.clearWaitingTimestampsForSession(h),e.lastTurnCompleteMarkers.delete(h),e.lastTerminalWakeMarkers.delete(h)},resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let x=new ui({persistSession:h=>e.persistSession(h),clearWaitingTimestamp:h=>{e.clearWaitingTimestampsForSession(h)},handleWorktreeStrategy:h=>e.handleWorktreeStrategy(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchSessionNotification:(h,w)=>e.dispatchSessionNotification(h,w),notifySession:(h,w,L,K)=>e.notifySession(h,w,L,K),clearRetryTimersForSession:h=>a.clearRetryTimersForSession(h),hasTurnCompleteWakeMarker:h=>e.lastTurnCompleteMarkers.has(h),shouldEmitTurnCompleteWake:h=>e.shouldEmitTurnCompleteWake(h),shouldEmitTerminalWake:h=>e.shouldEmitTerminalWake(h),resolvePlanApprovalMode:h=>e.resolvePlanApprovalMode(h),getPlanApprovalButtons:(h,w)=>d.getPlanApprovalButtons(h,w),getResumeButtons:(h,w)=>d.getResumeButtons(h,w),getQuestionButtons:(h,w,L)=>d.getQuestionButtons(h,w,L),extractLastOutputLine:h=>e.extractLastOutputLine(h),getOutputPreview:(h,w)=>e.getOutputPreview(h,w),originThreadLine:h=>e.originThreadLine(h),debounceWaitingEvent:(h,w)=>e.debounceWaitingEvent(h,w),isAlreadyMerged:h=>e.isAlreadyMerged(h),questionContextSummaryProvider:n.questionContextSummaryProvider??_c()}),T=new ci({getPersistedSession:h=>i.getPersistedSession(h),resolveActiveSession:h=>l.resolveActive(h),resolveWorktreeRepoDir:(h,w)=>e.resolveWorktreeRepoDir(h,w),updatePersistedSession:(h,w)=>e.updatePersistedSession(h,w),dispatchNotification:(h,w)=>f.dispatch(h,w),buildRoutingProxy:h=>e.buildRoutingProxy(h)}),A=new mi({hydrateSpawnedSession:(h,w,L)=>{k.hydrateSpawnedSession(h,w,L)},markRunning:h=>{i.markRunning(h),e.onPersistedSessionChanged(i.getPersistedSession(h.id))},handleTerminal:async h=>e.onSessionTerminal(h),handleTurnEnd:(h,w)=>x.handleTurnEnd(h,w),formatLaunchWorkdirLabel:h=>e.formatLaunchWorkdirLabel(h),notifySession:(h,w,L,K)=>e.notifySession(h,w,L,K)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:a,interactions:d,notifications:f,worktrees:p,questions:y,lifecycle:x,restore:k,stateSync:u,references:l,worktreeStrategy:c,worktreeDecisions:T,runtimeBootstrap:A,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 k=this.registry.get(e.sessionIdOverride);if(k?.status==="starting"||k?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${k.status}.`);k&&this.registry.remove(k.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||Td(e.prompt),i=this.uniqueName(o);i!==o&&`${o}${i}`;let s=this.checkRepoPolicyForLaunch(e.workdir,e.worktreeStrategy);if(!s.ok){let k=s;throw new Error(k.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,f=d==="claude-code"&&!e.canUseTool?async(k,m)=>{if(!u)throw new Error("canUseTool called before session ID was set");return l.handleAskUserQuestion(u,m)}:e.canUseTool,p=new Jr({...e,workdir:a.actualWorkdir,systemPrompt:a.effectiveSystemPrompt,canUseTool:f},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(Uc.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}Uc.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 or({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??D.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"&&he(),record:r};let o=$l(n);if(o){let i=Rs(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:As({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:As({provider:n.provider})}}checkRepoPolicyForLaunch(e,n){let r=n??D.defaultWorktreeStrategy??"off",o=this.resolveRepoPolicy(e);return r==="off"?{ok:!0,resolution:o}:o.source==="none"?{ok:!0,resolution:o}:o.source==="unknown"&&o.identity?{ok:!1,text:Is(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(Rs(r,n,"stored"))}resetRepoPolicy(e){let n=$n(e);return n?this.store.resetRepoPolicy(n.key):!1}requestRepoPolicyForLaunch(e){let n=e.worktreeStrategy??D.defaultWorktreeStrategy??"off",r=this.resolveRepoPolicy(e.workdir);if(!r.identity)return`Error: ${e.workdir} is not a git repository.`;let o=Is(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=sv(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(`
281
281
  `),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(`
282
- `),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??me(),o=e.permissionMode??D.permissionMode,i=e.planApproval??D.planApproval,s=this.spawn({prompt:e.prompt,workdir:e.workdir,sessionIdOverride:e.sessionIdOverride,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,allowedTools:e.allowedTools,resumeSessionId:e.resumeSessionId,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(f=>f.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 f=sv(u);a.has(f)||a.set(f,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 Yn(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:Gn({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:di({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,f=d?.prAvailable??!!(l&&l!=="never-pr"&&l!=="manual"),p=u?ws({policy:u,prAvailable:f}):{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=na(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(Jn(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}),f=[`📋 [${a.name}] Plan v${l??"?"} needs your decision:`,"","Why this was escalated:","",o,"","Choose Approve, Revise, or Reject below."].join(`
282
+ `),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??me(),o=e.permissionMode??D.permissionMode,i=e.planApproval??D.planApproval,s=this.spawn({prompt:e.prompt,workdir:e.workdir,sessionIdOverride:e.sessionIdOverride,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,allowedTools:e.allowedTools,resumeSessionId:e.resumeSessionId,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(f=>f.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 f=av(u);a.has(f)||a.set(f,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 Yn(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:Gn({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:di({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,f=d?.prAvailable??!!(l&&l!=="never-pr"&&l!=="manual"),p=u?bs({policy:u,prAvailable:f}):{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=oa(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(Jn(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}),f=[`📋 [${a.name}] Plan v${l??"?"} needs your decision:`,"","Why this was escalated:","",o,"","Choose Approve, Revise, or Reject below."].join(`
283
283
  `);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:f,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,f=o?.worktreeBranch??i?.worktreeBranch,p=this.resolveWorktreeRepoDir(o?.originalWorkdir??i?.workdir,u);if(!u)return`Error: Session "${e}" has no managed worktree path.`;if(!f)return`Error: Session "${e}" has no managed worktree branch.`;if(!p)return`Error: Session "${e}" has no resolvable repository root for worktree ${u}.`;let k=o?.worktreeBaseBranch??i?.worktreeBaseBranch??Le(p),m=He(p,f,k);if(!m)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 y=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:f,baseBranch:k,diffSummary:m,summaryLines:y,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)??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||!Eo(e,n))||!n?e:qr(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,io({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(`
284
284
  `),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=Dd(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,ir({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(`
285
- `),d=l=>zs({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:me(),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<ov?!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 Lc(e,n)}resolvePlanApprovalMode(e){return e.planApproval??D.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())rv.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)}canSubmitPendingInputOption(e){return this.sessions.get(e)?.canSubmitPendingInputOption?.()===!0}consumeQuestionAnswerTokens(e,n){return this.interactions.consumeQuestionAnswerTokens(e,n)}dispose(){this.disposeMaintenance(),this.questions.dispose(),this.notifications.dispose()}};V();ft();ae();ye();import{definePluginEntry as Vc}from"openclaw/plugin-sdk/plugin-entry";function cv(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??D.worktreeDir;if(s)i.add(s);else for(let d of t.listPersistedSessions())if(d.workdir)try{let l=uv("git",["rev-parse","--show-toplevel"],{cwd:d.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();l&&i.add(ga(l,".worktrees"))}catch{}if(i.size===0)return;let a=0;for(let d of i)try{let l=av(d);for(let u of l){if(!u.startsWith("openclaw-worktree-"))continue;let f=ga(d,u);try{let p=dv(f);if(!p.isDirectory()||p.mtimeMs>r||o.has(f))continue;lv(f,{recursive:!0,force:!0}),a++}catch(p){`${f}${p instanceof Error?p.message:String(p)}`}}}catch{}a>0&&`${a}${e}`}function pv(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 _e(e.accountId?`${n}|${e.accountId}|${r}`:`${n}|${r}`,e.threadId,e.sessionKey)}function mv(t){let e=null,n=null,r=null,o=!1,i=!1,s=t.registerTool;Et(t.runtime);let a=()=>ga(jo(process.env),"plugin-state","openclaw-code-agent"),d=c=>{let y=c.deliveryContext;return y?.channel&&y.to?_e(y.accountId?`${y.channel}|${y.accountId}|${y.to}`:`${y.channel}|${y.to}`,y.threadId,c.sessionKey):_e(c.messageChannel,void 0,c.sessionKey)},l=c=>{r?.maybeCheckForUpdate({route:c})},u=c=>{if(o){c&&!i&&(Et(t.runtime,c.config),i=!0);return}let y=t.pluginConfig??{};Da(y),c?(Et(t.runtime,c.config),i=!0):(Et(t.runtime),i=!1),e=new yi(D.maxSessions,D.maxPersistedSessions,{worktreeSummaryProvider:tc()}),n=new $o(e),r=new rr({stateDir:c?.stateDir??a(),currentVersion:t.version??ka.version??"0.0.0",actionButtonFactory:(S,b,x,T)=>e.makePluginActionButton(S,b,x,T)}),Wi(e),Li(n),Bi(r),n.start(),cv(e),e.bootstrapMaintenanceSchedules(),o=!0,l()},f=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=null,o=!1,i=!1,Et(void 0),Li(null),Wi(null),Bi(null)},p=(c,y)=>{s(S=>(u(),l(d(S)),c(S)),y)},k={...t,registerCommand(c){t.registerCommand({...c,handler:y=>(u(),l(d(y)),c.handler(y))})}},m=c=>{let y=uu(c);t.registerInteractiveHandler({...y,handler:async S=>(u(),l(pv(S)),y.handler(S))})};p(c=>Nd(c),{optional:!1,name:"agent_launch"}),p(c=>hl(c),{optional:!1,name:"agent_sessions"}),p(c=>yl(c),{optional:!1,name:"agent_kill"}),p(c=>to(c),{optional:!1,name:"agent_output"}),p(c=>bl(c),{optional:!1,name:"agent_respond"}),p(c=>Rl(c),{optional:!1,name:"agent_request_plan_approval"}),p(c=>Al(c),{optional:!1,name:"agent_request_worktree_decision"}),p(c=>Tl(c),{optional:!1,name:"agent_send_plan_offer"}),p(c=>Cl(c),{optional:!1,name:"agent_stats"}),p(c=>Dl(c),{optional:!1,name:"agent_repo_policy"}),p(c=>po(c),{optional:!1,name:"agent_merge"}),p(c=>Un(c),{optional:!1,name:"agent_pr"}),p(c=>Yl(c),{optional:!1,name:"agent_worktree_cleanup"}),p(c=>Zl(c),{optional:!1,name:"agent_worktree_status"}),p(c=>Xl(c),{optional:!1,name:"agent_goal_launch"}),p(c=>tu(c),{optional:!1,name:"agent_goal_status"}),p(c=>nu(c),{optional:!1,name:"agent_goal_stop"}),p(c=>ru(c),{optional:!1,name:"agent_goal_edit"}),m("telegram"),m("discord"),pu(k),mu(k),fu(k),gu(k),hu(k),yu(k),ku(k),vu(k),wu(k),Pu(k),Ru(k),t.registerService({id:"openclaw-code-agent",start:u,stop:f})}var CM=Vc({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:mv});export{CM as default,mv as register,pv as routeFromInteractiveContext};
285
+ `),d=l=>Js({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:me(),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<iv?!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 Lc(e,n)}resolvePlanApprovalMode(e){return e.planApproval??D.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())ov.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)}canSubmitPendingInputOption(e){return this.sessions.get(e)?.canSubmitPendingInputOption?.()===!0}consumeQuestionAnswerTokens(e,n){return this.interactions.consumeQuestionAnswerTokens(e,n)}dispose(){this.disposeMaintenance(),this.questions.dispose(),this.notifications.dispose()}};V();ft();ae();ye();import{definePluginEntry as Vc}from"openclaw/plugin-sdk/plugin-entry";function pv(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??D.worktreeDir;if(s)i.add(s);else for(let d of t.listPersistedSessions())if(d.workdir)try{let l=cv("git",["rev-parse","--show-toplevel"],{cwd:d.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();l&&i.add(ya(l,".worktrees"))}catch{}if(i.size===0)return;let a=0;for(let d of i)try{let l=dv(d);for(let u of l){if(!u.startsWith("openclaw-worktree-"))continue;let f=ya(d,u);try{let p=lv(f);if(!p.isDirectory()||p.mtimeMs>r||o.has(f))continue;uv(f,{recursive:!0,force:!0}),a++}catch(p){`${f}${p instanceof Error?p.message:String(p)}`}}}catch{}a>0&&`${a}${e}`}function mv(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 _e(e.accountId?`${n}|${e.accountId}|${r}`:`${n}|${r}`,e.threadId,e.sessionKey)}function fv(t){let e=null,n=null,r=null,o=!1,i=!1,s=t.registerTool;Et(t.runtime);let a=()=>ya(jo(process.env),"plugin-state","openclaw-code-agent"),d=c=>{let y=c.deliveryContext;return y?.channel&&y.to?_e(y.accountId?`${y.channel}|${y.accountId}|${y.to}`:`${y.channel}|${y.to}`,y.threadId,c.sessionKey):_e(c.messageChannel,void 0,c.sessionKey)},l=c=>{r?.maybeCheckForUpdate({route:c})},u=c=>{if(o){c&&!i&&(Et(t.runtime,c.config),i=!0);return}let y=t.pluginConfig??{};Na(y),c?(Et(t.runtime,c.config),i=!0):(Et(t.runtime),i=!1),e=new yi(D.maxSessions,D.maxPersistedSessions,{worktreeSummaryProvider:tc()}),n=new $o(e),r=new rr({stateDir:c?.stateDir??a(),currentVersion:t.version??va.version??"0.0.0",actionButtonFactory:(S,b,x,T)=>e.makePluginActionButton(S,b,x,T)}),Bi(e),Fi(n),qi(r),n.start(),pv(e),e.bootstrapMaintenanceSchedules(),o=!0,l()},f=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=null,o=!1,i=!1,Et(void 0),Fi(null),Bi(null),qi(null)},p=(c,y)=>{s(S=>(u(),l(d(S)),c(S)),y)},k={...t,registerCommand(c){t.registerCommand({...c,handler:y=>(u(),l(d(y)),c.handler(y))})}},m=c=>{let y=uu(c);t.registerInteractiveHandler({...y,handler:async S=>(u(),l(mv(S)),y.handler(S))})};p(c=>Nd(c),{optional:!1,name:"agent_launch"}),p(c=>hl(c),{optional:!1,name:"agent_sessions"}),p(c=>yl(c),{optional:!1,name:"agent_kill"}),p(c=>to(c),{optional:!1,name:"agent_output"}),p(c=>bl(c),{optional:!1,name:"agent_respond"}),p(c=>Rl(c),{optional:!1,name:"agent_request_plan_approval"}),p(c=>Al(c),{optional:!1,name:"agent_request_worktree_decision"}),p(c=>Tl(c),{optional:!1,name:"agent_send_plan_offer"}),p(c=>Cl(c),{optional:!1,name:"agent_stats"}),p(c=>Dl(c),{optional:!1,name:"agent_repo_policy"}),p(c=>po(c),{optional:!1,name:"agent_merge"}),p(c=>Un(c),{optional:!1,name:"agent_pr"}),p(c=>Yl(c),{optional:!1,name:"agent_worktree_cleanup"}),p(c=>Zl(c),{optional:!1,name:"agent_worktree_status"}),p(c=>Xl(c),{optional:!1,name:"agent_goal_launch"}),p(c=>tu(c),{optional:!1,name:"agent_goal_status"}),p(c=>nu(c),{optional:!1,name:"agent_goal_stop"}),p(c=>ru(c),{optional:!1,name:"agent_goal_edit"}),m("telegram"),m("discord"),pu(k),mu(k),fu(k),gu(k),hu(k),yu(k),ku(k),vu(k),wu(k),Pu(k),Ru(k),t.registerService({id:"openclaw-code-agent",start:u,stop:f})}var MM=Vc({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:fv});export{MM as default,fv as register,mv as routeFromInteractiveContext};