openclaw-code-agent 4.5.0 → 4.5.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,37 +1,37 @@
1
- var vu=Object.defineProperty;var Q=(t,e)=>()=>(t&&(e=t(t=0)),e);var Pu=(t,e)=>{for(var n in e)vu(t,n,{get:e[n],enumerable:!0})};function Ut(t,e){return e?{...e,...t}:t}function wu(t){return{...t,[Wo]:!0}}function bu(t){return{const:t,type:typeof t}}var Wo,g,te=Q(()=>{Wo=Symbol("optionalSchema");g={Object(t,e){let n=Object.entries(t).filter(([,o])=>!o[Wo]).map(([o])=>o),r=Object.fromEntries(Object.entries(t).map(([o,i])=>{let{[Wo]:s,...l}=i;return[o,l]}));return{...e,type:"object",...n.length>0?{required:n}:{},properties:r}},String(t){return Ut({type:"string"},t)},Number(t){return Ut({type:"number"},t)},Boolean(t){return Ut({type:"boolean"},t)},Array(t,e){return Ut({type:"array",items:t},e)},Literal:bu,Union(t,e){return Ut({anyOf:t},e)},Optional:wu}});function No(t){S=t}function Lo(t){j=t}var S,j,L=Q(()=>{S=null,j=null});function Ps(t){let e=t.chatId.trim(),n=t.topicId.trim();return!/^-?\d+$/.test(e)||!/^\d+$/.test(n)?null:`${e}:topic:${n}`}function Tu(t){let e=t.conversationId.trim(),n=e.match(/^(-?\d+):topic:(\d+)$/i);if(n?.[1]&&n[2]){let i=Ps({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=Ps({chatId:r,topicId:e});return o?{chatId:r,topicId:e,canonicalConversationId:o}:null}function Cu(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 Mu(t,e){if(!/^\d+$/.test(t))return t;let n=Cu(e);return n?`${n}:${t}`:`channel:${t}`}function _u(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 $u(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 Eu(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||!xu.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 Du(t,e=Tu){try{return e({conversationId:t})}catch{return null}}function Bo(t){return{provider:"system",target:"system",sessionKey:t?.trim()||void 0}}function Fo(t,e){return{...t,threadId:e??t.threadId}}function Wu(t,e,n){return t==="telegram"&&n?.provider==="telegram"&&!!n.target&&e!==n.target}function Nu(t){let e=t?.trim();if(!e)return;let n=Eu(e);if(!n)return;let{provider:r,kind:o,rawId:i}=n,s=$u(i),l=null;if(r==="telegram")try{l=Ou.safeParseTelegramTopicConversation(i)}catch{l=null}let a=l?.chatId??s.id,d=l?.topicId??s.threadId,u=r==="discord"?o==="direct"||o==="dm"?`user:${a}`:`channel:${a}`:a;return{provider:r,target:u,threadId:d,sessionKey:e}}function qo(t){let e=t?.match(/:topic:(\d+)$/i);return e?parseInt(e[1],10):void 0}function ws(t){return!!(t?.provider&&t.target&&t.provider!=="system"&&t.target!=="system")}function Vt(t,e,n){let r=Nu(n),o=e!=null?String(e):void 0,i=t?.trim();if(!i||i.toLowerCase()==="unknown")return r?Fo(r,o):Bo(n);let s=i.split("|").map(f=>f.trim());if(s.length<2)return r?Fo(r,o):Bo(n);let[l,a,d]=s,u=s.length>=3?d:a,c=s.length>=3?a:void 0,m=l?.toLowerCase();if(!m||!u)return r?Fo(r,o):Bo(n);let p=m==="discord"?Mu(u,n):u;return Wu(m,p,r)?{provider:m,accountId:c,target:r.target,threadId:o??r.threadId,sessionKey:n?.trim()||void 0}:{provider:m,accountId:c,target:p,threadId:o??(r?.provider===m?r.threadId:void 0),sessionKey:n?.trim()||void 0}}function He(t){return Vt(_u(t.route)??t.originChannel,t.route?.threadId??t.originThreadId,t.route?.sessionKey??t.originSessionKey)??t.route}function Me(t){let e=He(t);return ws(e)?e:void 0}function Lu(t){return Object.fromEntries(Object.entries(t).filter(e=>!!e[1]))}function Gt(t){let e=He(t);if(!ws(e))return"";let n=Lu({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 xu,Ou,be=Q(()=>{xu=new Set(["telegram","discord","slack","system","mattermost","feishu","line","whatsapp","signal","matrix","googlechat","bluebubbles","imessage","msteams"]);Ou={safeParseTelegramTopicConversation:Du}});import{readFileSync as Bu}from"fs";import{homedir as Fu}from"os";import{join as qu}from"path";function Rs(){if(jt!==void 0)return jt;try{let t=Bu(qu(Fu(),".claude.json"),"utf-8");jt=JSON.parse(t).mcpServers??{}}catch{jt={}}return jt}function As(t){let e=t.defaultHarness??bs,n={};for(let[r,o]of Object.entries(Ht)){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 ae(){return D.defaultHarness??bs}function Vo(t){let e=Ht[t],n=D.harnesses[t];return{...e,...n,allowedModels:n?.allowedModels??e?.allowedModels}}function at(t){return Vo(t).defaultModel}function Tn(t){return D.harnesses[t]?.allowedModels??D.allowedModels}function Le(t){return Vo(t).reasoningEffort}function lt(t){return t==="codex"?Vo(t).fastMode:void 0}function ke(t){return t==null?void 0:String(t).trim()||void 0}function Go(t){return{channel:ke(t?.deliveryContext?.channel),to:ke(t?.deliveryContext?.to),accountId:ke(t?.deliveryContext?.accountId),threadId:ke(t?.deliveryContext?.threadId)}}function Is(t,e,n){if(!(!t||!e))return n?`${t}|${n}|${e}`:`${t}|${e}`}function Ko(t){return ke(t?.requesterSenderId??t?.senderId)}function Uo(t){return(ke(t.deliveryContext?.channel)??t.messageChannel??t.channel)?.toLowerCase()!=="telegram"?!1:!!(qo(t.sessionKey)||ke(t.messageThreadId)||ke(t.deliveryContext?.threadId))}function Cn(t){let e=Go(t),n=Is(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=ke(t.chatId);if(r.length===1&&o)return`${r[0]}|${o}`;let i=Ko(t);if(r.length===1&&i&&!Uo(t))return`${r[0]}|${i}`}if(t.workspaceDir){let r=ze(t.workspaceDir);if(r)return r}if(t.messageChannel&&t.messageChannel.includes("|"))return t.messageChannel}function zt(t,e){if(e&&String(e).includes("|"))return String(e);let n=Go(t),r=Is(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 l=String(t.messageChannel);if(l.includes("|"))return l;let a=ke(t.chatId);if(a)return`${l}|${a}`;let d=Ko(t);if(d&&!Uo(t))return`${l}|${d}`}let o=ke(t?.channel),i=ke(t?.chatId);if(o&&i)return`${o}|${i}`;let s=Ko(t);return o&&s&&!Uo(t)?`${o}|${s}`:t?.id&&/^-?\d+$/.test(String(t.id))?`telegram|${t.id}`:D.fallbackChannel??"unknown"}function jo(t){return Go(t).threadId??t?.messageThreadId??void 0}function dt(t,e,n){return Vt(zt(t,e),jo(t),n??t?.sessionKey)}function ze(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 xs(t){return qo(t)}var jt,bs,Ht,D,ie=Q(()=>{be();bs="claude-code",Ht={"claude-code":{defaultModel:"anthropic/claude-sonnet-4-7",allowedModels:["sonnet","opus"]},codex:{defaultModel:"gpt-5.5",allowedModels:["gpt-5.5","gpt-5.5-pro"],reasoningEffort:"medium"},opencode:{}};D={maxSessions:20,idleTimeoutMinutes:15,sessionGcAgeMinutes:1440,maxPersistedSessions:1e4,maxAutoResponds:10,permissionMode:"plan",planApproval:"delegate",defaultWorktreeStrategy:"delegate",harnesses:{"claude-code":{...Ht["claude-code"]},codex:{...Ht.codex},opencode:{...Ht.opencode}}}});function q(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function G(t,e,n){for(let r of e){let o=t?.[r];if(typeof o!="string")continue;let i=n?.trim===!1?o:o.trim();if(i)return i}}function Ts(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 Cs(t){if(typeof t=="string"){let s=t.trim();return s?{label:s,value:s,recommended:Ts(s)}:void 0}let e=q(t);if(!e)return;let n=G(e,["label","title","text","value","name","id"])?.trim();if(!n)return;let r=G(e,["description","preview","detail","details"]),o=G(e,["value","id","name"]),i=e.isOther===!0||e.is_other===!0||e.other===!0;return{label:n,...r?{description:r}:{},...o?{value:o}:{},...i?{isOther:!0}:{},recommended:Ts(n,e)}}function Mn(t){let e=q(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(Cs).filter(r=>!!r):[]}function ct(t){let e=q(t);return(Array.isArray(e?.questions)?e.questions:[]).map((r,o)=>Ku(r,o)).filter(r=>!!r)}function Ku(t,e=0){let n=q(t);if(!n)return;let r=G(n,["question","prompt","message","text","summary"])?.trim();if(!r)return;let o=G(n,["id","questionId","question_id","name"]),i=G(n,["header","title","label"]),l=(Array.isArray(n.options)?n.options:Array.isArray(n.choices)?n.choices:[]).map(Cs).filter(u=>!!u),a=n.multiSelect===!0||n.multi_select===!0,d=n.isOther===!0||n.is_other===!0||n.allowFreeText===!0||n.allowsFreeText===!0||a||l.some(u=>u.isOther);return{id:o??`question_${e+1}`,...i?{header:i}:{},question:r,options:l,...a?{multiSelect:!0}:{},...d?{allowsFreeText:!0}:{},...n.isSecret===!0||n.is_secret===!0?{isSecret:!0}:{}}}function Ms(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 l=i.recommended&&!/\brecommended\b/i.test(i.label)?" (recommended)":"",a=i.description?` - ${i.description}`:"",d=i.isOther?" (free text)":"";return` ${s+1}. ${i.label}${l}${d}${a}`})),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 _n(t){if(t.length===0)return;let e=t.flatMap((n,r)=>[...r>0?[""]:[],...Ms(n,r,t.length)]);return t.length>1&&e.push("","Reply with answers by question, for example: Q1: ..., Q2: ..."),e.join(`
3
- `)}function _e(t,e,n){return Ms(t,e,n).join(`
4
- `)}var Qt=Q(()=>{});function pt(t){return{type:"backend_ref",ref:t}}function mt(t){return{type:"run_started",...t?{runId:t}:{}}}function Qe(t){return{type:"text_delta",text:t}}function $n(t,e){return{type:"tool_call",name:t,input:e}}function xe(t){return{type:"pending_input",state:t}}function Fe(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function En(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function ft(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function $e(t){return{type:"run_completed",data:t}}var Be,Dn=Q(()=>{Be=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 Wn from"@anthropic-ai/claude-agent-sdk";function Uu(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 Vu(t,e,n){let r=ct(n),o=r.length>0?0:void 0,i=o!=null?r[o]:void 0,s=i?.options.map(a=>a.label)??[],l=i?_e(i,o,r.length):_n(r);return{requestId:`${t||"claude"}-ask-${e}`,kind:"question",promptText:l,options:s,...r.length>0?{questions:r}:{},...o!=null?{activeQuestionIndex:o}:{},allowsFreeText:i?.allowsFreeText===!0||s.length===0}}var On,_s=Q(()=>{Qt();Dn();On=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 Be,r=!1,o="",i=!1,s=0,l=e.resumeSessionId??"",a=e.canUseTool,d={cwd:e.cwd,model:e.model,...e.reasoningEffort?{effort:e.reasoningEffort}:{},permissionMode:e.permissionMode,allowDangerouslySkipPermissions:!0,allowedTools:e.allowedTools,systemPrompt:e.systemPrompt,includePartialMessages:!0,abortController:e.abortController,mcpServers:e.mcpServers,...a?{canUseTool:async(f,h)=>{if(f!=="AskUserQuestion")return{behavior:"allow"};let k=Vu(l,++s,h);n.enqueue(xe(k));try{let v=await a(f,h);return n.enqueue(Fe(k.requestId)),v}catch(v){throw n.enqueue(Fe(k.requestId)),v}}}:{}};e.resumeSessionId&&(d.resume=e.resumeSessionId,d.forkSession=e.forkSession??!1);let u=e.prompt,c=this.deps.query??Wn.query,m=this.deps.startup??Wn.startup,p=(async()=>{if(typeof m!="function")return c({prompt:u,options:d});let f=await m({options:d});try{return f.query(u)}catch(h){throw await f.close?.(),h}})();return(async()=>{try{let f=await p;for await(let h of f){let k=h;if(k.type==="system"&&k.subtype==="init"){l=k.session_id??l,n.enqueue(pt({kind:"claude-code",conversationId:l}));continue}if(k.type==="system"&&k.subtype==="status"&&k.permissionMode){n.enqueue(ft(k.permissionMode));continue}if(k.type==="assistant"){r||(r=!0,n.enqueue(mt()));for(let v of k.message?.content??[]){if(v.type==="text"){o+=o?`
6
- ${v.text}`:v.text,n.enqueue(Qe(v.text));continue}v.type==="tool_use"&&((v.name==="ExitPlanMode"||v.name==="set_permission_mode")&&(i=!0),v.name!=="AskUserQuestion"&&n.enqueue($n(v.name,v.input)))}continue}if(k.type==="result"){let v=o.trim();if(v&&(e.permissionMode==="plan"||i)){let I={explanation:void 0,steps:[],markdown:v};n.enqueue(En(I,!0))}n.enqueue($e({success:k.subtype==="success",duration_ms:k.duration_ms??0,total_cost_usd:k.total_cost_usd??0,num_turns:k.num_turns??0,result:Uu(k),session_id:k.session_id??l})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(f=>{n.enqueue($e({success:!1,duration_ms:0,total_cost_usd:0,num_turns:0,result:f instanceof Error?f.message:String(f),session_id:l})),n.close()}),{messages:n.messages(),async setPermissionMode(f){let h=await p;typeof h.setPermissionMode=="function"&&await h.setPermissionMode(f)},async streamInput(f){let h=await p;typeof h.streamInput=="function"&&await h.streamInput(f)},async interrupt(){let f=await p;typeof f.interrupt=="function"&&await f.interrupt()}}}buildUserMessage(e,n){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:n}}}});import{spawn as Gu}from"node:child_process";import ju from"node:readline";function Hu(t){return t instanceof Error?t.message:String(t)}function zu(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function Qu(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:Hu(r)}})}}}var Nn,$s=Q(()=>{Nn=class{constructor(e,n,r){this.command=e;this.args=n;this.requestTimeoutMs=r}command;args;requestTimeoutMs;process=null;pending=new Map;counter=0;onNotification=()=>{};onRequest=async()=>({});setNotificationHandler(e){this.onNotification=e}setRequestHandler(e){this.onRequest=e}async connect(){if(this.process)return;let e=Gu(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(!e.stdin||!e.stdout||!e.stderr)throw new Error("codex app server stdio pipes unavailable");this.process=e,ju.createInterface({input:e.stdout}).on("line",r=>{this.handleLine(r)}),e.stderr.on("data",()=>{}),e.on("close",()=>{this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){this.flushPending(new Error("codex app server stdio closed"));let e=this.process;this.process=null,e&&e.kill()}async notify(e,n){this.write({jsonrpc:"2.0",method:e,params:n??{}})}async request(e,n,r){let o=`rpc-${++this.counter}`,i=new Promise((s,l)=>{let a=setTimeout(()=>{this.pending.delete(o),l(new Error(`codex app server timeout: ${e}`))},Math.max(100,r??this.requestTimeoutMs));a.unref?.(),this.pending.set(o,{resolve:s,reject:l,timer:a})});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=zu(e);n&&await Qu(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){for(let[n,r]of this.pending)clearTimeout(r.timer),r.reject(e),this.pending.delete(n)}}});function Ju(t){return t instanceof Error?t.message:String(t)}function Es(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function qe(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>qe(n)).join("");let e=q(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=qe(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=qe(e[n]);if(r)return r}return""}function Jt(t){let e=q(t);if(!e)return{};let n=q(e.thread)??q(e.session),r=q(e.turn)??q(e.run),o=q(e.item),i=q(e.serverRequest);return{threadId:G(e,["threadId","thread_id","conversationId","conversation_id"])??G(n,["id","threadId","thread_id","conversationId"]),runId:G(e,["turnId","turn_id","runId","run_id"])??G(r,["id","turnId","turn_id","runId","run_id"]),requestId:G(e,["requestId","request_id","serverRequestId"])??G(i,["id","requestId","request_id"]),itemId:G(e,["itemId","item_id"])??G(o,["id","itemId","item_id"])}}function Ln(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=Ln(i,e,n+1);if(s)return s}return}let r=q(t);if(!r)return;let o=G(r,e);if(o)return o;for(let i of Object.values(r)){let s=Ln(i,e,n+1);if(s)return s}}function Yt(t){return{threadId:Jt(t).threadId,cwd:Ln(t,["cwd","workdir","directory"])}}function Ds(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function Os(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 Bn(t){let e=q(t);if(!e)return;let n=q(e.item)??e;return G(n,["id","itemId","item_id","messageId","message_id"])}function Yu(t,e=!1){let n=q(t);if(!n)return"";let r=q(n.item)??n;return G(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?qe(r):G(r,["text"],{trim:!1})??qe(r)}function Ws(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:qe(e),itemId:Bn(e)}:n==="item/completed"?{mode:"snapshot",text:Yu(e),itemId:Bn(e)}:{mode:"ignore",text:""}}function Ns(t){return{itemId:Bn(t),delta:qe(t)}}function Ls(t){let e=q(t),n=q(e?.plan),o=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(i=>{let s=q(i),l=G(s,["step","title","text"]);if(!l)return null;let a=G(s,["status"])?.toLowerCase()??"pending";return{step:l,status:a==="inprogress"||a==="in_progress"?"inProgress":a==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:G(n,["explanation"])??G(e,["explanation"]),steps:o}}function Bs(t){let e=q(t);if(!e)return{};let n=q(e.item)??e;return G(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:Bn(n),text:G(n,["text"],{trim:!1})??qe(n)}}function Fs(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=q(e)??{},o=q(r.turn)??r,i=G(o,["status"])?.toLowerCase();return i==="failed"?"failed":i==="interrupted"||i==="cancelled"?"interrupted":"completed"}function qs(t,e){let n=q(e)??{},r=q(n.turn)??n,o=q(r.error)??q(n.error);if(o)return G(o,["message","text","summary","reason"])}function Zu(t,e){let n=Ju(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 ec(t){return Xu.has(t.trim().toLowerCase())}function tc(t){let e=q(t);return e?!!G(e,["threadId","thread_id"]):!1}async function Zt(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(ec(n)&&!tc(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,!Zu(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function Ks(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 Us(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 nc(t){return[{type:"text",text:t}]}function rc(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 Vs(t){let e={threadId:t.threadId,input:nc(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=rc(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function Gs(t){return[{threadId:t.threadId,turnId:t.turnId}]}function oc(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 js(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=ct(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let l=o?Mn(n):[],a=s.length>0?0:void 0,d=a!=null?s[a]:void 0,u=d?d.options:[],m=(o&&u.length===0?l:u).map(h=>h.label),p=(d?_e(d,a??0,s.length):_n(s))??(o?Ln(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,f=o?m.map(h=>({kind:"approval",label:h,decision:oc(h),responseDecision:h})):m.map(h=>({kind:"option",label:h,value:h}));return{requestId:e,kind:o?"approval":"question",promptText:p,options:m,...s.length>0?{questions:s}:{},...a!=null?{activeQuestionIndex:a}:{},actions:f,allowsFreeText:!0}}function Hs(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function Ho(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var Xu,zs=Q(()=>{Qt();Xu=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function dc(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return zo;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:zo}function Qo(t){return t instanceof Error?t.message:String(t)}function uc(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 Qs(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:_e(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}var ic,zo,sc,ac,lc,Fn,Js=Q(()=>{$s();Dn();Qt();zs();ic="1.0",zo=6e4,sc="OPENCLAW_CODEX_APP_SERVER_COMMAND",ac="OPENCLAW_CODEX_APP_SERVER_ARGS",lc="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS";Fn=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[sc]?.trim()||"codex",args:Es(process.env[ac]),requestTimeoutMs:dc(process.env[lc])},r=this.deps.createClient?.(n)??new Nn(n.command,n.args,n.requestTimeoutMs),o=new Be,i=e.resumeSessionId,s,l=e.backendRef?.worktreePath,a=e.backendRef?.worktreeId,d=e.permissionMode??"default",u,c=0,m="",p=[],f,h=new Map,k=new Set,v=E=>{let T=E?.trim();if(!T)return;let C=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&T!==C&&Ds(T)&&(l=T,a=Os(T))},I=()=>{i&&o.enqueue(pt({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...a?{worktreeId:a}:{},...l?{worktreePath:l}:{}}))};r.setNotificationHandler(async(E,T)=>{let C=E.trim().toLowerCase(),F=Jt(T),Y=Yt(T);if(F.threadId&&i&&F.threadId!==i)return;if(F.threadId&&(i=F.threadId),F.runId&&(s=F.runId),v(Y.cwd),(F.threadId||F.runId||Y.cwd)&&I(),C==="serverrequest/resolved"){u&&(o.enqueue(Fe(u.requestId)),u=void 0);return}if(C==="turn/plan/updated"){let N=Ls(T);m=N.explanation??m,N.steps.length>0&&(p=N.steps);return}if(C==="item/plan/delta"){let N=Ns(T);if(N.itemId&&N.delta){let oe=h.get(N.itemId)??"";h.set(N.itemId,`${oe}${N.delta}`)}return}if(C==="item/completed"){let N=Bs(T);if(N.text?.trim()){let oe={explanation:m||void 0,steps:p,markdown:N.text.trim()};o.enqueue(En(oe,!0));return}}let W=Ws(C,T);if(W.mode==="delta"&&W.text){W.itemId&&k.add(W.itemId),o.enqueue(Qe(W.text));return}W.mode==="snapshot"&&W.text&&(!W.itemId||!k.has(W.itemId))&&o.enqueue(Qe(W.text)),(C==="turn/completed"||C==="turn/failed"||C==="turn/cancelled")&&f&&(f.method=E,f.params=T,f.resolve())}),r.setRequestHandler(async(E,T)=>{if(!Hs(E))return{};let C=Jt(T),F=Yt(T);if(C.threadId&&i&&C.threadId!==i)return{};C.threadId&&(i=C.threadId),C.runId&&(s=C.runId),v(F.cwd),(C.threadId||C.runId||F.cwd)&&I();let Y=C.requestId??`${i??"codex"}-${Date.now().toString(36)}`,W;try{W=js(E,Y,T)}catch(qt){let In=Qo(qt);return`${In}`,{error:In}}let N=E.trim().toLowerCase(),oe=W.options,fe=W.actions??[],it=await new Promise(qt=>{u={requestId:Y,methodLower:N,state:W,options:oe,actions:fe,answers:{...W.answers??{}},resolveResponse:qt},o.enqueue(xe(W))});return u=void 0,o.enqueue(Fe(Y)),it});let x=async()=>{await r.connect(),await r.request("initialize",{protocolVersion:ic,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},n.requestTimeoutMs),await r.notify("initialized",{})},w=async()=>{let E=Ho(d,e.codexApprovalPolicy);if(i){let F=await Zt({client:r,methods:["thread/resume"],payloads:Us({threadId:i,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:E.approvalPolicy,sandbox:E.sandbox}),timeoutMs:n.requestTimeoutMs}),Y=Yt(F);i=Y.threadId??i,v(Y.cwd),I();return}let T=await Zt({client:r,methods:["thread/start","thread/new"],payloads:Ks({cwd:e.cwd,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:E.approvalPolicy,sandbox:E.sandbox}),timeoutMs:n.requestTimeoutMs}),C=Yt(T);if(i=C.threadId,!i)throw new Error("Codex App Server did not return a thread id.");v(C.cwd),I()},A=async E=>{await w(),o.enqueue(mt()),c+=1,m="",p=[],h.clear(),k.clear();let T="",C,F,Y=new Promise(W=>{F=W});f={resolve:F};try{let W=Ho(d,e.codexApprovalPolicy),N=await Zt({client:r,methods:["turn/start"],payloads:Vs({threadId:i,prompt:E,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:d,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),oe=Jt(N);oe.runId&&(s=oe.runId,I()),await Y,T=f?.method??"turn/failed",C=f?.params;let fe=Fs(T,C);o.enqueue($e({success:fe==="completed",outcome:fe,duration_ms:0,total_cost_usd:0,num_turns:c,result:qs(T,C),session_id:i}))}catch(W){o.enqueue($e({success:!1,duration_ms:0,total_cost_usd:0,num_turns:c,result:Qo(W),session_id:i??""}))}finally{f=void 0}},y=async E=>{let T=u;if(!T)return!1;let C=E.trim();if(T.methodLower.includes("requestapproval"))return T.resolveResponse({decision:C||"decline"}),!0;let F=T.state.questions??[];if(F.length>0){if(!C)return!1;let Y=T.state.activeQuestionIndex??0,W=F[Y];if(!W)return!1;T.answers={...T.answers,[W.id]:{answers:[C]}};let N=Y+1;if(N<F.length)return T.state=Qs(T.state,N,T.answers),T.options=T.state.options,o.enqueue(xe(T.state)),!0;T.resolveResponse({answers:T.answers})}else T.resolveResponse({text:C});return!0},b=async(E,T={})=>{let C=u;if(!C||T.requestId&&T.requestId!==C.state.requestId)return!1;let F=C.actions[E];if(F?.kind==="approval")return C.resolveResponse({decision:F.responseDecision,...F.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:F.proposedExecpolicyAmendment}:{}}),!0;let Y=C.state.questions??[],W=C.state.activeQuestionIndex??0,N=Y.length>0?Y[W]:void 0;if(T.questionId&&T.questionId!==N?.id)return!1;let oe=N?.options[E];if(N&&oe){C.answers={...C.answers,[N.id]:{answers:[oe.value??oe.label]}};let it=W+1;return it<Y.length?(C.state=Qs(C.state,it,C.answers),C.options=C.state.options,o.enqueue(xe(C.state)),!0):(C.resolveResponse({answers:C.answers}),!0)}let fe=C.options[E];return fe?(C.methodLower.includes("requestapproval")?C.resolveResponse({decision:fe}):C.resolveResponse({option:fe,index:E}),!0):!1},V=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{await x();for await(let E of V){let T=uc(E).trim();!T||await y(T)||await A(T)}}catch(E){o.enqueue($e({success:!1,duration_ms:0,total_cost_usd:0,num_turns:c,result:Qo(E),session_id:i??e.resumeSessionId??""}))}finally{await r.close().catch(()=>{}),o.close()}})(),{messages:o.messages(),async setPermissionMode(E){d=E,o.enqueue(ft(E))},async submitPendingInputOption(E,T){return b(E,T)},async submitPendingInputText(E){return y(E)},async interrupt(){!i||!s||await Zt({client:r,methods:["turn/interrupt"],payloads:Gs({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as cc}from"node:child_process";import{constants as pc,accessSync as mc}from"node:fs";import{createServer as fc}from"node:net";import{delimiter as gc,dirname as Jo,join as Xs,sep as hc}from"node:path";function ht(t){return t instanceof Error?t.message:String(t)}function Pc(t){try{return mc(t,pc.X_OK),!0}catch{return!1}}function wc(t){return t.includes("/")||hc==="\\"&&t.includes("\\")}function bc(t){let e=(t??"").split(gc).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(Xs(Jo(Jo(Jo(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function Rc(t,e=process.env.PATH){if(wc(t))return t;for(let n of bc(e)){let r=Xs(n,t);if(Pc(r))return r}return t}function ne(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Ac(t){if(typeof t=="string")return t;if(!ne(t))return String(t);if(typeof t.text=="string")return t.text;let e=ne(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function ea(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 Ic(t){let e=ea(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function Ys(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return vc.map(r=>({permission:r,pattern:"*",action:n}))}function Yo(){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 xc(){return new Promise((t,e)=>{let n=fc();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 ta(t){await new Promise(e=>setTimeout(e,t))}async function qn(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(a),e.signal?.removeEventListener("abort",l)},s=d=>{o||(o=!0,i(),d())},l=()=>{s(()=>r(new Error(e.abortMessage??"Operation was aborted.")))},a=setTimeout(()=>{s(()=>{e.onTimeout?.(),r(new Error(e.timeoutMessage))})},e.timeoutMs);e.signal?.addEventListener("abort",l,{once:!0}),t.then(d=>s(()=>n(d)),d=>s(()=>r(d)))})}async function gt(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 Tc(t){return t.headers.get("content-type")?.toLowerCase()??""}function Xo(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function Cc(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function Mc(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=Xo(r),s=Cc(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 _c(t,e,n){let r=ea(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function $c(t,e){if(!ne(t))return!1;if(!(e in t))return!0;let n=t[e];return ne(n)&&n.type==="idle"}function Ec(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function Dc(t){return new Promise((e,n)=>{Zs=Zs.then(()=>t().then(e,n)).catch(()=>{})})}async function Oc(t){return Dc(async()=>{let e=await xc(),n=process.env[yc]?.trim()||"opencode",r=Rc(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??ni,1e4),l=t.startupTimeoutMs??kc,a=cc(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),d=`http://127.0.0.1:${e}`,u="",c="",m,p=(v,I)=>{let x=v+String(I);return x.length>8e3?x.slice(-8e3):x};a.stdout.on("data",v=>{u=p(u,v)}),a.stderr.on("data",v=>{c=p(c,v)}),a.once("error",v=>{m=v});let f=()=>` Command: ${n===r?r:`${r} (resolved from ${n})`} ${o.join(" ")}. Cwd: ${t.cwd}. Port: ${e}. PATH: ${process.env.PATH??""}.`,h=()=>{let v=[u.trim(),c.trim()].filter(Boolean).join(`
1
+ var wu=Object.defineProperty;var Q=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(r){throw n=[r],r}};var bu=(t,e)=>{for(var n in e)wu(t,n,{get:e[n],enumerable:!0})};function Ut(t,e){return e?{...e,...t}:t}function Ru(t){return{...t,[Wo]:!0}}function Au(t){return{const:t,type:typeof t}}var Wo,g,te=Q(()=>{Wo=Symbol("optionalSchema");g={Object(t,e){let n=Object.entries(t).filter(([,o])=>!o[Wo]).map(([o])=>o),r=Object.fromEntries(Object.entries(t).map(([o,i])=>{let{[Wo]:s,...l}=i;return[o,l]}));return{...e,type:"object",...n.length>0?{required:n}:{},properties:r}},String(t){return Ut({type:"string"},t)},Number(t){return Ut({type:"number"},t)},Boolean(t){return Ut({type:"boolean"},t)},Array(t,e){return Ut({type:"array",items:t},e)},Literal:Au,Union(t,e){return Ut({anyOf:t},e)},Optional:Ru}});function No(t){S=t}function Lo(t){j=t}var S,j,L=Q(()=>{S=null,j=null});function ws(t){let e=t.chatId.trim(),n=t.topicId.trim();return!/^-?\d+$/.test(e)||!/^\d+$/.test(n)?null:`${e}:topic:${n}`}function Mu(t){let e=t.conversationId.trim(),n=e.match(/^(-?\d+):topic:(\d+)$/i);if(n?.[1]&&n[2]){let i=ws({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=ws({chatId:r,topicId:e});return o?{chatId:r,topicId:e,canonicalConversationId:o}:null}function _u(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 $u(t,e){if(!/^\d+$/.test(t))return t;let n=_u(e);return n?`${n}:${t}`:`channel:${t}`}function Eu(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 Du(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 Ou(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||!Cu.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 Wu(t,e=Mu){try{return e({conversationId:t})}catch{return null}}function Bo(t){return{provider:"system",target:"system",sessionKey:t?.trim()||void 0}}function Fo(t,e){return{...t,threadId:e??t.threadId}}function Lu(t,e,n){return t==="telegram"&&n?.provider==="telegram"&&!!n.target&&e!==n.target}function Bu(t){let e=t?.trim();if(!e)return;let n=Ou(e);if(!n)return;let{provider:r,kind:o,rawId:i}=n,s=Du(i),l=null;if(r==="telegram")try{l=Nu.safeParseTelegramTopicConversation(i)}catch{l=null}let a=l?.chatId??s.id,d=l?.topicId??s.threadId,u=r==="discord"?o==="direct"||o==="dm"?`user:${a}`:`channel:${a}`:a;return{provider:r,target:u,threadId:d,sessionKey:e}}function qo(t){let e=t?.match(/:topic:(\d+)$/i);return e?parseInt(e[1],10):void 0}function bs(t){return!!(t?.provider&&t.target&&t.provider!=="system"&&t.target!=="system")}function Vt(t,e,n){let r=Bu(n),o=e!=null?String(e):void 0,i=t?.trim();if(!i||i.toLowerCase()==="unknown")return r?Fo(r,o):Bo(n);let s=i.split("|").map(f=>f.trim());if(s.length<2)return r?Fo(r,o):Bo(n);let[l,a,d]=s,u=s.length>=3?d:a,c=s.length>=3?a:void 0,m=l?.toLowerCase();if(!m||!u)return r?Fo(r,o):Bo(n);let p=m==="discord"?$u(u,n):u;return Lu(m,p,r)?{provider:m,accountId:c,target:r.target,threadId:o??r.threadId,sessionKey:n?.trim()||void 0}:{provider:m,accountId:c,target:p,threadId:o??(r?.provider===m?r.threadId:void 0),sessionKey:n?.trim()||void 0}}function He(t){return Vt(Eu(t.route)??t.originChannel,t.route?.threadId??t.originThreadId,t.route?.sessionKey??t.originSessionKey)??t.route}function Me(t){let e=He(t);return bs(e)?e:void 0}function Fu(t){return Object.fromEntries(Object.entries(t).filter(e=>!!e[1]))}function Gt(t){let e=He(t);if(!bs(e))return"";let n=Fu({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 Cu,Nu,be=Q(()=>{Cu=new Set(["telegram","discord","slack","system","mattermost","feishu","line","whatsapp","signal","matrix","googlechat","bluebubbles","imessage","msteams"]);Nu={safeParseTelegramTopicConversation:Wu}});import{readFileSync as qu}from"fs";import{homedir as Ku}from"os";import{join as Uu}from"path";function As(){if(jt!==void 0)return jt;try{let t=qu(Uu(Ku(),".claude.json"),"utf-8");jt=JSON.parse(t).mcpServers??{}}catch{jt={}}return jt}function Is(t){let e=t.defaultHarness??Rs,n={};for(let[r,o]of Object.entries(Ht)){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 ae(){return D.defaultHarness??Rs}function Vo(t){let e=Ht[t],n=D.harnesses[t];return{...e,...n,allowedModels:n?.allowedModels??e?.allowedModels}}function at(t){return Vo(t).defaultModel}function Tn(t){return D.harnesses[t]?.allowedModels??D.allowedModels}function Le(t){return Vo(t).reasoningEffort}function lt(t){return t==="codex"?Vo(t).fastMode:void 0}function ke(t){return t==null?void 0:String(t).trim()||void 0}function Go(t){return{channel:ke(t?.deliveryContext?.channel),to:ke(t?.deliveryContext?.to),accountId:ke(t?.deliveryContext?.accountId),threadId:ke(t?.deliveryContext?.threadId)}}function xs(t,e,n){if(!(!t||!e))return n?`${t}|${n}|${e}`:`${t}|${e}`}function Ko(t){return ke(t?.requesterSenderId??t?.senderId)}function Uo(t){return(ke(t.deliveryContext?.channel)??t.messageChannel??t.channel)?.toLowerCase()!=="telegram"?!1:!!(qo(t.sessionKey)||ke(t.messageThreadId)||ke(t.deliveryContext?.threadId))}function Cn(t){let e=Go(t),n=xs(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=ke(t.chatId);if(r.length===1&&o)return`${r[0]}|${o}`;let i=Ko(t);if(r.length===1&&i&&!Uo(t))return`${r[0]}|${i}`}if(t.workspaceDir){let r=ze(t.workspaceDir);if(r)return r}if(t.messageChannel&&t.messageChannel.includes("|"))return t.messageChannel}function zt(t,e){if(e&&String(e).includes("|"))return String(e);let n=Go(t),r=xs(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 l=String(t.messageChannel);if(l.includes("|"))return l;let a=ke(t.chatId);if(a)return`${l}|${a}`;let d=Ko(t);if(d&&!Uo(t))return`${l}|${d}`}let o=ke(t?.channel),i=ke(t?.chatId);if(o&&i)return`${o}|${i}`;let s=Ko(t);return o&&s&&!Uo(t)?`${o}|${s}`:t?.id&&/^-?\d+$/.test(String(t.id))?`telegram|${t.id}`:D.fallbackChannel??"unknown"}function jo(t){return Go(t).threadId??t?.messageThreadId??void 0}function dt(t,e,n){return Vt(zt(t,e),jo(t),n??t?.sessionKey)}function ze(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 Ts(t){return qo(t)}var jt,Rs,Ht,D,ie=Q(()=>{be();Rs="claude-code",Ht={"claude-code":{defaultModel:"anthropic/claude-sonnet-4-7",allowedModels:["sonnet","opus"]},codex:{defaultModel:"gpt-5.5",allowedModels:["gpt-5.5","gpt-5.5-pro"],reasoningEffort:"medium"},opencode:{}};D={maxSessions:20,idleTimeoutMinutes:15,sessionGcAgeMinutes:1440,maxPersistedSessions:1e4,maxAutoResponds:10,permissionMode:"plan",planApproval:"delegate",defaultWorktreeStrategy:"delegate",harnesses:{"claude-code":{...Ht["claude-code"]},codex:{...Ht.codex},opencode:{...Ht.opencode}}}});function q(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function G(t,e,n){for(let r of e){let o=t?.[r];if(typeof o!="string")continue;let i=n?.trim===!1?o:o.trim();if(i)return i}}function Cs(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 Ms(t){if(typeof t=="string"){let s=t.trim();return s?{label:s,value:s,recommended:Cs(s)}:void 0}let e=q(t);if(!e)return;let n=G(e,["label","title","text","value","name","id"])?.trim();if(!n)return;let r=G(e,["description","preview","detail","details"]),o=G(e,["value","id","name"]),i=e.isOther===!0||e.is_other===!0||e.other===!0;return{label:n,...r?{description:r}:{},...o?{value:o}:{},...i?{isOther:!0}:{},recommended:Cs(n,e)}}function Mn(t){let e=q(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(Ms).filter(r=>!!r):[]}function ct(t){let e=q(t);return(Array.isArray(e?.questions)?e.questions:[]).map((r,o)=>Vu(r,o)).filter(r=>!!r)}function Vu(t,e=0){let n=q(t);if(!n)return;let r=G(n,["question","prompt","message","text","summary"])?.trim();if(!r)return;let o=G(n,["id","questionId","question_id","name"]),i=G(n,["header","title","label"]),l=(Array.isArray(n.options)?n.options:Array.isArray(n.choices)?n.choices:[]).map(Ms).filter(u=>!!u),a=n.multiSelect===!0||n.multi_select===!0,d=n.isOther===!0||n.is_other===!0||n.allowFreeText===!0||n.allowsFreeText===!0||a||l.some(u=>u.isOther);return{id:o??`question_${e+1}`,...i?{header:i}:{},question:r,options:l,...a?{multiSelect:!0}:{},...d?{allowsFreeText:!0}:{},...n.isSecret===!0||n.is_secret===!0?{isSecret:!0}:{}}}function _s(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 l=i.recommended&&!/\brecommended\b/i.test(i.label)?" (recommended)":"",a=i.description?` - ${i.description}`:"",d=i.isOther?" (free text)":"";return` ${s+1}. ${i.label}${l}${d}${a}`})),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 _n(t){if(t.length===0)return;let e=t.flatMap((n,r)=>[...r>0?[""]:[],..._s(n,r,t.length)]);return t.length>1&&e.push("","Reply with answers by question, for example: Q1: ..., Q2: ..."),e.join(`
3
+ `)}function _e(t,e,n){return _s(t,e,n).join(`
4
+ `)}var Qt=Q(()=>{});function pt(t){return{type:"backend_ref",ref:t}}function mt(t){return{type:"run_started",...t?{runId:t}:{}}}function Qe(t){return{type:"text_delta",text:t}}function $n(t,e){return{type:"tool_call",name:t,input:e}}function xe(t){return{type:"pending_input",state:t}}function Fe(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function En(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function ft(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function $e(t){return{type:"run_completed",data:t}}var Be,Dn=Q(()=>{Be=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 Wn from"@anthropic-ai/claude-agent-sdk";function Gu(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 ju(t,e,n){let r=ct(n),o=r.length>0?0:void 0,i=o!=null?r[o]:void 0,s=i?.options.map(a=>a.label)??[],l=i?_e(i,o,r.length):_n(r);return{requestId:`${t||"claude"}-ask-${e}`,kind:"question",promptText:l,options:s,...r.length>0?{questions:r}:{},...o!=null?{activeQuestionIndex:o}:{},allowsFreeText:i?.allowsFreeText===!0||s.length===0}}var On,$s=Q(()=>{Qt();Dn();On=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 Be,r=!1,o="",i=!1,s=0,l=e.resumeSessionId??"",a=e.canUseTool,d={cwd:e.cwd,model:e.model,...e.reasoningEffort?{effort:e.reasoningEffort}:{},permissionMode:e.permissionMode,allowDangerouslySkipPermissions:!0,allowedTools:e.allowedTools,systemPrompt:e.systemPrompt,includePartialMessages:!0,abortController:e.abortController,mcpServers:e.mcpServers,...a?{canUseTool:async(f,h)=>{if(f!=="AskUserQuestion")return{behavior:"allow"};let k=ju(l,++s,h);n.enqueue(xe(k));try{let v=await a(f,h);return n.enqueue(Fe(k.requestId)),v}catch(v){throw n.enqueue(Fe(k.requestId)),v}}}:{}};e.resumeSessionId&&(d.resume=e.resumeSessionId,d.forkSession=e.forkSession??!1);let u=e.prompt,c=this.deps.query??Wn.query,m=this.deps.startup??Wn.startup,p=(async()=>{if(typeof m!="function")return c({prompt:u,options:d});let f=await m({options:d});try{return f.query(u)}catch(h){throw await f.close?.(),h}})();return(async()=>{try{let f=await p;for await(let h of f){let k=h;if(k.type==="system"&&k.subtype==="init"){l=k.session_id??l,n.enqueue(pt({kind:"claude-code",conversationId:l}));continue}if(k.type==="system"&&k.subtype==="status"&&k.permissionMode){n.enqueue(ft(k.permissionMode));continue}if(k.type==="assistant"){r||(r=!0,n.enqueue(mt()));for(let v of k.message?.content??[]){if(v.type==="text"){o+=o?`
6
+ ${v.text}`:v.text,n.enqueue(Qe(v.text));continue}v.type==="tool_use"&&((v.name==="ExitPlanMode"||v.name==="set_permission_mode")&&(i=!0),v.name!=="AskUserQuestion"&&n.enqueue($n(v.name,v.input)))}continue}if(k.type==="result"){let v=o.trim();if(v&&(e.permissionMode==="plan"||i)){let I={explanation:void 0,steps:[],markdown:v};n.enqueue(En(I,!0))}n.enqueue($e({success:k.subtype==="success",duration_ms:k.duration_ms??0,total_cost_usd:k.total_cost_usd??0,num_turns:k.num_turns??0,result:Gu(k),session_id:k.session_id??l})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(f=>{n.enqueue($e({success:!1,duration_ms:0,total_cost_usd:0,num_turns:0,result:f instanceof Error?f.message:String(f),session_id:l})),n.close()}),{messages:n.messages(),async setPermissionMode(f){let h=await p;typeof h.setPermissionMode=="function"&&await h.setPermissionMode(f)},async streamInput(f){let h=await p;typeof h.streamInput=="function"&&await h.streamInput(f)},async interrupt(){let f=await p;typeof f.interrupt=="function"&&await f.interrupt()}}}buildUserMessage(e,n){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:n}}}});import{spawn as Hu}from"node:child_process";import zu from"node:readline";function Qu(t){return t instanceof Error?t.message:String(t)}function Ju(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function Yu(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:Qu(r)}})}}}function Zu(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 Nn,Es=Q(()=>{Nn=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=Hu(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(!e.stdin||!e.stdout||!e.stderr)throw new Error("codex app server stdio pipes unavailable");this.process=e,zu.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("close",()=>{this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){this.flushPending(new Error("codex app server stdio closed"));let e=this.process;this.process=null,e&&e.kill()}async notify(e,n){this.write({jsonrpc:"2.0",method:e,params:n??{}})}async request(e,n,r){let o=`rpc-${++this.counter}`,i=new Promise((s,l)=>{let a=Math.max(100,r??this.requestTimeoutMs),d=setTimeout(()=>{this.pending.delete(o),l(new Error(this.buildTimeoutErrorMessage(e,a)))},a);d.unref?.(),this.pending.set(o,{resolve:s,reject:l,timer:d})});return this.write({jsonrpc:"2.0",id:o,method:e,params:n??{}}),await i}write(e){if(!this.process?.stdin)throw new Error("codex app server stdio not connected");this.process.stdin.write(`${JSON.stringify(e)}
7
+ `)}async handleLine(e){let n=Ju(e);n&&await Yu(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){for(let[n,r]of this.pending)clearTimeout(r.timer),r.reject(e),this.pending.delete(n)}buildTimeoutErrorMessage(e,n){let r=this.stderrTail.trim(),o=r?`; recent stderr: ${Zu(r)}`:"";return`codex app server timeout after ${n}ms: ${e}${o}`}}});function Xu(t){return t instanceof Error?t.message:String(t)}function Ds(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function qe(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>qe(n)).join("");let e=q(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=qe(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=qe(e[n]);if(r)return r}return""}function Jt(t){let e=q(t);if(!e)return{};let n=q(e.thread)??q(e.session),r=q(e.turn)??q(e.run),o=q(e.item),i=q(e.serverRequest);return{threadId:G(e,["threadId","thread_id","conversationId","conversation_id"])??G(n,["id","threadId","thread_id","conversationId"]),runId:G(e,["turnId","turn_id","runId","run_id"])??G(r,["id","turnId","turn_id","runId","run_id"]),requestId:G(e,["requestId","request_id","serverRequestId"])??G(i,["id","requestId","request_id"]),itemId:G(e,["itemId","item_id"])??G(o,["id","itemId","item_id"])}}function Ln(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=Ln(i,e,n+1);if(s)return s}return}let r=q(t);if(!r)return;let o=G(r,e);if(o)return o;for(let i of Object.values(r)){let s=Ln(i,e,n+1);if(s)return s}}function Yt(t){return{threadId:Jt(t).threadId,cwd:Ln(t,["cwd","workdir","directory"])}}function Os(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function Ws(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 Bn(t){let e=q(t);if(!e)return;let n=q(e.item)??e;return G(n,["id","itemId","item_id","messageId","message_id"])}function ec(t,e=!1){let n=q(t);if(!n)return"";let r=q(n.item)??n;return G(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?qe(r):G(r,["text"],{trim:!1})??qe(r)}function Ns(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:qe(e),itemId:Bn(e)}:n==="item/completed"?{mode:"snapshot",text:ec(e),itemId:Bn(e)}:{mode:"ignore",text:""}}function Ls(t){return{itemId:Bn(t),delta:qe(t)}}function Bs(t){let e=q(t),n=q(e?.plan),o=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(i=>{let s=q(i),l=G(s,["step","title","text"]);if(!l)return null;let a=G(s,["status"])?.toLowerCase()??"pending";return{step:l,status:a==="inprogress"||a==="in_progress"?"inProgress":a==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:G(n,["explanation"])??G(e,["explanation"]),steps:o}}function Fs(t){let e=q(t);if(!e)return{};let n=q(e.item)??e;return G(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:Bn(n),text:G(n,["text"],{trim:!1})??qe(n)}}function qs(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=q(e)??{},o=q(r.turn)??r,i=G(o,["status"])?.toLowerCase();return i==="failed"?"failed":i==="interrupted"||i==="cancelled"?"interrupted":"completed"}function Ks(t,e){let n=q(e)??{},r=q(n.turn)??n,o=q(r.error)??q(n.error);if(o)return G(o,["message","text","summary","reason"])}function tc(t,e){let n=Xu(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 rc(t){return nc.has(t.trim().toLowerCase())}function oc(t){let e=q(t);return e?!!G(e,["threadId","thread_id"]):!1}async function Zt(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(rc(n)&&!oc(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,!tc(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function Us(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 Vs(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 ic(t){return[{type:"text",text:t}]}function sc(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 Gs(t){let e={threadId:t.threadId,input:ic(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=sc(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function js(t){return[{threadId:t.threadId,turnId:t.turnId}]}function ac(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 Hs(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=ct(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let l=o?Mn(n):[],a=s.length>0?0:void 0,d=a!=null?s[a]:void 0,u=d?d.options:[],m=(o&&u.length===0?l:u).map(h=>h.label),p=(d?_e(d,a??0,s.length):_n(s))??(o?Ln(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,f=o?m.map(h=>({kind:"approval",label:h,decision:ac(h),responseDecision:h})):m.map(h=>({kind:"option",label:h,value:h}));return{requestId:e,kind:o?"approval":"question",promptText:p,options:m,...s.length>0?{questions:s}:{},...a!=null?{activeQuestionIndex:a}:{},actions:f,allowsFreeText:!0}}function zs(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function Ho(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var nc,Qs=Q(()=>{Qt();nc=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function mc(t){let e=t?.trim();return e&&pc.test(e)?e:void 0}function fc(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return zo;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:zo}function Qo(t){return t instanceof Error?t.message:String(t)}function gc(t){if(typeof t=="string")return t;if(!t||typeof t!="object")return String(t);let e=t;return typeof e.message?.content=="string"?e.message.content:typeof e.text=="string"?e.text:String(t)}function Ys(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:_e(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}function hc(t){if(t===void 0)return Js;let e=Ds(t);return e.length>0?e:Js}var lc,zo,Js,dc,uc,cc,pc,Fn,Zs=Q(()=>{Es();Dn();Qt();Qs();lc="1.0",zo=12e4,Js=["--listen","stdio://"],dc="OPENCLAW_CODEX_APP_SERVER_COMMAND",uc="OPENCLAW_CODEX_APP_SERVER_ARGS",cc="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS",pc=/^(?: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}$/;Fn=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[dc]?.trim()||"codex",args:hc(process.env[uc]),requestTimeoutMs:fc(process.env[cc])},r=this.deps.createClient?.(n)??new Nn(n.command,n.args,n.requestTimeoutMs),o=new Be,i=mc(e.resumeSessionId);e.resumeSessionId&&!i&&`${e.resumeSessionId}`;let s,l=e.backendRef?.worktreePath,a=e.backendRef?.worktreeId,d=e.permissionMode??"default",u,c=0,m="",p=[],f,h=new Map,k=new Set,v=E=>{let T=E?.trim();if(!T)return;let C=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&T!==C&&Os(T)&&(l=T,a=Ws(T))},I=()=>{i&&o.enqueue(pt({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...a?{worktreeId:a}:{},...l?{worktreePath:l}:{}}))};r.setNotificationHandler(async(E,T)=>{let C=E.trim().toLowerCase(),F=Jt(T),Y=Yt(T);if(F.threadId&&i&&F.threadId!==i)return;if(F.threadId&&(i=F.threadId),F.runId&&(s=F.runId),v(Y.cwd),(F.threadId||F.runId||Y.cwd)&&I(),C==="serverrequest/resolved"){u&&(o.enqueue(Fe(u.requestId)),u=void 0);return}if(C==="turn/plan/updated"){let N=Bs(T);m=N.explanation??m,N.steps.length>0&&(p=N.steps);return}if(C==="item/plan/delta"){let N=Ls(T);if(N.itemId&&N.delta){let oe=h.get(N.itemId)??"";h.set(N.itemId,`${oe}${N.delta}`)}return}if(C==="item/completed"){let N=Fs(T);if(N.text?.trim()){let oe={explanation:m||void 0,steps:p,markdown:N.text.trim()};o.enqueue(En(oe,!0));return}}let W=Ns(C,T);if(W.mode==="delta"&&W.text){W.itemId&&k.add(W.itemId),o.enqueue(Qe(W.text));return}W.mode==="snapshot"&&W.text&&(!W.itemId||!k.has(W.itemId))&&o.enqueue(Qe(W.text)),(C==="turn/completed"||C==="turn/failed"||C==="turn/cancelled")&&f&&(f.method=E,f.params=T,f.resolve())}),r.setRequestHandler(async(E,T)=>{if(!zs(E))return{};let C=Jt(T),F=Yt(T);if(C.threadId&&i&&C.threadId!==i)return{};C.threadId&&(i=C.threadId),C.runId&&(s=C.runId),v(F.cwd),(C.threadId||C.runId||F.cwd)&&I();let Y=C.requestId??`${i??"codex"}-${Date.now().toString(36)}`,W;try{W=Hs(E,Y,T)}catch(qt){let In=Qo(qt);return`${In}`,{error:In}}let N=E.trim().toLowerCase(),oe=W.options,fe=W.actions??[],it=await new Promise(qt=>{u={requestId:Y,methodLower:N,state:W,options:oe,actions:fe,answers:{...W.answers??{}},resolveResponse:qt},o.enqueue(xe(W))});return u=void 0,o.enqueue(Fe(Y)),it});let x=async()=>{await r.connect(),await r.request("initialize",{protocolVersion:lc,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},n.requestTimeoutMs),await r.notify("initialized",{})},w=async()=>{let E=Ho(d,e.codexApprovalPolicy);if(i){let F=await Zt({client:r,methods:["thread/resume"],payloads:Vs({threadId:i,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:E.approvalPolicy,sandbox:E.sandbox}),timeoutMs:n.requestTimeoutMs}),Y=Yt(F);i=Y.threadId??i,v(Y.cwd),I();return}let T=await Zt({client:r,methods:["thread/start","thread/new"],payloads:Us({cwd:e.cwd,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:E.approvalPolicy,sandbox:E.sandbox}),timeoutMs:n.requestTimeoutMs}),C=Yt(T);if(i=C.threadId,!i)throw new Error("Codex App Server did not return a thread id.");v(C.cwd),I()},A=async E=>{await w(),o.enqueue(mt()),c+=1,m="",p=[],h.clear(),k.clear();let T="",C,F,Y=new Promise(W=>{F=W});f={resolve:F};try{let W=Ho(d,e.codexApprovalPolicy),N=await Zt({client:r,methods:["turn/start"],payloads:Gs({threadId:i,prompt:E,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:d,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),oe=Jt(N);oe.runId&&(s=oe.runId,I()),await Y,T=f?.method??"turn/failed",C=f?.params;let fe=qs(T,C);o.enqueue($e({success:fe==="completed",outcome:fe,duration_ms:0,total_cost_usd:0,num_turns:c,result:Ks(T,C),session_id:i}))}catch(W){o.enqueue($e({success:!1,duration_ms:0,total_cost_usd:0,num_turns:c,result:Qo(W),session_id:i??""}))}finally{f=void 0}},y=async E=>{let T=u;if(!T)return!1;let C=E.trim();if(T.methodLower.includes("requestapproval"))return T.resolveResponse({decision:C||"decline"}),!0;let F=T.state.questions??[];if(F.length>0){if(!C)return!1;let Y=T.state.activeQuestionIndex??0,W=F[Y];if(!W)return!1;T.answers={...T.answers,[W.id]:{answers:[C]}};let N=Y+1;if(N<F.length)return T.state=Ys(T.state,N,T.answers),T.options=T.state.options,o.enqueue(xe(T.state)),!0;T.resolveResponse({answers:T.answers})}else T.resolveResponse({text:C});return!0},b=async(E,T={})=>{let C=u;if(!C||T.requestId&&T.requestId!==C.state.requestId)return!1;let F=C.actions[E];if(F?.kind==="approval")return C.resolveResponse({decision:F.responseDecision,...F.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:F.proposedExecpolicyAmendment}:{}}),!0;let Y=C.state.questions??[],W=C.state.activeQuestionIndex??0,N=Y.length>0?Y[W]:void 0;if(T.questionId&&T.questionId!==N?.id)return!1;let oe=N?.options[E];if(N&&oe){C.answers={...C.answers,[N.id]:{answers:[oe.value??oe.label]}};let it=W+1;return it<Y.length?(C.state=Ys(C.state,it,C.answers),C.options=C.state.options,o.enqueue(xe(C.state)),!0):(C.resolveResponse({answers:C.answers}),!0)}let fe=C.options[E];return fe?(C.methodLower.includes("requestapproval")?C.resolveResponse({decision:fe}):C.resolveResponse({option:fe,index:E}),!0):!1},V=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{await x();for await(let E of V){let T=gc(E).trim();!T||await y(T)||await A(T)}}catch(E){o.enqueue($e({success:!1,duration_ms:0,total_cost_usd:0,num_turns:c,result:Qo(E),session_id:i??e.resumeSessionId??""}))}finally{await r.close().catch(()=>{}),o.close()}})(),{messages:o.messages(),async setPermissionMode(E){d=E,o.enqueue(ft(E))},async submitPendingInputOption(E,T){return b(E,T)},async submitPendingInputText(E){return y(E)},async interrupt(){!i||!s||await Zt({client:r,methods:["turn/interrupt"],payloads:js({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as yc}from"node:child_process";import{constants as kc,accessSync as Sc}from"node:fs";import{createServer as vc}from"node:net";import{delimiter as Pc,dirname as Jo,join as ta,sep as wc}from"node:path";function ht(t){return t instanceof Error?t.message:String(t)}function xc(t){try{return Sc(t,kc.X_OK),!0}catch{return!1}}function Tc(t){return t.includes("/")||wc==="\\"&&t.includes("\\")}function Cc(t){let e=(t??"").split(Pc).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(ta(Jo(Jo(Jo(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function Mc(t,e=process.env.PATH){if(Tc(t))return t;for(let n of Cc(e)){let r=ta(n,t);if(xc(r))return r}return t}function ne(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function _c(t){if(typeof t=="string")return t;if(!ne(t))return String(t);if(typeof t.text=="string")return t.text;let e=ne(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function na(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 $c(t){let e=na(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function Xs(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return Ic.map(r=>({permission:r,pattern:"*",action:n}))}function Yo(){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 Ec(){return new Promise((t,e)=>{let n=vc();n.once("error",e),n.listen(0,"127.0.0.1",()=>{let r=n.address();n.close(()=>{r&&typeof r=="object"?t(r.port):e(new Error("Could not allocate local OpenCode server port."))})})})}async function ra(t){await new Promise(e=>setTimeout(e,t))}async function qn(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(a),e.signal?.removeEventListener("abort",l)},s=d=>{o||(o=!0,i(),d())},l=()=>{s(()=>r(new Error(e.abortMessage??"Operation was aborted.")))},a=setTimeout(()=>{s(()=>{e.onTimeout?.(),r(new Error(e.timeoutMessage))})},e.timeoutMs);e.signal?.addEventListener("abort",l,{once:!0}),t.then(d=>s(()=>n(d)),d=>s(()=>r(d)))})}async function gt(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 Dc(t){return t.headers.get("content-type")?.toLowerCase()??""}function Xo(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function Oc(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function Wc(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=Xo(r),s=Oc(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 Nc(t,e,n){let r=na(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function Lc(t,e){if(!ne(t))return!1;if(!(e in t))return!0;let n=t[e];return ne(n)&&n.type==="idle"}function Bc(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function Fc(t){return new Promise((e,n)=>{ea=ea.then(()=>t().then(e,n)).catch(()=>{})})}async function qc(t){return Fc(async()=>{let e=await Ec(),n=process.env[bc]?.trim()||"opencode",r=Mc(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??ni,1e4),l=t.startupTimeoutMs??Rc,a=yc(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),d=`http://127.0.0.1:${e}`,u="",c="",m,p=(v,I)=>{let x=v+String(I);return x.length>8e3?x.slice(-8e3):x};a.stdout.on("data",v=>{u=p(u,v)}),a.stderr.on("data",v=>{c=p(c,v)}),a.once("error",v=>{m=v});let f=()=>` Command: ${n===r?r:`${r} (resolved from ${n})`} ${o.join(" ")}. Cwd: ${t.cwd}. Port: ${e}. PATH: ${process.env.PATH??""}.`,h=()=>{let v=[u.trim(),c.trim()].filter(Boolean).join(`
8
8
  `).trim();return`${f()}${v?` Output:
9
- ${v}`:""}`},k=()=>{gt(a)};if(t.signal?.aborted)throw await gt(a),new Error(`OpenCode server startup aborted before readiness.${h()}`);t.signal?.addEventListener("abort",k,{once:!0});try{let v=Date.now();for(;Date.now()-v<l;){if(t.signal?.aborted)throw await gt(a),new Error(`OpenCode server startup aborted before readiness.${h()}`);if(m)throw new Error(`OpenCode server failed to start: ${m.message}${h()}`);if(a.exitCode!==null)throw new Error(`OpenCode server exited before readiness.${h()}`);try{if(await Nc({baseUrl:d,fetchImpl:i,requestTimeoutMs:s,startupSignal:t.signal,timeoutMessage:`OpenCode GET /api/health timed out after ${s}ms during server readiness.${h()}`,abortMessage:`OpenCode server startup aborted before readiness.${h()}`}))return{baseUrl:d,close:async()=>{await gt(a)}}}catch{if(t.signal?.aborted)throw await gt(a),new Error(`OpenCode server startup aborted before readiness.${h()}`)}await ta(100)}throw await gt(a),new Error(`Timed out waiting for OpenCode server readiness.${h()}`)}finally{t.signal?.removeEventListener("abort",k)}})}async function Wc(t){for(let e=1;;e+=1)try{return await Oc(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(ht(n)))throw n}}async function Nc(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await qn(t.fetchImpl(`${t.baseUrl}/api/health`,{headers:Yo(),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 Lc(t){let e=ne(t)&&ne(t.payload)?t.payload:t;return ne(e)?e.type==="sync"?{type:typeof e.name=="string"?e.name.replace(/\.\d+$/,""):void 0,properties:ne(e.data)?e.data:{}}:{type:typeof e.type=="string"?e.type:void 0,properties:ne(e.properties)?e.properties:e}:{properties:{}}}function Bc(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function Fc(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 qc(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=ct(t),o=Mn(t),i=r.length>0?r:[{id:e,question:n,options:o,allowsFreeText:!0}],s=i.length>0?0:void 0,l=s!=null?i[s]:void 0,a=l?.options.map(d=>d.label)??o.map(d=>d.label);return{requestId:e,kind:"question",promptText:l?_e(l,s??0,i.length):n,options:a,...i.length>0?{questions:i}:{},...s!=null?{activeQuestionIndex:s}:{},allowsFreeText:!0}}function Kc(t,e,n){let r=t.questions??[],o=r[e],i=o?.options.map(s=>s.label)??[];return{...t,promptText:o?_e(o,e,r.length):t.promptText,options:i,activeQuestionIndex:e,answers:n}}function Uc(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
+ ${v}`:""}`},k=()=>{gt(a)};if(t.signal?.aborted)throw await gt(a),new Error(`OpenCode server startup aborted before readiness.${h()}`);t.signal?.addEventListener("abort",k,{once:!0});try{let v=Date.now();for(;Date.now()-v<l;){if(t.signal?.aborted)throw await gt(a),new Error(`OpenCode server startup aborted before readiness.${h()}`);if(m)throw new Error(`OpenCode server failed to start: ${m.message}${h()}`);if(a.exitCode!==null)throw new Error(`OpenCode server exited before readiness.${h()}`);try{if(await Uc({baseUrl:d,fetchImpl:i,requestTimeoutMs:s,startupSignal:t.signal,timeoutMessage:`OpenCode GET /api/health timed out after ${s}ms during server readiness.${h()}`,abortMessage:`OpenCode server startup aborted before readiness.${h()}`}))return{baseUrl:d,close:async()=>{await gt(a)}}}catch{if(t.signal?.aborted)throw await gt(a),new Error(`OpenCode server startup aborted before readiness.${h()}`)}await ra(100)}throw await gt(a),new Error(`Timed out waiting for OpenCode server readiness.${h()}`)}finally{t.signal?.removeEventListener("abort",k)}})}async function Kc(t){for(let e=1;;e+=1)try{return await qc(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(ht(n)))throw n}}async function Uc(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await qn(t.fetchImpl(`${t.baseUrl}/api/health`,{headers:Yo(),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 Vc(t){let e=ne(t)&&ne(t.payload)?t.payload:t;return ne(e)?e.type==="sync"?{type:typeof e.name=="string"?e.name.replace(/\.\d+$/,""):void 0,properties:ne(e.data)?e.data:{}}:{type:typeof e.type=="string"?e.type:void 0,properties:ne(e.properties)?e.properties:e}:{properties:{}}}function Gc(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function jc(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 Hc(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=ct(t),o=Mn(t),i=r.length>0?r:[{id:e,question:n,options:o,allowsFreeText:!0}],s=i.length>0?0:void 0,l=s!=null?i[s]:void 0,a=l?.options.map(d=>d.label)??o.map(d=>d.label);return{requestId:e,kind:"question",promptText:l?_e(l,s??0,i.length):n,options:a,...i.length>0?{questions:i}:{},...s!=null?{activeQuestionIndex:s}:{},allowsFreeText:!0}}function zc(t,e,n){let r=t.questions??[],o=r[e],i=o?.options.map(s=>s.label)??[];return{...t,promptText:o?_e(o,e,r.length):t.promptText,options:i,activeQuestionIndex:e,answers:n}}function Qc(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 Vc(t){return ti(t).result}function ti(t){let e=Array.isArray(t)?t:ne(t)&&Array.isArray(t.messages)?t.messages:ne(t)&&Array.isArray(t.items)?t.items:[],n=[];for(let r of e){let o=ne(r)&&ne(r.info)?r.info:r;if(!ne(o)||(typeof o.role=="string"?o.role:o.type)!=="assistant")continue;let s=Array.isArray(o.content)?o.content:[],l=ne(r)&&Array.isArray(r.parts)?r.parts:[];for(let a of[...s,...l])ne(a)&&a.type==="text"&&typeof a.text=="string"&&n.push(a.text)}return{count:n.length,result:n.at(-1)}}var yc,kc,ni,Sc,vc,Zo,Zs,ei,Kn,na=Q(()=>{Qt();Dn();yc="OPENCLAW_OPENCODE_COMMAND",kc=15e3,ni=6e4,Sc=15*6e4,vc=["edit","bash","task","todowrite","external_directory"];Zo=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};Zs=Promise.resolve();ei=class{constructor(e,n,r=ni){this.baseUrl=e;this.fetchImpl=n;this.requestTimeoutMs=r}baseUrl;fetchImpl;requestTimeoutMs;async request(e,n,r,o={}){let i=new AbortController,s=!1,l=!1,a=o.timeoutMs??this.requestTimeoutMs,d=`OpenCode ${e} ${n} timed out after ${a}ms.`,u=`OpenCode ${e} ${n} was aborted.`,c=()=>{s=!0,i.abort()};o.signal?.aborted?(s=!0,i.abort()):o.signal?.addEventListener("abort",c,{once:!0});try{let m=await qn(this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:{...Yo(),...r===void 0?{}:{"content-type":"application/json"}},body:r===void 0?void 0:JSON.stringify(r),signal:i.signal}),{timeoutMs:a,timeoutMessage:d,signal:o.signal,abortMessage:u,onTimeout:()=>{l=!0,i.abort()}});if(!m.ok){let h=await qn(m.text(),{timeoutMs:a,timeoutMessage:d,signal:o.signal,abortMessage:u,onTimeout:()=>{l=!0,i.abort()}}).catch(()=>"");throw new Zo(e,n,m.status,Xo(h))}if(m.status===204)return;let p=await qn(m.text(),{timeoutMs:a,timeoutMessage:d,signal:o.signal,abortMessage:u,onTimeout:()=>{l=!0,i.abort()}});if(!p)return;let f=Tc(m);if(!f.includes("application/json")&&!f.includes("+json"))throw new Error(Mc(e,n,f,p));try{return JSON.parse(p)}catch(h){let k=Xo(p);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${ht(h)}${k?`: ${k}`:""}`)}}catch(m){if(i.signal.aborted){if(l)throw new Error(`OpenCode ${e} ${n} timed out after ${a}ms.`);if(s)throw new Error(`OpenCode ${e} ${n} was aborted.`)}throw m}finally{o.signal?.removeEventListener("abort",c)}}async streamEvents(e,n){let r=await this.fetchImpl(`${this.baseUrl}/event`,{headers:Yo(),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="",l=async d=>{let u=d.split(/\r?\n/).filter(c=>c.startsWith("data:")).map(c=>c.slice(5).trimStart()).join(`
13
- `).trim();!u||u==="[DONE]"||await e(JSON.parse(u))};for(;;){let{done:d,value:u}=await o.read();if(d)break;s+=i.decode(u,{stream:!0});let c=/\r?\n\r?\n/.exec(s);for(;c;){let m=s.slice(0,c.index);s=s.slice(c.index+c[0].length),await l(m),c=/\r?\n\r?\n/.exec(s)}}let a=s.trim();a&&await l(a)}};Kn=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 Be,r=this.deps.fetch??fetch,o,i,s,l=e.resumeSessionId,a=0,d=e.permissionMode??"default",u,c=!e.resumeSessionId,m=!1,p=!1,f=new AbortController,h,k=!1,v=!1,I=!1,x=!1,w=!1,A=!1,y,b=new Set,V=M=>x?!1:(x=!0,n.enqueue($e(M)),!0),E=(M,R,_)=>V({success:M,outcome:R,duration_ms:0,total_cost_usd:0,num_turns:a,result:_,session_id:l??""}),T=()=>{l&&y!==l&&(y=l,n.enqueue(pt({kind:"opencode-server",conversationId:l})))},C=M=>{M&&b.has(M)||(M&&b.add(M),n.enqueue(Fe(M)),M&&u?.requestId===M&&(u=void 0))},F=async()=>{if(i)return i;s??=(async()=>{let M=await(this.deps.createServer??Wc)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(w||e.abortController?.signal.aborted)throw await M.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=M,i=new ei(M.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(M){throw s=void 0,M}},Y=async(M,R)=>{!i||!l||await i.request("POST",`/permission/${encodeURIComponent(M)}/reply`,{reply:R})},W=async(M,R)=>{!i||!l||await i.request("POST",`/question/${encodeURIComponent(M)}/reply`,{answers:[[R]]})},N=async M=>{let R=Lc(M),_=Bc(R.properties);if(!(_&&_!==l)){if((R.type==="session.next.text.delta"||R.type==="message.part.delta")&&R.properties.field!=="reasoning"&&typeof R.properties.delta=="string"){n.enqueue(Qe(R.properties.delta));return}if(R.type==="session.next.tool.called"||R.type==="message.part.updated"){let O=ne(R.properties.part)?R.properties.part:void 0;if(R.type==="message.part.updated"&&O?.type!=="tool"){n.enqueue({type:"activity"});return}let ee=typeof R.properties.tool=="string"?R.properties.tool:typeof O?.tool=="string"?O.tool:"tool";n.enqueue($n(ee,R.properties.input));return}if(R.type==="session.next.step.failed"||R.type==="session.error"){let O=ne(R.properties.error)&&typeof R.properties.error.message=="string"?R.properties.error.message:`${R.type} failed`;v&&!I&&(h?.abort(),E(!1,"failed",O));return}if(R.type==="permission.asked"){if(d==="bypassPermissions"){let ee=typeof R.properties.id=="string"?R.properties.id:void 0;ee&&(await Y(ee,"once").catch(()=>{}),C(ee));return}let O=Fc(R.properties);u={requestId:O.requestId,kind:"approval",options:O.options,actions:O.actions??[],state:O},n.enqueue(xe(O));return}if(R.type==="permission.replied"){let O=typeof R.properties.requestID=="string"?R.properties.requestID:void 0;C(O);return}if(R.type==="question.asked"){let O=qc(R.properties);u={requestId:O.requestId,kind:"question",options:O.options,actions:[],state:O},n.enqueue(xe(O));return}if(R.type==="question.replied"||R.type==="question.rejected"){let O=typeof R.properties.requestID=="string"?R.properties.requestID:void 0;C(O);return}(R.type?.startsWith("session.next.")||R.type?.startsWith("message.")||R.type==="session.status"||R.type==="session.idle")&&(Ec(R)&&(A=!0),n.enqueue({type:"activity"}))}},oe=()=>{k||!i||(k=!0,i.streamEvents(N,f.signal).catch(M=>{!f.signal.aborted&&v&&!I&&(h?.abort(),E(!1,"failed",ht(M)))}).finally(()=>{k=!1}))},fe=async(M,R)=>await M.request("GET",`/session/${encodeURIComponent(R)}/message`),it=async(M,R,_,O,ee)=>{await M.request("POST",`/session/${encodeURIComponent(R)}/prompt_async`,_c(_,e.model,O),{signal:ee})},qt=async(M,R,_,O)=>{let ee=Date.now(),Ie=!1,ge=_,Oe,st=0,We,Ss=this.deps.turnTimeoutMs??Sc;for(;;){if(O.aborted)throw new Error("wait aborted");let Su=await fe(M,R).catch(()=>{}),Ne=ti(Su),vs=Ne.count>_&&!!Ne.result;vs&&Ne.count===ge&&Ne.result===Oe?st+=1:(st=vs?1:0,ge=Ne.count,Oe=Ne.result);let Oo=!1;try{let Kt=await M.request("GET","/session/status",void 0,{signal:O,timeoutMs:Math.min(this.deps.requestTimeoutMs??ni,1e4)});Oo=$c(Kt,R),We=void 0,Oo||(Ie=!0)}catch(Kt){if(O.aborted)throw new Error("wait aborted");We=ht(Kt)}if(Oo&&(Ie||Ne.count>_)||A&&Ne.count>_||st>=2&&We)return;if(Date.now()-ee>Ss){let Kt=We?` Last status error: ${We}`:"";throw new Error(`Timed out waiting for OpenCode session ${R} to become idle after ${Ss}ms.${Kt}`)}await ta(250)}},In=async()=>{let M=await F();if(l){if(e.forkSession&&!m){let O=await M.request("POST",`/session/${encodeURIComponent(l)}/fork`,{});if(!O.id)throw new Error("OpenCode fork did not return a session id.");l=O.id,m=!0,c=!0}else c||(await fe(M,l),c=!0);return T(),oe(),l}let R=Ic(e.model),_=await M.request("POST","/session",{...R?{model:R}:{},metadata:{client:"openclaw-code-agent"},permission:Ys(d)});if(!_.id)throw new Error("OpenCode did not return a session id.");return l=_.id,c=!0,T(),oe(),l},ks=async(M,R,_=M?"completed":"failed")=>{let O=R;if(M&&i&&l){let ee=await fe(i,l).catch(()=>{});O=O??Vc(ee)}E(M,_,O)},yu=async M=>{v=!0,I=!1,x=!1,A=!1;try{let R=await F();if(w)return;let _=await In();if(w)return;n.enqueue(mt()),a+=1;let O=p?void 0:e.systemPrompt,ee=await fe(R,_).catch(()=>{}),Ie=ti(ee).count,ge=new AbortController;h=ge,await it(R,_,M,O,ge.signal),p=!0,await qt(R,_,Ie,ge.signal),h=void 0,I=!0,await ks(!0)}catch(R){h=void 0,await ks(!1,ht(R))}finally{v=!1,I=!1}},Do=async(M,R={})=>{let _=u;if(!_||_.kind!=="question"||R.requestId&&R.requestId!==_.requestId)return!1;let O=M.trim();if(!O)return!1;let ee=_.state?.questions??[];if(ee.length>0){let Ie=_.state?.activeQuestionIndex??0,ge=ee[Ie];if(!ge||R.questionId&&R.questionId!==ge.id)return!1;_.answers={..._.answers,[ge.id]:{answers:[O]}};let Oe=Ie+1;return Oe<ee.length?(_.state=Kc(_.state,Oe,_.answers),_.options=_.state.options,n.enqueue(xe(_.state)),!0):(await W(_.requestId,Uc(ee,_.answers)),C(_.requestId),!0)}return await W(_.requestId,O),C(_.requestId),!0},ku=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 ku){if(w)break;let R=Ac(M).trim();if(R){if(u?.kind==="question"){await Do(R);continue}if(await yu(R),w)break}}}catch(M){w||(v||(x=!1),E(!1,"failed",ht(M)))}finally{f.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(M){l&&await(await F()).request("PATCH",`/session/${encodeURIComponent(l)}`,{permission:Ys(M)}),d=M,n.enqueue(ft(M))},async submitPendingInputOption(M,R={}){let _=u;if(!_||R.requestId&&R.requestId!==_.requestId)return!1;if(_.kind==="approval"){let st=_.actions[M],We=st?.kind==="approval"?st.responseDecision:void 0;return We?(await Y(_.requestId,We),C(_.requestId),!0):!1}let O=_.state?.questions??[],ee=_.state?.activeQuestionIndex??0,Ie=O[ee];if(R.questionId&&R.questionId!==Ie?.id)return!1;let ge=Ie?.options[M],Oe=ge?.value??ge?.label??_.options[M];return Oe?await Do(Oe,R):!1},async submitPendingInputText(M){return await Do(M)},async interrupt(){if(w=!0,f.abort(),h?.abort(),v||(x=!1),E(!1,"interrupted"),!i){await o?.close().catch(()=>{});return}if(!l)return;await i.request("POST",`/session/${encodeURIComponent(l)}/abort`).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});function oi(t){ri.set(t.name,t)}function Xt(t){let e=ri.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...ri.keys()].join(", ")}`);return e}function ra(){return Xt(ae())}var ri,ii=Q(()=>{_s();Js();na();ie();ri=new Map;oi(new On);oi(new Fn);oi(new Kn)});function $(t){return t.backendRef?.conversationId??t.harnessSessionId}function K(t){return t.id??t.sessionId??t.name??$(t)??t.harnessSessionId}function Gc(t){return t.harnessSessionId}function ue(t){let e=[K(t),$(t),Gc(t)].filter(n=>!!n);return[...new Set(e)]}function si(t){return t.harnessName??t.persistedHarness??ae()}function en(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return Xt(si(t)).capabilities.worktrees}catch{return"plugin-managed"}}function ai(t){return t==="native-execution"}function Un(t){return t==="native-restore"}function jc(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function le(t){let e=en(t);return(ai(e)||Un(e))&&jc(t)}var Z=Q(()=>{ie();ii()});import{execFileSync as re}from"child_process";import*as ir from"fs";import{tmpdir as wp}from"os";import{dirname as Ia,join as bp}from"path";function Rp(t){try{return re("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function sr(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(D.worktreeDir)return D.worktreeDir;if(t){let e=Rp(t);if(e)return bp(e,".worktrees")}return wp()}function xa(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100).replace(/[-.]+$/,"")||"session"}function ar(t){try{let e=re("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")?Ia(e):void 0}catch{return}}function Ap(){if(rr!==void 0)return rr;try{return re("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),rr=!0,!0}catch{return rr=!1,!1}}function Ae(){if(or!==void 0)return or;try{return re("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),or=!0,!0}catch{return or=!1,!1}}function pi(t){if(!Ap())return!1;try{return re("git",["rev-parse","--git-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Ta(t){try{let e=xp(t);if(!e)return`${sr(t)}`,!0;let n=ir.statfsSync(e),r=n.bavail*n.bsize;return Tp(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function sn(t,e){try{return re("git",["-C",t,"rev-parse","--verify",e],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Ip(t){let e=t;for(;;){if(ir.existsSync(e))return e;let n=Ia(e);if(n===e)return;e=n}}function xp(t){return Ip(sr(t))}function Tp(t){return t>=104857600}function Te(t){let e=process.env.OPENCLAW_WORKTREE_BASE_BRANCH?.trim();if(e)return e;try{let r=re("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 re("git",["-C",t,"rev-parse","--verify","main"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"main"}catch{}try{return re("git",["-C",t,"rev-parse","--verify","master"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"master"}catch{return"main"}}function Pt(t){try{let n=re("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 an(t,e,n){try{let r=re("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 Ca(t,e,n){try{let r=re("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 wt(t,e,n){try{return re("git",["-C",t,"merge-base","--is-ancestor",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Ma(t,e,n){try{let r=re("git",["-C",t,"merge-tree","--write-tree",n,e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),o=re("git",["-C",t,"rev-parse",`${n}^{tree}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return!!r&&r===o}catch{return!1}}function Se(t,e){try{return re("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 _a(t,e){if(e)return e;let n;try{n=re("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}try{let r=re("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 rr,or,bt=Q(()=>{ie()});import{execFileSync as Rt}from"child_process";import{randomBytes as Cp}from"crypto";import{appendFileSync as Mp,existsSync as Da,mkdirSync as $a,readFileSync as _p,rmSync as mi}from"fs";import{relative as $p,sep as Ea}from"path";function Ep(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function Dp(t){try{return Rt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Op(t){return t===0?"":`-${t}-${Cp(8).toString("hex")}`}function Wp(t,e){let n=Dp(t);if(!n)return;let r=$p(n,e);if(!r||r.startsWith("..")||r.includes(`..${Ea}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(Ea).join("/").replace(/\/$/,"")}/`;try{let s=Da(o)?_p(o,"utf-8"):"";s.split(/\r?\n/).map(a=>a.trim()).some(a=>a===i||a===`/${i}`)||Mp(o,`${s.endsWith(`
12
+ `)}function Jc(t){return ti(t).result}function ti(t){let e=Array.isArray(t)?t:ne(t)&&Array.isArray(t.messages)?t.messages:ne(t)&&Array.isArray(t.items)?t.items:[],n=[];for(let r of e){let o=ne(r)&&ne(r.info)?r.info:r;if(!ne(o)||(typeof o.role=="string"?o.role:o.type)!=="assistant")continue;let s=Array.isArray(o.content)?o.content:[],l=ne(r)&&Array.isArray(r.parts)?r.parts:[];for(let a of[...s,...l])ne(a)&&a.type==="text"&&typeof a.text=="string"&&n.push(a.text)}return{count:n.length,result:n.at(-1)}}var bc,Rc,ni,Ac,Ic,Zo,ea,ei,Kn,oa=Q(()=>{Qt();Dn();bc="OPENCLAW_OPENCODE_COMMAND",Rc=15e3,ni=6e4,Ac=15*6e4,Ic=["edit","bash","task","todowrite","external_directory"];Zo=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};ea=Promise.resolve();ei=class{constructor(e,n,r=ni){this.baseUrl=e;this.fetchImpl=n;this.requestTimeoutMs=r}baseUrl;fetchImpl;requestTimeoutMs;async request(e,n,r,o={}){let i=new AbortController,s=!1,l=!1,a=o.timeoutMs??this.requestTimeoutMs,d=`OpenCode ${e} ${n} timed out after ${a}ms.`,u=`OpenCode ${e} ${n} was aborted.`,c=()=>{s=!0,i.abort()};o.signal?.aborted?(s=!0,i.abort()):o.signal?.addEventListener("abort",c,{once:!0});try{let m=await qn(this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:{...Yo(),...r===void 0?{}:{"content-type":"application/json"}},body:r===void 0?void 0:JSON.stringify(r),signal:i.signal}),{timeoutMs:a,timeoutMessage:d,signal:o.signal,abortMessage:u,onTimeout:()=>{l=!0,i.abort()}});if(!m.ok){let h=await qn(m.text(),{timeoutMs:a,timeoutMessage:d,signal:o.signal,abortMessage:u,onTimeout:()=>{l=!0,i.abort()}}).catch(()=>"");throw new Zo(e,n,m.status,Xo(h))}if(m.status===204)return;let p=await qn(m.text(),{timeoutMs:a,timeoutMessage:d,signal:o.signal,abortMessage:u,onTimeout:()=>{l=!0,i.abort()}});if(!p)return;let f=Dc(m);if(!f.includes("application/json")&&!f.includes("+json"))throw new Error(Wc(e,n,f,p));try{return JSON.parse(p)}catch(h){let k=Xo(p);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${ht(h)}${k?`: ${k}`:""}`)}}catch(m){if(i.signal.aborted){if(l)throw new Error(`OpenCode ${e} ${n} timed out after ${a}ms.`);if(s)throw new Error(`OpenCode ${e} ${n} was aborted.`)}throw m}finally{o.signal?.removeEventListener("abort",c)}}async streamEvents(e,n){let r=await this.fetchImpl(`${this.baseUrl}/event`,{headers:Yo(),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="",l=async d=>{let u=d.split(/\r?\n/).filter(c=>c.startsWith("data:")).map(c=>c.slice(5).trimStart()).join(`
13
+ `).trim();!u||u==="[DONE]"||await e(JSON.parse(u))};for(;;){let{done:d,value:u}=await o.read();if(d)break;s+=i.decode(u,{stream:!0});let c=/\r?\n\r?\n/.exec(s);for(;c;){let m=s.slice(0,c.index);s=s.slice(c.index+c[0].length),await l(m),c=/\r?\n\r?\n/.exec(s)}}let a=s.trim();a&&await l(a)}};Kn=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 Be,r=this.deps.fetch??fetch,o,i,s,l=e.resumeSessionId,a=0,d=e.permissionMode??"default",u,c=!e.resumeSessionId,m=!1,p=!1,f=new AbortController,h,k=!1,v=!1,I=!1,x=!1,w=!1,A=!1,y,b=new Set,V=M=>x?!1:(x=!0,n.enqueue($e(M)),!0),E=(M,R,_)=>V({success:M,outcome:R,duration_ms:0,total_cost_usd:0,num_turns:a,result:_,session_id:l??""}),T=()=>{l&&y!==l&&(y=l,n.enqueue(pt({kind:"opencode-server",conversationId:l})))},C=M=>{M&&b.has(M)||(M&&b.add(M),n.enqueue(Fe(M)),M&&u?.requestId===M&&(u=void 0))},F=async()=>{if(i)return i;s??=(async()=>{let M=await(this.deps.createServer??Kc)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(w||e.abortController?.signal.aborted)throw await M.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=M,i=new ei(M.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(M){throw s=void 0,M}},Y=async(M,R)=>{!i||!l||await i.request("POST",`/permission/${encodeURIComponent(M)}/reply`,{reply:R})},W=async(M,R)=>{!i||!l||await i.request("POST",`/question/${encodeURIComponent(M)}/reply`,{answers:[[R]]})},N=async M=>{let R=Vc(M),_=Gc(R.properties);if(!(_&&_!==l)){if((R.type==="session.next.text.delta"||R.type==="message.part.delta")&&R.properties.field!=="reasoning"&&typeof R.properties.delta=="string"){n.enqueue(Qe(R.properties.delta));return}if(R.type==="session.next.tool.called"||R.type==="message.part.updated"){let O=ne(R.properties.part)?R.properties.part:void 0;if(R.type==="message.part.updated"&&O?.type!=="tool"){n.enqueue({type:"activity"});return}let ee=typeof R.properties.tool=="string"?R.properties.tool:typeof O?.tool=="string"?O.tool:"tool";n.enqueue($n(ee,R.properties.input));return}if(R.type==="session.next.step.failed"||R.type==="session.error"){let O=ne(R.properties.error)&&typeof R.properties.error.message=="string"?R.properties.error.message:`${R.type} failed`;v&&!I&&(h?.abort(),E(!1,"failed",O));return}if(R.type==="permission.asked"){if(d==="bypassPermissions"){let ee=typeof R.properties.id=="string"?R.properties.id:void 0;ee&&(await Y(ee,"once").catch(()=>{}),C(ee));return}let O=jc(R.properties);u={requestId:O.requestId,kind:"approval",options:O.options,actions:O.actions??[],state:O},n.enqueue(xe(O));return}if(R.type==="permission.replied"){let O=typeof R.properties.requestID=="string"?R.properties.requestID:void 0;C(O);return}if(R.type==="question.asked"){let O=Hc(R.properties);u={requestId:O.requestId,kind:"question",options:O.options,actions:[],state:O},n.enqueue(xe(O));return}if(R.type==="question.replied"||R.type==="question.rejected"){let O=typeof R.properties.requestID=="string"?R.properties.requestID:void 0;C(O);return}(R.type?.startsWith("session.next.")||R.type?.startsWith("message.")||R.type==="session.status"||R.type==="session.idle")&&(Bc(R)&&(A=!0),n.enqueue({type:"activity"}))}},oe=()=>{k||!i||(k=!0,i.streamEvents(N,f.signal).catch(M=>{!f.signal.aborted&&v&&!I&&(h?.abort(),E(!1,"failed",ht(M)))}).finally(()=>{k=!1}))},fe=async(M,R)=>await M.request("GET",`/session/${encodeURIComponent(R)}/message`),it=async(M,R,_,O,ee)=>{await M.request("POST",`/session/${encodeURIComponent(R)}/prompt_async`,Nc(_,e.model,O),{signal:ee})},qt=async(M,R,_,O)=>{let ee=Date.now(),Ie=!1,ge=_,Oe,st=0,We,vs=this.deps.turnTimeoutMs??Ac;for(;;){if(O.aborted)throw new Error("wait aborted");let Pu=await fe(M,R).catch(()=>{}),Ne=ti(Pu),Ps=Ne.count>_&&!!Ne.result;Ps&&Ne.count===ge&&Ne.result===Oe?st+=1:(st=Ps?1:0,ge=Ne.count,Oe=Ne.result);let Oo=!1;try{let Kt=await M.request("GET","/session/status",void 0,{signal:O,timeoutMs:Math.min(this.deps.requestTimeoutMs??ni,1e4)});Oo=Lc(Kt,R),We=void 0,Oo||(Ie=!0)}catch(Kt){if(O.aborted)throw new Error("wait aborted");We=ht(Kt)}if(Oo&&(Ie||Ne.count>_)||A&&Ne.count>_||st>=2&&We)return;if(Date.now()-ee>vs){let Kt=We?` Last status error: ${We}`:"";throw new Error(`Timed out waiting for OpenCode session ${R} to become idle after ${vs}ms.${Kt}`)}await ra(250)}},In=async()=>{let M=await F();if(l){if(e.forkSession&&!m){let O=await M.request("POST",`/session/${encodeURIComponent(l)}/fork`,{});if(!O.id)throw new Error("OpenCode fork did not return a session id.");l=O.id,m=!0,c=!0}else c||(await fe(M,l),c=!0);return T(),oe(),l}let R=$c(e.model),_=await M.request("POST","/session",{...R?{model:R}:{},metadata:{client:"openclaw-code-agent"},permission:Xs(d)});if(!_.id)throw new Error("OpenCode did not return a session id.");return l=_.id,c=!0,T(),oe(),l},Ss=async(M,R,_=M?"completed":"failed")=>{let O=R;if(M&&i&&l){let ee=await fe(i,l).catch(()=>{});O=O??Jc(ee)}E(M,_,O)},Su=async M=>{v=!0,I=!1,x=!1,A=!1;try{let R=await F();if(w)return;let _=await In();if(w)return;n.enqueue(mt()),a+=1;let O=p?void 0:e.systemPrompt,ee=await fe(R,_).catch(()=>{}),Ie=ti(ee).count,ge=new AbortController;h=ge,await it(R,_,M,O,ge.signal),p=!0,await qt(R,_,Ie,ge.signal),h=void 0,I=!0,await Ss(!0)}catch(R){h=void 0,await Ss(!1,ht(R))}finally{v=!1,I=!1}},Do=async(M,R={})=>{let _=u;if(!_||_.kind!=="question"||R.requestId&&R.requestId!==_.requestId)return!1;let O=M.trim();if(!O)return!1;let ee=_.state?.questions??[];if(ee.length>0){let Ie=_.state?.activeQuestionIndex??0,ge=ee[Ie];if(!ge||R.questionId&&R.questionId!==ge.id)return!1;_.answers={..._.answers,[ge.id]:{answers:[O]}};let Oe=Ie+1;return Oe<ee.length?(_.state=zc(_.state,Oe,_.answers),_.options=_.state.options,n.enqueue(xe(_.state)),!0):(await W(_.requestId,Qc(ee,_.answers)),C(_.requestId),!0)}return await W(_.requestId,O),C(_.requestId),!0},vu=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 vu){if(w)break;let R=_c(M).trim();if(R){if(u?.kind==="question"){await Do(R);continue}if(await Su(R),w)break}}}catch(M){w||(v||(x=!1),E(!1,"failed",ht(M)))}finally{f.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(M){l&&await(await F()).request("PATCH",`/session/${encodeURIComponent(l)}`,{permission:Xs(M)}),d=M,n.enqueue(ft(M))},async submitPendingInputOption(M,R={}){let _=u;if(!_||R.requestId&&R.requestId!==_.requestId)return!1;if(_.kind==="approval"){let st=_.actions[M],We=st?.kind==="approval"?st.responseDecision:void 0;return We?(await Y(_.requestId,We),C(_.requestId),!0):!1}let O=_.state?.questions??[],ee=_.state?.activeQuestionIndex??0,Ie=O[ee];if(R.questionId&&R.questionId!==Ie?.id)return!1;let ge=Ie?.options[M],Oe=ge?.value??ge?.label??_.options[M];return Oe?await Do(Oe,R):!1},async submitPendingInputText(M){return await Do(M)},async interrupt(){if(w=!0,f.abort(),h?.abort(),v||(x=!1),E(!1,"interrupted"),!i){await o?.close().catch(()=>{});return}if(!l)return;await i.request("POST",`/session/${encodeURIComponent(l)}/abort`).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});function oi(t){ri.set(t.name,t)}function Xt(t){let e=ri.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...ri.keys()].join(", ")}`);return e}function ia(){return Xt(ae())}var ri,ii=Q(()=>{$s();Zs();oa();ie();ri=new Map;oi(new On);oi(new Fn);oi(new Kn)});function $(t){return t.backendRef?.conversationId??t.harnessSessionId}function K(t){return t.id??t.sessionId??t.name??$(t)??t.harnessSessionId}function Yc(t){return t.harnessSessionId}function ue(t){let e=[K(t),$(t),Yc(t)].filter(n=>!!n);return[...new Set(e)]}function si(t){return t.harnessName??t.persistedHarness??ae()}function en(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return Xt(si(t)).capabilities.worktrees}catch{return"plugin-managed"}}function ai(t){return t==="native-execution"}function Un(t){return t==="native-restore"}function Zc(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function le(t){let e=en(t);return(ai(e)||Un(e))&&Zc(t)}var Z=Q(()=>{ie();ii()});import{execFileSync as re}from"child_process";import*as ir from"fs";import{tmpdir as Tp}from"os";import{dirname as Ta,join as Cp}from"path";function Mp(t){try{return re("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function sr(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(D.worktreeDir)return D.worktreeDir;if(t){let e=Mp(t);if(e)return Cp(e,".worktrees")}return Tp()}function Ca(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100).replace(/[-.]+$/,"")||"session"}function ar(t){try{let e=re("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")?Ta(e):void 0}catch{return}}function _p(){if(rr!==void 0)return rr;try{return re("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),rr=!0,!0}catch{return rr=!1,!1}}function Ae(){if(or!==void 0)return or;try{return re("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),or=!0,!0}catch{return or=!1,!1}}function pi(t){if(!_p())return!1;try{return re("git",["rev-parse","--git-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Ma(t){try{let e=Ep(t);if(!e)return`${sr(t)}`,!0;let n=ir.statfsSync(e),r=n.bavail*n.bsize;return Dp(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function sn(t,e){try{return re("git",["-C",t,"rev-parse","--verify",e],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function $p(t){let e=t;for(;;){if(ir.existsSync(e))return e;let n=Ta(e);if(n===e)return;e=n}}function Ep(t){return $p(sr(t))}function Dp(t){return t>=104857600}function Te(t){let e=process.env.OPENCLAW_WORKTREE_BASE_BRANCH?.trim();if(e)return e;try{let r=re("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 re("git",["-C",t,"rev-parse","--verify","main"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"main"}catch{}try{return re("git",["-C",t,"rev-parse","--verify","master"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"master"}catch{return"main"}}function Pt(t){try{let n=re("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 an(t,e,n){try{let r=re("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 _a(t,e,n){try{let r=re("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 wt(t,e,n){try{return re("git",["-C",t,"merge-base","--is-ancestor",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function $a(t,e,n){try{let r=re("git",["-C",t,"merge-tree","--write-tree",n,e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),o=re("git",["-C",t,"rev-parse",`${n}^{tree}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return!!r&&r===o}catch{return!1}}function Se(t,e){try{return re("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 Ea(t,e){if(e)return e;let n;try{n=re("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}try{let r=re("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 rr,or,bt=Q(()=>{ie()});import{execFileSync as Rt}from"child_process";import{randomBytes as Op}from"crypto";import{appendFileSync as Wp,existsSync as Wa,mkdirSync as Da,readFileSync as Np,rmSync as mi}from"fs";import{relative as Lp,sep as Oa}from"path";function Bp(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function Fp(t){try{return Rt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function qp(t){return t===0?"":`-${t}-${Op(8).toString("hex")}`}function Kp(t,e){let n=Fp(t);if(!n)return;let r=Lp(n,e);if(!r||r.startsWith("..")||r.includes(`..${Oa}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(Oa).join("/").replace(/\/$/,"")}/`;try{let s=Wa(o)?Np(o,"utf-8"):"";s.split(/\r?\n/).map(a=>a.trim()).some(a=>a===i||a===`/${i}`)||Wp(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 fi(t,e,n={}){let r=xa(e),o=sr(t);Wp(t,o),$a(o,{recursive:!0});let i=n.allowExistingBranch===!0,s,l,a=10,d=!1;for(let c=0;c<a;c++){let m=Op(c),p=`${o}/openclaw-worktree-${r}${m}`,f=`agent/${r}${m}`;if(!i&&sn(t,f))continue;let h=!1;do{h=!1;try{$a(p,{recursive:!1}),s=p,l=f;break}catch(k){if(Ep(k,"EEXIST")){if(i&&c===0&&!d)try{mi(p,{recursive:!0,force:!0}),d=!0,h=!0}catch(v){throw new Error(`Failed to recreate existing worktree branch ${f}: could not clear blocked path ${p}: ${v instanceof Error?v.message:String(v)}`)}else if(i&&c===0)throw new Error(`Failed to recreate existing worktree branch ${f}: path ${p} remains blocked after one cleanup attempt`);continue}throw k}}while(h);if(s&&l)break}if(!s||!l)throw new Error(`Failed to create unique worktree directory and branch after ${a} attempts`);let u=sn(t,l);try{u?Rt("git",["-C",t,"worktree","add",s,l],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):Rt("git",["-C",t,"worktree","add","-b",l,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{mi(s,{recursive:!0,force:!0})}catch{}throw c}return s}function Xe(t){if(!Da(t))return[];try{let e=Rt("git",["-C",t,"status","--porcelain","--untracked-files=all"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e?e.split(`
17
- `).map(n=>n.trim()).filter(Boolean):[]}catch{return[]}}function At(t){return Xe(t).length>0}function ce(t,e,n={}){let r=n.destructive===!0,o=Xe(e);if(o.length>0&&!r)return`${e}${o[0]}`,!1;try{return Rt("git",["-C",t,"worktree","remove",...r?["--force"]:[],e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(i){if(`${e}${i instanceof Error?i.message:String(i)}`,!r)return!1;try{return mi(e,{recursive:!0,force:!0}),`${e}`,!0}catch(s){return console.error(`[worktree] Both git worktree remove and rmSync failed for ${e}: ${s instanceof Error?s.message:String(s)}`),!1}}}function lr(t){try{Rt("git",["-C",t,"worktree","prune"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(e){let n=e instanceof Error?e.message.split(/\r?\n/,1)[0]:String(e);`${t}${n}`}}var gi=Q(()=>{bt()});import{execFileSync as H}from"child_process";import{existsSync as Np}from"fs";function It(t){return(t.warnings??[]).filter(e=>!(t.stashPopConflict&&e.startsWith("Failed to pop auto-stash after merge"))).map(e=>`Recovery warning: ${e}`)}function Ce(t,e){let n=It(e);return n.length===0?t:`${t}
16
+ `,"utf-8")}catch(s){`${i}${o}${s instanceof Error?s.message:String(s)}`}}function fi(t,e,n={}){let r=Ca(e),o=sr(t);Kp(t,o),Da(o,{recursive:!0});let i=n.allowExistingBranch===!0,s,l,a=10,d=!1;for(let c=0;c<a;c++){let m=qp(c),p=`${o}/openclaw-worktree-${r}${m}`,f=`agent/${r}${m}`;if(!i&&sn(t,f))continue;let h=!1;do{h=!1;try{Da(p,{recursive:!1}),s=p,l=f;break}catch(k){if(Bp(k,"EEXIST")){if(i&&c===0&&!d)try{mi(p,{recursive:!0,force:!0}),d=!0,h=!0}catch(v){throw new Error(`Failed to recreate existing worktree branch ${f}: could not clear blocked path ${p}: ${v instanceof Error?v.message:String(v)}`)}else if(i&&c===0)throw new Error(`Failed to recreate existing worktree branch ${f}: path ${p} remains blocked after one cleanup attempt`);continue}throw k}}while(h);if(s&&l)break}if(!s||!l)throw new Error(`Failed to create unique worktree directory and branch after ${a} attempts`);let u=sn(t,l);try{u?Rt("git",["-C",t,"worktree","add",s,l],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):Rt("git",["-C",t,"worktree","add","-b",l,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{mi(s,{recursive:!0,force:!0})}catch{}throw c}return s}function Xe(t){if(!Wa(t))return[];try{let e=Rt("git",["-C",t,"status","--porcelain","--untracked-files=all"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e?e.split(`
17
+ `).map(n=>n.trim()).filter(Boolean):[]}catch{return[]}}function At(t){return Xe(t).length>0}function ce(t,e,n={}){let r=n.destructive===!0,o=Xe(e);if(o.length>0&&!r)return`${e}${o[0]}`,!1;try{return Rt("git",["-C",t,"worktree","remove",...r?["--force"]:[],e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(i){if(`${e}${i instanceof Error?i.message:String(i)}`,!r)return!1;try{return mi(e,{recursive:!0,force:!0}),`${e}`,!0}catch(s){return console.error(`[worktree] Both git worktree remove and rmSync failed for ${e}: ${s instanceof Error?s.message:String(s)}`),!1}}}function lr(t){try{Rt("git",["-C",t,"worktree","prune"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(e){let n=e instanceof Error?e.message.split(/\r?\n/,1)[0]:String(e);`${t}${n}`}}var gi=Q(()=>{bt()});import{execFileSync as H}from"child_process";import{existsSync as Up}from"fs";function It(t){return(t.warnings??[]).filter(e=>!(t.stashPopConflict&&e.startsWith("Failed to pop auto-stash after merge"))).map(e=>`Recovery warning: ${e}`)}function Ce(t,e){let n=It(e);return n.length===0?t:`${t}
18
18
  ${n.map(r=>`⚠️ ${r}`).join(`
19
19
  `)}`}function dr(t){return t instanceof Error?t.message:String(t)}function Ee(t,e,n){try{let r=H("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10),s=H("git",["-C",t,"diff","--shortstat",`${n}...${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),l=0,a=0,d=0,u=s.match(/(\d+)\s+files?\s+changed/);u&&(l=parseInt(u[1],10));let c=s.match(/(\d+)\s+insertions?\(/);c&&(a=parseInt(c[1],10));let m=s.match(/(\d+)\s+deletions?\(/);m&&(d=parseInt(m[1],10));let f=H("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(v=>v.trim()).filter(Boolean),k=H("git",["-C",t,"log",`${n}..${e}`,"--format=%h|%s|%an","-n","5"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
21
- `).filter(Boolean).map(v=>{let[I,x,w]=v.split("|");return{hash:I||"",message:x||"",author:w||""}});return{commits:o,filesChanged:l,insertions:a,deletions:d,changedFiles:f,commitMessages:k}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function ur(t,e,n="origin"){try{return H("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 Oa(t){try{return H("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 cr(t,e,n,r="merge",o){let i=!1,s,l=[],a=c=>l.length>0?{...c,warnings:[...l]}:c,d=(c,m)=>{l.push(`${c}: ${dr(m)}`)},u=c=>{if(i)try{H("git",["-C",c,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){d("Failed to pop auto-stash during recovery",m)}};try{if(r==="squash"){if(H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Oa(t)){let h;try{h=H("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(k){return a({success:!1,dirtyError:!0,error:`Auto-stash failed: ${dr(k)}. Commit or stash changes manually, then retry.`})}if(!h.includes("No local changes to save")){i=!0;try{s=H("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(k){d("Failed to determine auto-stash ref",k)}}}H("git",["-C",t,"merge","--squash",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),H("git",["-C",t,"commit","-m",`Squash merge ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let f=!1;if(i)try{H("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(h){f=!0,d("Failed to pop auto-stash after merge",h)}return a({success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:f||void 0})}let c=o&&Np(o),m=c?o:t;if(c||H("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Oa(t)){let f;try{f=H("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(h){try{H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(k){d(`Failed to check out ${n} after auto-stash failure`,k)}return a({success:!1,dirtyError:!0,error:`Auto-stash failed: ${dr(h)}. Commit or stash changes manually, then retry.`})}if(!f.includes("No local changes to save")){i=!0;try{s=H("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(h){d("Failed to determine auto-stash ref",h)}}}try{H("git",["-C",m,"rebase",n],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{try{H("git",["-C",m,"rebase","--abort"],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){d("Failed to abort rebase during recovery",f)}try{H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){d(`Failed to check out ${n} during recovery`,f)}return u(t),a({success:!1,rebaseConflict:!0,stashed:i||void 0,stashRef:s,error:[`Rebase of ${e} onto ${n} hit conflicts.`,"To resolve manually:",` cd ${m}`,` 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
- `)})}H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),H("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let p=!1;if(i)try{H("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){p=!0,d("Failed to pop auto-stash after merge",f)}return a({success:!0,fastForward:!0,stashed:i||void 0,stashRef:s,stashPopConflict:p||void 0})}catch(c){try{H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){d(`Failed to check out ${n} during recovery`,m)}return u(t),a({success:!1,error:dr(c),stashed:i||void 0,stashRef:s})}}var Wa=Q(()=>{});import{execFileSync as ln}from"child_process";function Na(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function La(t,e,n){let r=xt(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 Ba(t){try{return ln("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function Lp(t,e,n){if(!n)return e;let r=Ba(t);return r?`${r}:${e}`:e}function Fa(t,e,n,r,o,i,s={}){if(!Ae())return{success:!1,error:"GitHub CLI (gh) is not available"};let l;try{return l=["pr","create","--base",n],(s.draft??!0)&&l.push("--draft"),i&&l.push("--repo",i),l.push("--head",Lp(t,e,i)),r&&o?l.push("--title",r,"--body",o):l.push("--fill-verbose"),{success:!0,prUrl:ln("gh",l,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}}catch(a){let d=a instanceof Error?a.message:String(a);if(Na(d))return La(t,e,i)??{success:!1,error:d};if((s.draft??!0)&&l&&/draft/i.test(d))try{let u=l.filter(p=>p!=="--draft");return{success:!0,prUrl:ln("gh",u,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),warnings:["Target repo does not support draft PRs; created as regular (non-draft) PR instead."]}}catch(u){let c=u instanceof Error?u.message:String(u);return Na(c)?La(t,e,i)??{success:!1,error:`Draft PR creation failed (${d}); non-draft retry also failed: ${c}`}:{success:!1,error:`Draft PR creation failed (${d}); non-draft retry also failed: ${c}`}}return{success:!1,error:d}}}function xt(t,e,n){if(!Ae())return{exists:!1,state:"none"};try{let r=["pr","list","--head",e,"--state","all","--json","url,number,title,state,headRepositoryOwner,headRefName"];n&&r.push("--repo",n);let i=ln("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),l=n?Ba(t)?.toLowerCase():void 0,a=l?s.find(c=>c.headRefName===e&&c.headRepositoryOwner?.login?.toLowerCase()===l):s[0];if(!a)return{exists:!1,state:"none"};let d=a.state.toLowerCase();return{exists:!0,state:d==="open"?"open":d==="merged"?"merged":d==="closed"?"closed":"none",url:a.url,number:a.number,title:a.title}}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function qa(t,e,n,r){if(!Ae())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),ln("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 et(t){if(t.kind==="merge"){let e=t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:"";return`✅ Merged: ${t.branch} → ${t.base??"main"}${e}`}return t.kind==="pr-updated"?`✅ PR updated: ${t.prUrl??""}`:t.targetRepo?`✅ PR opened against ${t.targetRepo}: ${t.prUrl??""}`:`✅ PR opened: ${t.prUrl??""}`}var hi=Q(()=>{bt()});import{existsSync as yi}from"fs";function Ka(){return new Date().toISOString()}function Bp(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:Ka(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function Fp(t){let e=Ua(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&yi(e)?Te(e):void 0)}function Ua(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function Ke(t,e={}){let n=Bp(t),r=Ka(),o=new Set,i=Ua(t),s=!!(i&&yi(i)),l=!!(t.worktreePath&&yi(t.worktreePath)),a=t.worktreeBranch,d=Fp(t),u=!1,c=!1,m=!1,p=!1,f,h,k=t.worktreePrUrl?"open":"none",v=t.worktreePrUrl,I=t.worktreePrNumber;if(s||o.add("repo_missing"),a||o.add("branch_missing"),!l&&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&&a&&(u=sn(i,a),u||o.add("branch_missing")),l&&t.worktreePath&&(c=At(t.worktreePath),c&&o.add("dirty_worktree_entries")),s&&i&&u&&a&&d){let T=Ca(i,a,d);f=T?.ahead,h=T?.behind,m=wt(i,a,d),m?o.add("topology_merged"):(p=Ma(i,a,d),p&&o.add("merge_noop_content_already_on_base"),!p&&(f??0)>0&&o.add("unique_content"))}else d||o.add("base_branch_missing");if(e.includePrSync&&s&&i&&a){let T=xt(i,a,t.worktreePrTargetRepo??n.targetRepo);k=T.state,v=T.url??v,I=T.number??I}k==="open"&&o.add("pr_open"),k==="merged"&&!m&&!p&&o.add("pr_merged_not_reflected_locally");let x;m?x="merged":p&&(x="released");let w=e.activeSession||c,A=n.state;!w&&x?A=x:!u&&n.state==="pending_decision"&&(A="cleanup_failed");let y=A==="merged"||A==="released",b=e.activeSession||c||!y&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||n.state==="pr_open"||k==="open"||o.has("pr_merged_not_reflected_locally"),V=!b&&(A==="merged"||A==="released"||n.state==="dismissed"||n.state==="no_change"),E={checkedAt:r,repoExists:s,branchExists:u,worktreeExists:l,activeSession:e.activeSession===!0,dirtyTracked:c,topologyMerged:m,releaseNoopMerge:p,branchAheadCount:f,baseAheadCount:h,prState:k,prUrl:v,prNumber:I,reasons:[...o]};return{lifecycle:n,evidence:E,derivedState:A,cleanupSafe:V,preserve:b,reasons:[...o]}}var dn=Q(()=>{bt();hi();gi()});var he=Q(()=>{bt();gi();Wa();hi();dn()});function Pr(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function wr(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:Pr(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function ml(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:Pr(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function Ct(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:Pr(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function fl(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:Pr(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 fn=Q(()=>{});function Mt(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?K(n):r?K(r):void 0;return{activeSession:n,persistedSession:r,persistedRef:o,sessionName:n?.name??r?.name??e,prompt:n?.prompt??r?.prompt,worktreePath:n?.worktreePath??r?.worktreePath,originalWorkdir:n?.originalWorkdir??r?.workdir,branchName:n?.worktreeBranch??r?.worktreeBranch,notificationTarget:n??(r?{id:o??e,name:r.name,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,goalTaskId:r.goalTaskId}:void 0)}}function gn(t){return[...t.persistedSession?ue(t.persistedSession):[],...t.activeSession?ue(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function Mm(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 br(t,e,n={}){let{activeSession:r,persistedSession:o}=Mm(t,e),i=Ke({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 Rr(t){let e=t.list("all").filter(o=>o.worktreePath),n=t.listPersistedSessions().filter(o=>o.worktreePath),r=new Map;for(let o of n){if(!o.worktreePath)continue;let i=$(o),s=o.sessionId??i??o.harnessSessionId;s&&r.set(s,{id:o.sessionId??i??o.harnessSessionId,name:o.name,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,workdir:o.workdir,worktreeMerged:o.worktreeMerged,worktreeMergedAt:o.worktreeMergedAt,worktreePrUrl:o.worktreePrUrl,backendConversationId:i,harnessSessionId:o.harnessSessionId})}for(let o of e)o.worktreePath&&r.set(o.id,{id:o.id,name:o.name,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,workdir:o.originalWorkdir??o.workdir,worktreeMerged:void 0,worktreeMergedAt:void 0,worktreePrUrl:void 0,backendConversationId:$(o),harnessSessionId:o.harnessSessionId});return Array.from(r.values())}function Ar(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function nt(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 Ir(t){switch(t){case"active_session":return"active session";case"pending_decision":return"pending decision";case"merge_conflict_resolving":return"conflict resolving";case"dirty_tracked_changes":case"dirty_worktree_entries":return"dirty worktree";case"unique_content":return"still has unique content";case"topology_merged":return"merged by ancestry";case"merge_noop_content_already_on_base":return"content already on base";case"pr_open":return"PR open";case"pr_merged_not_reflected_locally":return"merged PR not reflected locally";case"repo_missing":return"repo missing";case"branch_missing":return"branch missing";case"worktree_missing":return"worktree missing";case"base_branch_missing":return"base branch missing";default:return t.replaceAll("_"," ")}}var hn=Q(()=>{Z();dn()});function hl(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
21
+ `).filter(Boolean).map(v=>{let[I,x,w]=v.split("|");return{hash:I||"",message:x||"",author:w||""}});return{commits:o,filesChanged:l,insertions:a,deletions:d,changedFiles:f,commitMessages:k}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function ur(t,e,n="origin"){try{return H("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 Na(t){try{return H("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 cr(t,e,n,r="merge",o){let i=!1,s,l=[],a=c=>l.length>0?{...c,warnings:[...l]}:c,d=(c,m)=>{l.push(`${c}: ${dr(m)}`)},u=c=>{if(i)try{H("git",["-C",c,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){d("Failed to pop auto-stash during recovery",m)}};try{if(r==="squash"){if(H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Na(t)){let h;try{h=H("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(k){return a({success:!1,dirtyError:!0,error:`Auto-stash failed: ${dr(k)}. Commit or stash changes manually, then retry.`})}if(!h.includes("No local changes to save")){i=!0;try{s=H("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(k){d("Failed to determine auto-stash ref",k)}}}H("git",["-C",t,"merge","--squash",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),H("git",["-C",t,"commit","-m",`Squash merge ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let f=!1;if(i)try{H("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(h){f=!0,d("Failed to pop auto-stash after merge",h)}return a({success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:f||void 0})}let c=o&&Up(o),m=c?o:t;if(c||H("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Na(t)){let f;try{f=H("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(h){try{H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(k){d(`Failed to check out ${n} after auto-stash failure`,k)}return a({success:!1,dirtyError:!0,error:`Auto-stash failed: ${dr(h)}. Commit or stash changes manually, then retry.`})}if(!f.includes("No local changes to save")){i=!0;try{s=H("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(h){d("Failed to determine auto-stash ref",h)}}}try{H("git",["-C",m,"rebase",n],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{try{H("git",["-C",m,"rebase","--abort"],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){d("Failed to abort rebase during recovery",f)}try{H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){d(`Failed to check out ${n} during recovery`,f)}return u(t),a({success:!1,rebaseConflict:!0,stashed:i||void 0,stashRef:s,error:[`Rebase of ${e} onto ${n} hit conflicts.`,"To resolve manually:",` cd ${m}`,` 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
+ `)})}H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),H("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let p=!1;if(i)try{H("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){p=!0,d("Failed to pop auto-stash after merge",f)}return a({success:!0,fastForward:!0,stashed:i||void 0,stashRef:s,stashPopConflict:p||void 0})}catch(c){try{H("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){d(`Failed to check out ${n} during recovery`,m)}return u(t),a({success:!1,error:dr(c),stashed:i||void 0,stashRef:s})}}var La=Q(()=>{});import{execFileSync as ln}from"child_process";function Ba(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function Fa(t,e,n){let r=xt(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 qa(t){try{return ln("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function Vp(t,e,n){if(!n)return e;let r=qa(t);return r?`${r}:${e}`:e}function Ka(t,e,n,r,o,i,s={}){if(!Ae())return{success:!1,error:"GitHub CLI (gh) is not available"};let l;try{return l=["pr","create","--base",n],(s.draft??!0)&&l.push("--draft"),i&&l.push("--repo",i),l.push("--head",Vp(t,e,i)),r&&o?l.push("--title",r,"--body",o):l.push("--fill-verbose"),{success:!0,prUrl:ln("gh",l,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}}catch(a){let d=a instanceof Error?a.message:String(a);if(Ba(d))return Fa(t,e,i)??{success:!1,error:d};if((s.draft??!0)&&l&&/draft/i.test(d))try{let u=l.filter(p=>p!=="--draft");return{success:!0,prUrl:ln("gh",u,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),warnings:["Target repo does not support draft PRs; created as regular (non-draft) PR instead."]}}catch(u){let c=u instanceof Error?u.message:String(u);return Ba(c)?Fa(t,e,i)??{success:!1,error:`Draft PR creation failed (${d}); non-draft retry also failed: ${c}`}:{success:!1,error:`Draft PR creation failed (${d}); non-draft retry also failed: ${c}`}}return{success:!1,error:d}}}function xt(t,e,n){if(!Ae())return{exists:!1,state:"none"};try{let r=["pr","list","--head",e,"--state","all","--json","url,number,title,state,headRepositoryOwner,headRefName"];n&&r.push("--repo",n);let i=ln("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),l=n?qa(t)?.toLowerCase():void 0,a=l?s.find(c=>c.headRefName===e&&c.headRepositoryOwner?.login?.toLowerCase()===l):s[0];if(!a)return{exists:!1,state:"none"};let d=a.state.toLowerCase();return{exists:!0,state:d==="open"?"open":d==="merged"?"merged":d==="closed"?"closed":"none",url:a.url,number:a.number,title:a.title}}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function Ua(t,e,n,r){if(!Ae())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),ln("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 et(t){if(t.kind==="merge"){let e=t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:"";return`✅ Merged: ${t.branch} → ${t.base??"main"}${e}`}return t.kind==="pr-updated"?`✅ PR updated: ${t.prUrl??""}`:t.targetRepo?`✅ PR opened against ${t.targetRepo}: ${t.prUrl??""}`:`✅ PR opened: ${t.prUrl??""}`}var hi=Q(()=>{bt()});import{existsSync as yi}from"fs";function Va(){return new Date().toISOString()}function Gp(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:Va(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function jp(t){let e=Ga(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&yi(e)?Te(e):void 0)}function Ga(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function Ke(t,e={}){let n=Gp(t),r=Va(),o=new Set,i=Ga(t),s=!!(i&&yi(i)),l=!!(t.worktreePath&&yi(t.worktreePath)),a=t.worktreeBranch,d=jp(t),u=!1,c=!1,m=!1,p=!1,f,h,k=t.worktreePrUrl?"open":"none",v=t.worktreePrUrl,I=t.worktreePrNumber;if(s||o.add("repo_missing"),a||o.add("branch_missing"),!l&&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&&a&&(u=sn(i,a),u||o.add("branch_missing")),l&&t.worktreePath&&(c=At(t.worktreePath),c&&o.add("dirty_worktree_entries")),s&&i&&u&&a&&d){let T=_a(i,a,d);f=T?.ahead,h=T?.behind,m=wt(i,a,d),m?o.add("topology_merged"):(p=$a(i,a,d),p&&o.add("merge_noop_content_already_on_base"),!p&&(f??0)>0&&o.add("unique_content"))}else d||o.add("base_branch_missing");if(e.includePrSync&&s&&i&&a){let T=xt(i,a,t.worktreePrTargetRepo??n.targetRepo);k=T.state,v=T.url??v,I=T.number??I}k==="open"&&o.add("pr_open"),k==="merged"&&!m&&!p&&o.add("pr_merged_not_reflected_locally");let x;m?x="merged":p&&(x="released");let w=e.activeSession||c,A=n.state;!w&&x?A=x:!u&&n.state==="pending_decision"&&(A="cleanup_failed");let y=A==="merged"||A==="released",b=e.activeSession||c||!y&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||n.state==="pr_open"||k==="open"||o.has("pr_merged_not_reflected_locally"),V=!b&&(A==="merged"||A==="released"||n.state==="dismissed"||n.state==="no_change"),E={checkedAt:r,repoExists:s,branchExists:u,worktreeExists:l,activeSession:e.activeSession===!0,dirtyTracked:c,topologyMerged:m,releaseNoopMerge:p,branchAheadCount:f,baseAheadCount:h,prState:k,prUrl:v,prNumber:I,reasons:[...o]};return{lifecycle:n,evidence:E,derivedState:A,cleanupSafe:V,preserve:b,reasons:[...o]}}var dn=Q(()=>{bt();hi();gi()});var he=Q(()=>{bt();gi();La();hi();dn()});function Pr(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function wr(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:Pr(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function gl(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:Pr(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function Ct(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:Pr(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function hl(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:Pr(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 fn=Q(()=>{});function Mt(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?K(n):r?K(r):void 0;return{activeSession:n,persistedSession:r,persistedRef:o,sessionName:n?.name??r?.name??e,prompt:n?.prompt??r?.prompt,worktreePath:n?.worktreePath??r?.worktreePath,originalWorkdir:n?.originalWorkdir??r?.workdir,branchName:n?.worktreeBranch??r?.worktreeBranch,notificationTarget:n??(r?{id:o??e,name:r.name,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,goalTaskId:r.goalTaskId}:void 0)}}function gn(t){return[...t.persistedSession?ue(t.persistedSession):[],...t.activeSession?ue(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function Wm(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 br(t,e,n={}){let{activeSession:r,persistedSession:o}=Wm(t,e),i=Ke({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 Rr(t){let e=t.list("all").filter(o=>o.worktreePath),n=t.listPersistedSessions().filter(o=>o.worktreePath),r=new Map;for(let o of n){if(!o.worktreePath)continue;let i=$(o),s=o.sessionId??i??o.harnessSessionId;s&&r.set(s,{id:o.sessionId??i??o.harnessSessionId,name:o.name,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,workdir:o.workdir,worktreeMerged:o.worktreeMerged,worktreeMergedAt:o.worktreeMergedAt,worktreePrUrl:o.worktreePrUrl,backendConversationId:i,harnessSessionId:o.harnessSessionId})}for(let o of e)o.worktreePath&&r.set(o.id,{id:o.id,name:o.name,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,workdir:o.originalWorkdir??o.workdir,worktreeMerged:void 0,worktreeMergedAt:void 0,worktreePrUrl:void 0,backendConversationId:$(o),harnessSessionId:o.harnessSessionId});return Array.from(r.values())}function Ar(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function nt(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 Ir(t){switch(t){case"active_session":return"active session";case"pending_decision":return"pending decision";case"merge_conflict_resolving":return"conflict resolving";case"dirty_tracked_changes":case"dirty_worktree_entries":return"dirty worktree";case"unique_content":return"still has unique content";case"topology_merged":return"merged by ancestry";case"merge_noop_content_already_on_base":return"content already on base";case"pr_open":return"PR open";case"pr_merged_not_reflected_locally":return"merged PR not reflected locally";case"repo_missing":return"repo missing";case"branch_missing":return"branch missing";case"worktree_missing":return"worktree missing";case"base_branch_missing":return"base branch missing";default:return t.replaceAll("_"," ")}}var hn=Q(()=>{Z();dn()});function kl(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
24
24
  `).split(`
25
25
  `).map(r=>r.trim()).reduce((r,o)=>o?(r.push(o),r):(e.preserveBlankLines&&r[r.length-1]!==""&&r.push(o),r),[]).join(e.preserveBlankLines?`
26
- `:" ").replace(/[ \t]+/g," ").trim()||void 0}function _t(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function kn(t){return t.replace(/\b[A-Za-z0-9_-]*(?:api[_-]?key|token|secret|password|passwd|pwd|credential|credentials|authorization|auth)[A-Za-z0-9_-]*\b\s*[:=]\s*["']?[^"'\s,;)]+/gi,"[redacted credential]").replace(/\b(?:api key|token|secret|password|credential|credentials)\s+\[redacted credential\]/gi,"[redacted credential]").replace(/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{16,}\b/g,"[redacted token]").replace(/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,"[redacted token]").replace(/\bsk-[A-Za-z0-9_-]{20,}\b/g,"[redacted token]").replace(/\bxox[baprs]-[A-Za-z0-9-]{20,}\b/g,"[redacted token]").replace(/\bAKIA[0-9A-Z]{16}\b/g,"[redacted token]").replace(/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{10,}\b/g,"[redacted token]").replace(/\bhttps?:\/\/\S+/gi,"[redacted link]").replace(/\b[A-Z]:\\(?:Users|Documents and Settings)\\[^\s`'")]+/gi,"[redacted path]").replace(/(?:^|[\s(])\/(?:home|Users|var|etc|private|tmp)\/[^\s`'").]+/g,e=>`${e.startsWith(" ")||e.startsWith("(")?e[0]:""}[redacted path]`).replace(new RegExp("\\b[A-Za-z0-9_-]{32,}\\b","g"),"[redacted token]")}function Mr(t){return/\b[A-Za-z0-9_-]*(?:api[_-]?key|token|secret|password|passwd|pwd|credential|credentials|authorization|auth)[A-Za-z0-9_-]*\b\s*[:=]\s*["']?[^"'\s,;)]+/i.test(t)||/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{16,}\b/.test(t)||/\bgithub_pat_[A-Za-z0-9_]{20,}\b/.test(t)||/\bsk-[A-Za-z0-9_-]{20,}\b/.test(t)||/\bxox[baprs]-[A-Za-z0-9-]{20,}\b/.test(t)||/\bAKIA[0-9A-Z]{16}\b/.test(t)||/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{10,}\b/.test(t)||/\bhttps?:\/\/\S+/i.test(t)||/\b[A-Z]:\\(?:Users|Documents and Settings)\\[^\s`'")]+/i.test(t)||/(?:^|[\s(])\/(?:home|Users|var|etc|private|tmp)\/[^\s`'").]+/.test(t)||new RegExp("\\b[A-Za-z0-9_-]{32,}\\b").test(t)}function Dm(t){let e=hl(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=kn(n).replace(/\s+/g," ").trim();return r?_t(r,180):void 0}function yl(t){return kn(t.trim()).replace(/\s+/g," ").trim()}function Om(t,e){return t?.commitMessages.map(n=>yl(n.message)).filter(Boolean).slice(0,e)??[]}function Mi(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function kl(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function Wm(t){let e=Dm(t.prompt),n=t.diffSummary;return{sessionName:t.sessionName,branchName:t.branchName,objective:e,stats:n?{commits:n.commits,filesChanged:n.filesChanged,insertions:n.insertions,deletions:n.deletions}:void 0,changedFiles:n?.changedFiles??[],commitSubjects:Om(n,5),validation:Mi(),notes:kl()}}function Cr(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 Sl(t,e){let n=hl(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 yn(t,e,n){let r=t.toLowerCase();return Sl(e,n.objective).some(o=>r.includes(o))}function gl(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function _i(t,e){let n=new Set(e.changedFiles);if([...t.matchAll(/(?:^|[^\w.-])((?:\.?[\w-][\w.-]*\/)+(?:\.?[\w-][\w.-]*))(?![\w.-])/g)].map(m=>m[1]).some(m=>/\.[A-Za-z0-9]+$/.test(m)&&!n.has(m)))return!0;let o=new Set(e.changedFiles.filter(m=>!m.includes("/"))),i=String.raw`\.[a-z0-9][\w.-]*`,s=t.matchAll(new RegExp(`[\\\`"'](${i})[\\\`"']`,"g"));for(let m of s)if(!o.has(m[1]))return!0;let l=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 m of l)if(!o.has(m[1]))return!0;if(o.size===0)return!1;let a=new Set([...o].map(m=>m.match(/\.([A-Za-z0-9]+)$/)?.[1]?.toLowerCase()).filter(m=>!!m)),d=String.raw`[A-Za-z0-9][\w.-]*\.([A-Za-z0-9]+)`,u=t.matchAll(new RegExp(`[\\\`"'](${d})[\\\`"']`,"g"));for(let m of u){let p=m[1],f=m[2]?.toLowerCase();if(f!==void 0&&a.has(f)&&!o.has(p)&&!gl(p))return!0}return[...t.matchAll(new RegExp(String.raw`\b(?:file|files|path|paths|changed|changes|updated?|updates?|modified?|modifies|touched?|touches|added?|adds?|removed?|removes?|deleted?|deletes?)\s+(?:the\s+)?(${d})\b`,"gi"))].some(m=>{let p=m[1],f=m[2]?.toLowerCase();return f!==void 0&&a.has(f)&&!o.has(p)&&!gl(p)})}function De(t){return kn(t).replace(/\s+/g," ").trim()}function Nm(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||!Cr(r.summary,5,180)||!Cr(r.changes,10,160)||!Cr(r.validation,5,160)||!Cr(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(l=>Mr(l)||yn(l,n,e)))return;let i={title:De(r.title),summary:r.summary.map(De),changes:r.changes.map(De),validation:r.validation.map(De),notes:r.notes.map(De)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(l=>!l||Mr(l)||yn(l,n,e))&&!s.some(l=>_i(l,e)))return i}function Lm(t,e){let n=_t(kn(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),r=_t(`OpenClaw agent changes: ${n}`,90),o=["Deterministic fallback metadata generated because no LLM PR metadata provider is configured.",`Session: ${n}.`,...t.objective?[`Objective: ${t.objective}`]:[],...t.stats?[`Scope: ${t.stats.commits} commits, ${t.stats.filesChanged} files changed (+${t.stats.insertions} / -${t.stats.deletions}).`]:["Scope: Diff summary was unavailable when the PR body was generated."]],i=t.changedFiles.length>0?t.changedFiles.slice(0,10).map(p=>`\`${p}\``):["Review the pushed worktree branch for the full set of changes."],s=t.changedFiles.length>10?[`...and ${t.changedFiles.length-10} more changed files.`]:[],l=["Fallback metadata is conservative; review the diff and CI/checks before marking the draft PR ready.",...t.notes],a={title:r,summary:o,changes:[...i,...s],validation:t.validation,notes:l},d=!1,u=!1,c=p=>{let f=De(p);if(yn(f,e,t)){d=!0;let h=Sl(e,t.objective);for(let k of h){let v=new RegExp(k.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");f=f.replace(v,"[redacted prompt detail]")}f=De(f)}return _i(f,t)&&(u=!0,f="[redacted file reference outside change set]"),f=De(f),(yn(f,e,t)||Mr(f))&&(d=!0,f="[redacted prompt detail]"),f};if(a={title:c(a.title)||_t(`OpenClaw agent changes: ${n}`,90),summary:a.summary.map(c).filter(p=>p&&p.length>0),changes:a.changes.map(c).filter(p=>p&&p.length>0),validation:a.validation.map(c).filter(p=>p&&p.length>0),notes:a.notes.map(c).filter(p=>p&&p.length>0)},a.summary.length===0&&(a.summary=["Deterministic fallback metadata generated because no LLM PR metadata provider is configured."]),a.changes.length===0&&(a.changes=["Review the pushed worktree branch for the full set of changes."]),a.validation.length===0&&(a.validation=Mi()),a.notes.length===0&&(a.notes=kl()),d||u){let p="Some content was stripped from fallback metadata due to safety checks (prompt leak guard or references to files outside the diff).";a.notes.some(f=>f.toLowerCase().includes("stripped")||f.toLowerCase().includes("sanitized"))||(a.notes=[...a.notes,p])}let m=[a.title,...a.summary,...a.changes,...a.validation,...a.notes];if(m.some(p=>!p)||m.some(p=>Mr(p)||yn(p,e,t))||m.some(p=>_i(p,t))){let p=_t(kn(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);a={title:_t(`OpenClaw agent changes: ${p}`,90),summary:["Deterministic fallback metadata (sanitized for safety)."],changes:t.changedFiles.length>0?t.changedFiles.slice(0,5).map(f=>`\`${f}\``):["See the worktree branch diff for the full set of changes."],validation:Mi(),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 p=De(t.branchName);a.notes.some(f=>f.toLowerCase().includes(p.toLowerCase()))||(a.notes=[...a.notes,`Branch: ${p}`])}return a}async function _r(t){let e=Wm({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:Lm(e,t.prompt),evidence:e};try{let n=await t.provider.generatePrMetadata(e),r=Nm(n,e,t.prompt);return r?{ok:!0,metadata:r,evidence:e}:{ok:!1,error:"LLM-generated PR metadata failed schema or safety validation. Pass explicit title/body or retry after correcting the provider output.",evidence:e}}catch(n){return`${n instanceof Error?n.message:String(n)}`,{ok:!1,error:"PR metadata provider failed. Pass explicit title/body or retry after the provider is healthy.",evidence:e}}}function $r(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} ${yl(o.message)} (${o.author})`),r=t.diffSummary.commits>5?[`- ...and ${t.diffSummary.commits-5} more`]:[];n.length>0&&e.push("## Commits",...n,...r,"")}return e.push("## Validation",...t.metadata.validation.map(n=>`- ${n}`),"","## Notes / Risks",...t.metadata.notes.map(n=>`- ${n}`),""),e.push("---","Generated with [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)"),e.join(`
27
- `)}var $i=Q(()=>{});var vl={};Pu(vl,{buildPrCompletionWakeOutcomeKey:()=>Di,buildPrMetadata:()=>_r,buildPrOutcomeDetailLines:()=>Ei,formatPrBody:()=>$r,makeAgentPrTool:()=>Sn});import{existsSync as Bm}from"fs";function Fm(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Ei(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 Di(t){let e=t.prNumber!==void 0?`#${t.prNumber}`:t.prUrl??"unknown-pr",n=t.diffSummary?.commitMessages.map(o=>o.hash.trim()).filter(Boolean).join(","),r=t.action==="updated"?n||[`commits:${t.diffSummary?.commits??"unknown"}`,`insertions:${t.diffSummary?.insertions??"unknown"}`,`deletions:${t.diffSummary?.deletions??"unknown"}`].join(","):"created";return["worktree-pr",t.action,t.targetRepo??"default-repo",e,t.branchName,r].join(":")}function Sn(t,e={}){return{name:"agent_pr",description:"Create or update a GitHub PR for a worktree branch. Handles full PR lifecycle: creates new PRs, updates existing open PRs with comments, and handles merged/closed PRs. Pushes the branch, syncs PR state, and persists metadata.",parameters:g.Object({session:g.String({description:"Session name or ID to create/update PR for"}),title:g.Optional(g.String({description:"PR title (default: auto-generated from session name)"})),body:g.Optional(g.String({description:"PR body (default: auto-generated from commit summary)"})),base_branch:g.Optional(g.String({description:"Base branch for the PR (default: detected from repo)"})),force_new:g.Optional(g.Boolean({description:"Force creation of a new PR even if one exists (default: false)"})),target_repo:g.Optional(g.String({description:"Target repository for cross-repo PRs (e.g. 'openai/codex'). Auto-detected from 'upstream' remote if not set."}))}),async execute(n,r){if(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}],meta:{success:!1,state:"error"}};if(!Fm(r))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, title?, body?, base_branch?, force_new? }."}],meta:{success:!1,state:"error"}};if(!Ae())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=Mt(S,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:l,originalWorkdir:a,sessionName:d,branchName:u}=o;if(!l||!a)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 ${l}. The worktree may have been removed and no persisted branch name is available.`}],meta:{success:!1,state:"error"}};Bm(l)||`${l}${u}${a}`;let c=r.base_branch??Te(a),m=S.resolveRepoPolicy(a);if(m?.policy==="never-pr")return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${m.identity?.repoRoot??a}.`}],meta:{success:!1,state:"error"}};if(m&&!m.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${m.identity?.repoRoot??a}. Provider: ${m.provider}.`}],meta:{success:!1,state:"error"}};let p=k=>{let v=fl({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:k.prUrl,prNumber:k.prNumber,baseBranch:c,targetRepo:k.targetRepo,disposition:k.disposition});for(let I of gn(o))S.updatePersistedSession(I,v)},f=_a(a,r.target_repo??s?.worktreePrTargetRepo);if(!ur(a,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let h=xt(a,u,f);if(r.force_new&&h.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${h.state}).
26
+ `:" ").replace(/[ \t]+/g," ").trim()||void 0}function _t(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function kn(t){return t.replace(/\b[A-Za-z0-9_-]*(?:api[_-]?key|token|secret|password|passwd|pwd|credential|credentials|authorization|auth)[A-Za-z0-9_-]*\b\s*[:=]\s*["']?[^"'\s,;)]+/gi,"[redacted credential]").replace(/\b(?:api key|token|secret|password|credential|credentials)\s+\[redacted credential\]/gi,"[redacted credential]").replace(/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{16,}\b/g,"[redacted token]").replace(/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,"[redacted token]").replace(/\bsk-[A-Za-z0-9_-]{20,}\b/g,"[redacted token]").replace(/\bxox[baprs]-[A-Za-z0-9-]{20,}\b/g,"[redacted token]").replace(/\bAKIA[0-9A-Z]{16}\b/g,"[redacted token]").replace(/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{10,}\b/g,"[redacted token]").replace(/\bhttps?:\/\/\S+/gi,"[redacted link]").replace(/\b[A-Z]:\\(?:Users|Documents and Settings)\\[^\s`'")]+/gi,"[redacted path]").replace(/(?:^|[\s(])\/(?:home|Users|var|etc|private|tmp)\/[^\s`'").]+/g,e=>`${e.startsWith(" ")||e.startsWith("(")?e[0]:""}[redacted path]`).replace(new RegExp("\\b[A-Za-z0-9_-]{32,}\\b","g"),"[redacted token]")}function Mr(t){return/\b[A-Za-z0-9_-]*(?:api[_-]?key|token|secret|password|passwd|pwd|credential|credentials|authorization|auth)[A-Za-z0-9_-]*\b\s*[:=]\s*["']?[^"'\s,;)]+/i.test(t)||/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{16,}\b/.test(t)||/\bgithub_pat_[A-Za-z0-9_]{20,}\b/.test(t)||/\bsk-[A-Za-z0-9_-]{20,}\b/.test(t)||/\bxox[baprs]-[A-Za-z0-9-]{20,}\b/.test(t)||/\bAKIA[0-9A-Z]{16}\b/.test(t)||/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{10,}\b/.test(t)||/\bhttps?:\/\/\S+/i.test(t)||/\b[A-Z]:\\(?:Users|Documents and Settings)\\[^\s`'")]+/i.test(t)||/(?:^|[\s(])\/(?:home|Users|var|etc|private|tmp)\/[^\s`'").]+/.test(t)||new RegExp("\\b[A-Za-z0-9_-]{32,}\\b").test(t)}function Fm(t){let e=kl(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=kn(n).replace(/\s+/g," ").trim();return r?_t(r,180):void 0}function Sl(t){return kn(t.trim()).replace(/\s+/g," ").trim()}function qm(t,e){return t?.commitMessages.map(n=>Sl(n.message)).filter(Boolean).slice(0,e)??[]}function _i(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function vl(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function Km(t){let e=Fm(t.prompt),n=t.diffSummary;return{sessionName:t.sessionName,branchName:t.branchName,objective:e,stats:n?{commits:n.commits,filesChanged:n.filesChanged,insertions:n.insertions,deletions:n.deletions}:void 0,changedFiles:n?.changedFiles??[],commitSubjects:qm(n,5),validation:_i(),notes:vl()}}function Cr(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 Pl(t,e){let n=kl(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 yn(t,e,n){let r=t.toLowerCase();return Pl(e,n.objective).some(o=>r.includes(o))}function yl(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function $i(t,e){let n=new Set(e.changedFiles);if([...t.matchAll(/(?:^|[^\w.-])((?:\.?[\w-][\w.-]*\/)+(?:\.?[\w-][\w.-]*))(?![\w.-])/g)].map(m=>m[1]).some(m=>/\.[A-Za-z0-9]+$/.test(m)&&!n.has(m)))return!0;let o=new Set(e.changedFiles.filter(m=>!m.includes("/"))),i=String.raw`\.[a-z0-9][\w.-]*`,s=t.matchAll(new RegExp(`[\\\`"'](${i})[\\\`"']`,"g"));for(let m of s)if(!o.has(m[1]))return!0;let l=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 m of l)if(!o.has(m[1]))return!0;if(o.size===0)return!1;let a=new Set([...o].map(m=>m.match(/\.([A-Za-z0-9]+)$/)?.[1]?.toLowerCase()).filter(m=>!!m)),d=String.raw`[A-Za-z0-9][\w.-]*\.([A-Za-z0-9]+)`,u=t.matchAll(new RegExp(`[\\\`"'](${d})[\\\`"']`,"g"));for(let m of u){let p=m[1],f=m[2]?.toLowerCase();if(f!==void 0&&a.has(f)&&!o.has(p)&&!yl(p))return!0}return[...t.matchAll(new RegExp(String.raw`\b(?:file|files|path|paths|changed|changes|updated?|updates?|modified?|modifies|touched?|touches|added?|adds?|removed?|removes?|deleted?|deletes?)\s+(?:the\s+)?(${d})\b`,"gi"))].some(m=>{let p=m[1],f=m[2]?.toLowerCase();return f!==void 0&&a.has(f)&&!o.has(p)&&!yl(p)})}function De(t){return kn(t).replace(/\s+/g," ").trim()}function Um(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||!Cr(r.summary,5,180)||!Cr(r.changes,10,160)||!Cr(r.validation,5,160)||!Cr(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(l=>Mr(l)||yn(l,n,e)))return;let i={title:De(r.title),summary:r.summary.map(De),changes:r.changes.map(De),validation:r.validation.map(De),notes:r.notes.map(De)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(l=>!l||Mr(l)||yn(l,n,e))&&!s.some(l=>$i(l,e)))return i}function Vm(t,e){let n=_t(kn(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),r=_t(`OpenClaw agent changes: ${n}`,90),o=["Deterministic fallback metadata generated because no LLM PR metadata provider is configured.",`Session: ${n}.`,...t.objective?[`Objective: ${t.objective}`]:[],...t.stats?[`Scope: ${t.stats.commits} commits, ${t.stats.filesChanged} files changed (+${t.stats.insertions} / -${t.stats.deletions}).`]:["Scope: Diff summary was unavailable when the PR body was generated."]],i=t.changedFiles.length>0?t.changedFiles.slice(0,10).map(p=>`\`${p}\``):["Review the pushed worktree branch for the full set of changes."],s=t.changedFiles.length>10?[`...and ${t.changedFiles.length-10} more changed files.`]:[],l=["Fallback metadata is conservative; review the diff and CI/checks before marking the draft PR ready.",...t.notes],a={title:r,summary:o,changes:[...i,...s],validation:t.validation,notes:l},d=!1,u=!1,c=p=>{let f=De(p);if(yn(f,e,t)){d=!0;let h=Pl(e,t.objective);for(let k of h){let v=new RegExp(k.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");f=f.replace(v,"[redacted prompt detail]")}f=De(f)}return $i(f,t)&&(u=!0,f="[redacted file reference outside change set]"),f=De(f),(yn(f,e,t)||Mr(f))&&(d=!0,f="[redacted prompt detail]"),f};if(a={title:c(a.title)||_t(`OpenClaw agent changes: ${n}`,90),summary:a.summary.map(c).filter(p=>p&&p.length>0),changes:a.changes.map(c).filter(p=>p&&p.length>0),validation:a.validation.map(c).filter(p=>p&&p.length>0),notes:a.notes.map(c).filter(p=>p&&p.length>0)},a.summary.length===0&&(a.summary=["Deterministic fallback metadata generated because no LLM PR metadata provider is configured."]),a.changes.length===0&&(a.changes=["Review the pushed worktree branch for the full set of changes."]),a.validation.length===0&&(a.validation=_i()),a.notes.length===0&&(a.notes=vl()),d||u){let p="Some content was stripped from fallback metadata due to safety checks (prompt leak guard or references to files outside the diff).";a.notes.some(f=>f.toLowerCase().includes("stripped")||f.toLowerCase().includes("sanitized"))||(a.notes=[...a.notes,p])}let m=[a.title,...a.summary,...a.changes,...a.validation,...a.notes];if(m.some(p=>!p)||m.some(p=>Mr(p)||yn(p,e,t))||m.some(p=>$i(p,t))){let p=_t(kn(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);a={title:_t(`OpenClaw agent changes: ${p}`,90),summary:["Deterministic fallback metadata (sanitized for safety)."],changes:t.changedFiles.length>0?t.changedFiles.slice(0,5).map(f=>`\`${f}\``):["See the worktree branch diff for the full set of changes."],validation:_i(),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 p=De(t.branchName);a.notes.some(f=>f.toLowerCase().includes(p.toLowerCase()))||(a.notes=[...a.notes,`Branch: ${p}`])}return a}async function _r(t){let e=Km({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:Vm(e,t.prompt),evidence:e};try{let n=await t.provider.generatePrMetadata(e),r=Um(n,e,t.prompt);return r?{ok:!0,metadata:r,evidence:e}:{ok:!1,error:"LLM-generated PR metadata failed schema or safety validation. Pass explicit title/body or retry after correcting the provider output.",evidence:e}}catch(n){return`${n instanceof Error?n.message:String(n)}`,{ok:!1,error:"PR metadata provider failed. Pass explicit title/body or retry after the provider is healthy.",evidence:e}}}function $r(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} ${Sl(o.message)} (${o.author})`),r=t.diffSummary.commits>5?[`- ...and ${t.diffSummary.commits-5} more`]:[];n.length>0&&e.push("## Commits",...n,...r,"")}return e.push("## Validation",...t.metadata.validation.map(n=>`- ${n}`),"","## Notes / Risks",...t.metadata.notes.map(n=>`- ${n}`),""),e.push("---","Generated with [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)"),e.join(`
27
+ `)}var Ei=Q(()=>{});var wl={};bu(wl,{buildPrCompletionWakeOutcomeKey:()=>Oi,buildPrMetadata:()=>_r,buildPrOutcomeDetailLines:()=>Di,formatPrBody:()=>$r,makeAgentPrTool:()=>Sn});import{existsSync as Gm}from"fs";function jm(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Di(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 Oi(t){let e=t.prNumber!==void 0?`#${t.prNumber}`:t.prUrl??"unknown-pr",n=t.diffSummary?.commitMessages.map(o=>o.hash.trim()).filter(Boolean).join(","),r=t.action==="updated"?n||[`commits:${t.diffSummary?.commits??"unknown"}`,`insertions:${t.diffSummary?.insertions??"unknown"}`,`deletions:${t.diffSummary?.deletions??"unknown"}`].join(","):"created";return["worktree-pr",t.action,t.targetRepo??"default-repo",e,t.branchName,r].join(":")}function Sn(t,e={}){return{name:"agent_pr",description:"Create or update a GitHub PR for a worktree branch. Handles full PR lifecycle: creates new PRs, updates existing open PRs with comments, and handles merged/closed PRs. Pushes the branch, syncs PR state, and persists metadata.",parameters:g.Object({session:g.String({description:"Session name or ID to create/update PR for"}),title:g.Optional(g.String({description:"PR title (default: auto-generated from session name)"})),body:g.Optional(g.String({description:"PR body (default: auto-generated from commit summary)"})),base_branch:g.Optional(g.String({description:"Base branch for the PR (default: detected from repo)"})),force_new:g.Optional(g.Boolean({description:"Force creation of a new PR even if one exists (default: false)"})),target_repo:g.Optional(g.String({description:"Target repository for cross-repo PRs (e.g. 'openai/codex'). Auto-detected from 'upstream' remote if not set."}))}),async execute(n,r){if(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}],meta:{success:!1,state:"error"}};if(!jm(r))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, title?, body?, base_branch?, force_new? }."}],meta:{success:!1,state:"error"}};if(!Ae())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=Mt(S,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:l,originalWorkdir:a,sessionName:d,branchName:u}=o;if(!l||!a)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 ${l}. The worktree may have been removed and no persisted branch name is available.`}],meta:{success:!1,state:"error"}};Gm(l)||`${l}${u}${a}`;let c=r.base_branch??Te(a),m=S.resolveRepoPolicy(a);if(m?.policy==="never-pr")return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${m.identity?.repoRoot??a}.`}],meta:{success:!1,state:"error"}};if(m&&!m.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${m.identity?.repoRoot??a}. Provider: ${m.provider}.`}],meta:{success:!1,state:"error"}};let p=k=>{let v=hl({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:k.prUrl,prNumber:k.prNumber,baseBranch:c,targetRepo:k.targetRepo,disposition:k.disposition});for(let I of gn(o))S.updatePersistedSession(I,v)},f=Ea(a,r.target_repo??s?.worktreePrTargetRepo);if(!ur(a,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let h=xt(a,u,f);if(r.force_new&&h.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${h.state}).
28
28
 
29
29
  Existing PR: ${h.url}
30
30
 
31
31
  To create a new PR, you must first close/merge the existing PR manually or use a different branch.`}],meta:{success:!1,state:"error"}};if(h.exists&&h.state==="open"){let k=Ee(a,u,c);if(k&&k.commits>0){let v=k.commitMessages.slice(0,5).map(A=>`• ${A.hash} ${A.message} (${A.author})`).join(`
32
32
  `),I=k.commits>5?`
33
33
  ...and ${k.commits-5} more commits`:"",x=["🔄 **New commits pushed**","",`${k.commits} new commits (+${k.insertions} / -${k.deletions})`,"","### Latest commits:",v+I,"","---","🤖 [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)"].join(`
34
- `);if(qa(a,h.number,x,f)){p({prUrl:h.url,prNumber:h.number,targetRepo:f});let A=et({kind:"pr-updated",branch:u,prUrl:h.url});return S.notifyWorktreeOutcome(o.notificationTarget,A,{completionWakeOutcomeKey:Di({action:"updated",branchName:u,prUrl:h.url,prNumber:h.number,targetRepo:f,diffSummary:k}),detailLines:Ei({action:"updated",branchName:u,baseBranch:c,prUrl:h.url,prNumber:h.number,targetRepo:f,commits:k.commits,insertions:k.insertions,deletions:k.deletions})}),{content:[{type:"text",text:`${A}
34
+ `);if(Ua(a,h.number,x,f)){p({prUrl:h.url,prNumber:h.number,targetRepo:f});let A=et({kind:"pr-updated",branch:u,prUrl:h.url});return S.notifyWorktreeOutcome(o.notificationTarget,A,{completionWakeOutcomeKey:Oi({action:"updated",branchName:u,prUrl:h.url,prNumber:h.number,targetRepo:f,diffSummary:k}),detailLines:Di({action:"updated",branchName:u,baseBranch:c,prUrl:h.url,prNumber:h.number,targetRepo:f,commits:k.commits,insertions:k.insertions,deletions:k.deletions})}),{content:[{type:"text",text:`${A}
35
35
 
36
36
  📝 Added comment detailing ${k.commits} new commits (+${k.insertions} / -${k.deletions})`}],meta:{success:!0,state:"pr_updated"}}}else return{content:[{type:"text",text:`⚠️ Pushed to ${h.url} but failed to add comment.
37
37
 
@@ -47,227 +47,227 @@ What would you like to do?
47
47
  2. Close and delete the branch with agent_merge(delete_branch=true), then start a new session/worktree
48
48
  3. Manually delete the closed PR on GitHub, then call agent_pr(force_new=true) to create a fresh PR
49
49
 
50
- (This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{let k=!r.title||!r.body?Ee(a,u,c):void 0,v;if(!r.title||!r.body){let A=await _r({sessionName:d,branchName:u,prompt:o.prompt,diffSummary:k,provider:e.metadataProvider});if(A.ok===!1)return{content:[{type:"text",text:`❌ ${A.error}`}],meta:{success:!1,state:"error"}};v=A.metadata}let I=r.title??v.title,x=r.body;x||(x=$r({sessionName:d,metadata:v,diffSummary:k}));let w=Fa(a,u,c,I,x,f,{draft:!0});if(w.success&&w.prUrl){let A=xt(a,u,f);p({prUrl:w.prUrl,prNumber:A.number,targetRepo:f,disposition:"pr-opened"});let y=et({kind:"pr-opened",branch:u,targetRepo:f,prUrl:w.prUrl});return S.notifyWorktreeOutcome(o.notificationTarget,y,{completionWakeOutcomeKey:Di({action:"opened",branchName:u,prUrl:w.prUrl,prNumber:A.number,targetRepo:f}),detailLines:Ei({action:"opened",branchName:u,baseBranch:c,prUrl:w.prUrl,prNumber:A.number,targetRepo:f})}),{content:[{type:"text",text:w.warnings&&w.warnings.length>0?`${y}
50
+ (This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{let k=!r.title||!r.body?Ee(a,u,c):void 0,v;if(!r.title||!r.body){let A=await _r({sessionName:d,branchName:u,prompt:o.prompt,diffSummary:k,provider:e.metadataProvider});if(A.ok===!1)return{content:[{type:"text",text:`❌ ${A.error}`}],meta:{success:!1,state:"error"}};v=A.metadata}let I=r.title??v.title,x=r.body;x||(x=$r({sessionName:d,metadata:v,diffSummary:k}));let w=Ka(a,u,c,I,x,f,{draft:!0});if(w.success&&w.prUrl){let A=xt(a,u,f);p({prUrl:w.prUrl,prNumber:A.number,targetRepo:f,disposition:"pr-opened"});let y=et({kind:"pr-opened",branch:u,targetRepo:f,prUrl:w.prUrl});return S.notifyWorktreeOutcome(o.notificationTarget,y,{completionWakeOutcomeKey:Oi({action:"opened",branchName:u,prUrl:w.prUrl,prNumber:A.number,targetRepo:f}),detailLines:Di({action:"opened",branchName:u,baseBranch:c,prUrl:w.prUrl,prNumber:A.number,targetRepo:f})}),{content:[{type:"text",text:w.warnings&&w.warnings.length>0?`${y}
51
51
 
52
- ⚠️ ${w.warnings.join("; ")}`:y}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${w.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var Er=Q(()=>{te();L();he();$i();fn();hn();$i()});import{readdirSync as _y,statSync as $y,rmSync as Ey}from"fs";import{execFileSync as Dy}from"child_process";import{join as hu}from"path";te();L();function Ru(t){return t.length>80?`${t.slice(0,80)}...`:t}function Au(t){return t.worktreePath?!t.originalWorkdir||t.originalWorkdir===t.worktreePath?`${t.worktreePath} (worktree)`:`${t.worktreePath} (worktree of ${t.originalWorkdir})`:t.workdir}function Iu(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: ${Au(t)}`,` Model: ${t.model??"default"}`,` Prompt: "${Ru(t.prompt)}"`];return t.reasoningEffort&&e.push(` Reasoning effort: ${t.reasoningEffort}`),t.fastMode&&e.push(" Fast mode: enabled"),t.resumeSessionId?e.push(` Resume: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`):t.forceNewSession&&e.push(" Force new session: true"),t.clearedPersistedCodexResume&&e.push(" Thread state: historical Codex state cleared; starting a fresh thread."),e.push(" Mode: multi-turn (use agent_respond to send follow-up messages)"),e.push("","Use agent_sessions to check status, agent_output to see output."),e.join(`
53
- `)}function xn(t,e){return Iu({...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})}ie();function ut(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}}Z();function Vn(t){return"id"in t?t.id:t.sessionId}function tn(t){return t.status==="completed"||t.killReason==="done"}function Hc(t){return!tn(t)||!$(t)?!1:t.backendRef?.kind==="codex-app-server"||t.backendRef?.kind==="opencode-server"}function zc(t){return(t.killReason==="shutdown"||t.killReason==="startup-timeout")&&!$(t)}function nn(t){if(t.status==="running")return{kind:"direct",reason:"already_running"};let e=Vn(t);if(tn(t)&&!Hc(t))return{kind:"unavailable",reason:"completed",stableSessionId:e};let n=$(t);if(n){let r="harnessName"in t?void 0:t,{resumeSessionId:o,clearedPersistedCodexResume:i}=ut({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 zc(t)?{kind:"relaunch",stableSessionId:e}:{kind:"unavailable",reason:"missing_backend_state",stableSessionId:e}}ie();import{existsSync as aa}from"fs";function Gn(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()))}Z();function oa(t){return t==null?void 0:String(t).trim()||void 0}function Qc(t){return t.trim().replace(/^['"`](.*)['"`]$/s,"$1").trim()}function Jc(t){let e=t.split(/\n\s*\n/,1)[0]?.split(`
54
- `).map(n=>n.trim()).filter(Boolean)??[];if(e.length!==0)for(let n of e){let r=n.match(/^(Workdir|Repo):\s*(.+)$/),o=Qc(r?.[2]??"");if(o.startsWith("/")&&aa(o))return o}}function ia(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&&oa(t.originThreadId)===oa(e.originThreadId)}function sa(t){return t.slice(0,3).map(e=>` - ${e.name} [${e.ref}] | status=${e.status}${e.lifecycle?` | lifecycle=${e.lifecycle}`:""}`).join(`
55
- `)}function Yc(t,e){let n=[],r=[],o=new Set;for(let i of t.list?.("all")??[]){if(!ia(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||!ia(i,e))continue;let s=K(i)??i.harnessSessionId,l=i.sessionId??$(i)??i.harnessSessionId;!s||!l||o.has(l)||(o.add(l),n.push({ref:s,name:i.name,status:i.status,lifecycle:i.lifecycle,resumable:!0}))}return{resumable:n,active:r}}function jn(t,e,n){let r=t.workdir||Jc(t.prompt)||e.workspaceDir||D.defaultWorkdir||process.cwd();if(!aa(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=t.harness??ae(),i=at(o),s=t.model??i,l=t.model!==void 0,a=Tn(o);if(!s&&(o!=="opencode"||a&&a.length>0))return{kind:"error",text:`Error: No default model configured for harness "${o}". Set plugins.entries["openclaw-code-agent"].config.harnesses.${o}.defaultModel or pass model explicitly.`};if(s&&a&&a.length>0&&!Gn(s,a))return{kind:"error",text:l?`Error: Model "${s}" is not allowed. Permitted models: ${a.join(", ")}`:`Error: Default model "${s||"undefined"}" is not in allowedModels (${a.join(", ")}). Update your plugin config to set a compatible defaultModel.`};let d=Cn(e),u=zt(e,d||ze(r)),c=e.sessionKey||void 0,m=xs(c)??jo(e);if(!t.resume_session_id&&!t.force_new_session){let w=Yc(n,{workdir:r,originSessionKey:c,originChannel:u,originThreadId:m});if(w.resumable.length>0||w.active.length>0){let A=w.resumable.length>0?["Linked resumable session(s) already exist for this thread/workdir:",sa(w.resumable),"","Resume the latest one with:",` agent_respond(session='${w.resumable[0].ref}', message='<next instruction>')`,"Fork from it with:",` agent_launch(prompt='<new task>', resume_session_id='${w.resumable[0].ref}', fork_session=true)`].join(`
56
- `):"",y=w.active.length>0?[w.resumable.length>0?"Linked active session(s):":"Linked active session(s) already exist for this thread/workdir:",sa(w.active),"","Send a follow-up instead of launching a duplicate:",` agent_respond(session='${w.active[0].ref}', message='<next instruction>')`].join(`
52
+ ⚠️ ${w.warnings.join("; ")}`:y}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${w.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var Er=Q(()=>{te();L();he();Ei();fn();hn();Ei()});import{readdirSync as Ny,statSync as Ly,rmSync as By}from"fs";import{execFileSync as Fy}from"child_process";import{join as ku}from"path";te();L();function Iu(t){return t.length>80?`${t.slice(0,80)}...`:t}function xu(t){return t.worktreePath?!t.originalWorkdir||t.originalWorkdir===t.worktreePath?`${t.worktreePath} (worktree)`:`${t.worktreePath} (worktree of ${t.originalWorkdir})`:t.workdir}function Tu(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: ${xu(t)}`,` Model: ${t.model??"default"}`,` Prompt: "${Iu(t.prompt)}"`];return t.reasoningEffort&&e.push(` Reasoning effort: ${t.reasoningEffort}`),t.fastMode&&e.push(" Fast mode: enabled"),t.resumeSessionId?e.push(` Resume: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`):t.forceNewSession&&e.push(" Force new session: true"),t.clearedPersistedCodexResume&&e.push(" Thread state: historical Codex state cleared; starting a fresh thread."),e.push(" Mode: multi-turn (use agent_respond to send follow-up messages)"),e.push("","Use agent_sessions to check status, agent_output to see output."),e.join(`
53
+ `)}function xn(t,e){return Tu({...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})}ie();function ut(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}}Z();function Vn(t){return"id"in t?t.id:t.sessionId}function tn(t){return t.status==="completed"||t.killReason==="done"}function Xc(t){return!tn(t)||!$(t)?!1:t.backendRef?.kind==="codex-app-server"||t.backendRef?.kind==="opencode-server"}function ep(t){return(t.killReason==="shutdown"||t.killReason==="startup-timeout")&&!$(t)}function nn(t){if(t.status==="running")return{kind:"direct",reason:"already_running"};let e=Vn(t);if(tn(t)&&!Xc(t))return{kind:"unavailable",reason:"completed",stableSessionId:e};let n=$(t);if(n){let r="harnessName"in t?void 0:t,{resumeSessionId:o,clearedPersistedCodexResume:i}=ut({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 ep(t)?{kind:"relaunch",stableSessionId:e}:{kind:"unavailable",reason:"missing_backend_state",stableSessionId:e}}ie();import{existsSync as da}from"fs";function Gn(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()))}Z();function sa(t){return t==null?void 0:String(t).trim()||void 0}function tp(t){return t.trim().replace(/^['"`](.*)['"`]$/s,"$1").trim()}function np(t){let e=t.split(/\n\s*\n/,1)[0]?.split(`
54
+ `).map(n=>n.trim()).filter(Boolean)??[];if(e.length!==0)for(let n of e){let r=n.match(/^(Workdir|Repo):\s*(.+)$/),o=tp(r?.[2]??"");if(o.startsWith("/")&&da(o))return o}}function aa(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&&sa(t.originThreadId)===sa(e.originThreadId)}function la(t){return t.slice(0,3).map(e=>` - ${e.name} [${e.ref}] | status=${e.status}${e.lifecycle?` | lifecycle=${e.lifecycle}`:""}`).join(`
55
+ `)}function rp(t,e){let n=[],r=[],o=new Set;for(let i of t.list?.("all")??[]){if(!aa(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||!aa(i,e))continue;let s=K(i)??i.harnessSessionId,l=i.sessionId??$(i)??i.harnessSessionId;!s||!l||o.has(l)||(o.add(l),n.push({ref:s,name:i.name,status:i.status,lifecycle:i.lifecycle,resumable:!0}))}return{resumable:n,active:r}}function jn(t,e,n){let r=t.workdir||np(t.prompt)||e.workspaceDir||D.defaultWorkdir||process.cwd();if(!da(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=t.harness??ae(),i=at(o),s=t.model??i,l=t.model!==void 0,a=Tn(o);if(!s&&(o!=="opencode"||a&&a.length>0))return{kind:"error",text:`Error: No default model configured for harness "${o}". Set plugins.entries["openclaw-code-agent"].config.harnesses.${o}.defaultModel or pass model explicitly.`};if(s&&a&&a.length>0&&!Gn(s,a))return{kind:"error",text:l?`Error: Model "${s}" is not allowed. Permitted models: ${a.join(", ")}`:`Error: Default model "${s||"undefined"}" is not in allowedModels (${a.join(", ")}). Update your plugin config to set a compatible defaultModel.`};let d=Cn(e),u=zt(e,d||ze(r)),c=e.sessionKey||void 0,m=Ts(c)??jo(e);if(!t.resume_session_id&&!t.force_new_session){let w=rp(n,{workdir:r,originSessionKey:c,originChannel:u,originThreadId:m});if(w.resumable.length>0||w.active.length>0){let A=w.resumable.length>0?["Linked resumable session(s) already exist for this thread/workdir:",la(w.resumable),"","Resume the latest one with:",` agent_respond(session='${w.resumable[0].ref}', message='<next instruction>')`,"Fork from it with:",` agent_launch(prompt='<new task>', resume_session_id='${w.resumable[0].ref}', fork_session=true)`].join(`
56
+ `):"",y=w.active.length>0?[w.resumable.length>0?"Linked active session(s):":"Linked active session(s) already exist for this thread/workdir:",la(w.active),"","Send a follow-up instead of launching a duplicate:",` agent_respond(session='${w.active[0].ref}', message='<next instruction>')`].join(`
57
57
  `):"";return{kind:"blocked",text:["Resume-first protection blocked a fresh launch.","",A,y,["If you intentionally want a brand-new independent session here, call:"," agent_launch(prompt='<new task>', force_new_session=true)"].join(`
58
58
  `)].filter(Boolean).join(`
59
59
 
60
- `)}}}let p=t.resume_session_id,f=p?n.resolve?.(p):void 0,h=p?n.getPersistedSession?.(p):void 0;if(p){let w=n.resolveBackendConversationId?.(p)??n.resolveHarnessSessionId?.(p);if(!w)return{kind:"error",text:`Error: Could not resolve resume_session_id "${p}" to a session ID. Use agent_sessions to list available sessions.`};p=w}let{resumeSessionId:k,clearedPersistedCodexResume:v}=ut({requestedResumeSessionId:p,activeSession:f?{harnessSessionId:f.backendConversationId??f.harnessSessionId}:void 0,persistedSession:h?{harness:h.harness,backendRef:h.backendRef}:void 0}),I=t.permission_mode??D.permissionMode,x=t.plan_approval??D.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:s,permissionMode:I,planApproval:x,originChannel:u,originThreadId:m,originSessionKey:c,route:dt(e,u,c),resumeSessionId:k,resolvedResumeId:p,clearedPersistedCodexResume:v,reasoningEffort:Le(o),fastMode:lt(o)}}Z();function rn(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function Hn(t){let e=rn(t);return e?` | ${e}`:""}function Re(t){let e=Math.floor(t/1e3),n=Math.floor(e/60),r=e%60;return n>0?`${n}m${r}s`:`${r}s`}var Zc=new Set(["a","an","the","is","are","was","were","be","been","being","have","has","had","do","does","did","will","would","could","should","may","might","shall","can","need","must","i","me","my","we","our","you","your","it","its","he","she","to","of","in","for","on","with","at","by","from","as","into","through","about","that","this","these","those","and","or","but","if","then","so","not","no","please","just","also","very","all","some","any","each","make","write","create","build","implement","add","update"]);function da(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!Zc.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var la={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function Xc(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 ua(t){let e=la[t.phase]??la[t.status]??"❓",n=Re(t.duration),r=t.multiTurn?"multi-turn":"single",o=t.prompt.length>80?t.prompt.slice(0,80)+"...":t.prompt,i=t.costUsd>0?` | $${t.costUsd.toFixed(2)}`:"",s=[`${e} ${t.name} [${t.id}] (${n}${i}) — ${r}`,` 📁 ${t.workdir}`,` 📝 "${o}"`];t.worktreePath&&t.worktreeBranch&&s.push(` 🌿 Worktree: ${t.worktreeBranch} ${Xc(t)}`),t.phase!==t.status&&s.push(` ⚙️ Phase: ${t.phase}`),t.lifecycle&&t.lifecycle!==t.phase&&s.push(` 🔄 Lifecycle: ${t.lifecycle}`),(t.requestedPermissionMode||t.currentPermissionMode||t.approvalExecutionState)&&s.push(` 🔐 Approval: ${t.approvalExecutionState??"unknown"} (requested=${t.requestedPermissionMode??"unknown"}, effective=${t.currentPermissionMode??"unknown"})`),t.resumable&&s.push(" ↩️ Resumable: yes"),t.recovered&&s.push(" ♻️ Recovered: persisted metadata only; no live process to kill"),t.harness?s.push(` 🧰 Harness | model: ${rn({harness:t.harness,model:t.model})}`):t.model&&s.push(` 🧰 Harness | model: ${t.model}`);let l=$(t);return l&&s.push(` 🔗 Backend ID: ${l}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
60
+ `)}}}let p=t.resume_session_id,f=p?n.resolve?.(p):void 0,h=p?n.getPersistedSession?.(p):void 0;if(p){let w=n.resolveBackendConversationId?.(p)??n.resolveHarnessSessionId?.(p);if(!w)return{kind:"error",text:`Error: Could not resolve resume_session_id "${p}" to a session ID. Use agent_sessions to list available sessions.`};p=w}let{resumeSessionId:k,clearedPersistedCodexResume:v}=ut({requestedResumeSessionId:p,activeSession:f?{harnessSessionId:f.backendConversationId??f.harnessSessionId}:void 0,persistedSession:h?{harness:h.harness,backendRef:h.backendRef}:void 0}),I=t.permission_mode??D.permissionMode,x=t.plan_approval??D.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:s,permissionMode:I,planApproval:x,originChannel:u,originThreadId:m,originSessionKey:c,route:dt(e,u,c),resumeSessionId:k,resolvedResumeId:p,clearedPersistedCodexResume:v,reasoningEffort:Le(o),fastMode:lt(o)}}Z();function rn(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function Hn(t){let e=rn(t);return e?` | ${e}`:""}function Re(t){let e=Math.floor(t/1e3),n=Math.floor(e/60),r=e%60;return n>0?`${n}m${r}s`:`${r}s`}var op=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 ca(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!op.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var ua={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function ip(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 pa(t){let e=ua[t.phase]??ua[t.status]??"❓",n=Re(t.duration),r=t.multiTurn?"multi-turn":"single",o=t.prompt.length>80?t.prompt.slice(0,80)+"...":t.prompt,i=t.costUsd>0?` | $${t.costUsd.toFixed(2)}`:"",s=[`${e} ${t.name} [${t.id}] (${n}${i}) — ${r}`,` 📁 ${t.workdir}`,` 📝 "${o}"`];t.worktreePath&&t.worktreeBranch&&s.push(` 🌿 Worktree: ${t.worktreeBranch} ${ip(t)}`),t.phase!==t.status&&s.push(` ⚙️ Phase: ${t.phase}`),t.lifecycle&&t.lifecycle!==t.phase&&s.push(` 🔄 Lifecycle: ${t.lifecycle}`),(t.requestedPermissionMode||t.currentPermissionMode||t.approvalExecutionState)&&s.push(` 🔐 Approval: ${t.approvalExecutionState??"unknown"} (requested=${t.requestedPermissionMode??"unknown"}, effective=${t.currentPermissionMode??"unknown"})`),t.resumable&&s.push(" ↩️ Resumable: yes"),t.recovered&&s.push(" ♻️ Recovered: persisted metadata only; no live process to kill"),t.harness?s.push(` 🧰 Harness | model: ${rn({harness:t.harness,model:t.model})}`):t.model&&s.push(` 🧰 Harness | model: ${t.model}`);let l=$(t);return l&&s.push(` 🔗 Backend ID: ${l}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
61
61
  `)}function zn(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?Re(n):"n/a"}`];if(t.mostExpensive){let l=t.mostExpensive;s.push("","🏆 Notable session",` ${l.name} [${l.id}]`,` 📝 "${l.prompt}"`)}return s.join(`
62
- `)}function se(t,e){return e<=0?"":t.length<=e?t:e<=3?".".repeat(e):t.slice(0,e-3)+"..."}function ca(t,e){let n=t.split(`
62
+ `)}function se(t,e){return e<=0?"":t.length<=e?t:e<=3?".".repeat(e):t.slice(0,e-3)+"..."}function ma(t,e){let n=t.split(`
63
63
  `),r=[],o=0;for(let i=n.length-1;i>=0;i--){let s=n[i].length+(r.length>0?1:0);if(o+s>e&&r.length>0)break;r.unshift(n[i]),o+=s}return r.join(`
64
- `)}function pa(t,e){let n=t.split(`
64
+ `)}function fa(t,e){let n=t.split(`
65
65
  `),r=[],o=0;for(let i=0;i<n.length;i++){let s=n[i].length+(r.length>0?1:0);if(o+s>e&&r.length>0)break;r.push(n[i]),o+=s}return r.join(`
66
- `)}var Je,on,yt=!1;function ma(t){try{return t?.config?.current?.()}catch{return}}function kt(t,e){if(t&&typeof t=="object"){Je=t,arguments.length>=2?(on=e,yt=!0):yt||(on=ma(Je),yt=!0);return}Je=void 0,on=void 0,yt=!1}function St(){return Je}function fa(){return Je?.tasks?.managedFlows??Je?.taskFlow}function ga(){return yt||(on=ma(Je),yt=!0),on}var ep="openclaw-code-agent",tp=160,Qn={create(){},progress(){},finalize(){}};function Jn(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function np(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function rp(t){let e=t.prompt.trim().replace(/\s+/g," ");return se(e||t.name,tp)}function op(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 ip(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 li(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 sp(t){return t.lifecycle==="awaiting_plan_decision"||t.lifecycle==="awaiting_user_input"||t.lifecycle==="awaiting_worktree_decision"||t.lifecycle==="suspended"}function di(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 ap(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 ha(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var ui=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:ep,goal:rp(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:di(e,"created",n),createdAt:e.startedAt,updatedAt:r}),this.lastProgressKey=this.progressKey(e,n)}catch(o){Jn("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=op(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=di(e,"progress",n),i=Date.now(),s=sp(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=ha(this.flow,s),this.lastProgressKey=r}catch(o){Jn("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=ip(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":li(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...di(e,"terminal",r),terminalStatus:n,terminalSummary:li(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:li(e.status,e.killReason),updatedAt:o,endedAt:o});np("finalize",s),this.flow=ha(this.flow,s),this.finalized=!0}catch(o){Jn("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function Yn(t){if(!t.sessionKey?.trim())return Qn;try{let e=fa()?.fromToolContext;if(typeof e!="function")return Qn;let n=e(t);return ap(n)?new ui(n):Qn}catch(e){return Jn("resolve",e),Qn}}function lp(t){return t instanceof Error?t.message:String(t)}function ya(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function dp(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function up(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function cp(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function ka(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!dp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=jn(n,t,S);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};let{workdir:o,harness:i,resolvedModel:s,permissionMode:l,planApproval:a,originChannel:d,originThreadId:u,originSessionKey:c,route:m,resumeSessionId:p,resolvedResumeId:f,clearedPersistedCodexResume:h,reasoningEffort:k,fastMode:v}=r,I=n.resume_session_id?S.resolve(n.resume_session_id)??S.getPersistedSession(n.resume_session_id):void 0,x=!n.fork_session&&I?nn(I):void 0;if(x?.kind==="direct")return{content:[{type:"text",text:`Session ${I.name} [${ya(I,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 ${I.name} [${ya(I,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 w=n.worktree_strategy??D.defaultWorktreeStrategy??"off",A=n.fork_session?void 0:x?.kind==="resume"||x?.kind==="relaunch"?x.stableSessionId:void 0;if(w!=="off"&&cp(S)&&S.checkRepoPolicyForLaunch(o,n.worktree_strategy).ok===!1)return{content:[{type:"text",text:S.requestRepoPolicyForLaunch({route:m,prompt:n.prompt,workdir:o,name:n.name,model:s,reasoningEffort:k,fastMode:v,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:p,resumeWorktreeFrom:f,sessionIdOverride:A,clearedPersistedCodexResume:h,forkSession:p?n.fork_session:!1,forceNewSession:n.force_new_session,permissionMode:l,planApproval:a,harness:i,worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo,originAgentId:t.agentId||void 0})}]};let y=S.spawn({prompt:n.prompt,sessionIdOverride:A,name:n.name,workdir:o,model:s,reasoningEffort:k,fastMode:v,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:p,resumeWorktreeFrom:f,forkSession:p?n.fork_session:!1,multiTurn:!0,permissionMode:l,planApproval:a,codexApprovalPolicy:i==="codex"?"never":void 0,originChannel:d,originThreadId:u,originAgentId:t.agentId||void 0,originSessionKey:c,route:m,harness:i,taskLifecycle:Yn(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:up(S)?S.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:l??D.permissionMode,planApproval:a,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,clearedPersistedCodexResume:h},y):xn({prompt:n.prompt,workdir:o,harness:i,permissionMode:l??D.permissionMode,planApproval:a,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:h},{id:y.id,name:y.name,model:y.model,reasoningEffort:y.reasoningEffort??Le(i),fastMode:y.fastMode??v,worktreeStrategy:y.worktreeStrategy??n.worktree_strategy??D.defaultWorktreeStrategy??"off",repoIntegrationPolicy:y.repoIntegrationPolicy,repoProvider:y.repoProvider,worktreePath:y.worktreePath,originalWorkdir:y.originalWorkdir})}]}}catch(r){let o=lp(r),i=o.includes("Max sessions")?"":`
66
+ `)}var Je,on,yt=!1;function ga(t){try{return t?.config?.current?.()}catch{return}}function kt(t,e){if(t&&typeof t=="object"){Je=t,arguments.length>=2?(on=e,yt=!0):yt||(on=ga(Je),yt=!0);return}Je=void 0,on=void 0,yt=!1}function St(){return Je}function ha(){return Je?.tasks?.managedFlows??Je?.taskFlow}function ya(){return yt||(on=ga(Je),yt=!0),on}var sp="openclaw-code-agent",ap=160,Qn={create(){},progress(){},finalize(){}};function Jn(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function lp(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function dp(t){let e=t.prompt.trim().replace(/\s+/g," ");return se(e||t.name,ap)}function up(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 cp(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 li(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 pp(t){return t.lifecycle==="awaiting_plan_decision"||t.lifecycle==="awaiting_user_input"||t.lifecycle==="awaiting_worktree_decision"||t.lifecycle==="suspended"}function di(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 mp(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 ka(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var ui=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:sp,goal:dp(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:di(e,"created",n),createdAt:e.startedAt,updatedAt:r}),this.lastProgressKey=this.progressKey(e,n)}catch(o){Jn("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=up(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=di(e,"progress",n),i=Date.now(),s=pp(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=ka(this.flow,s),this.lastProgressKey=r}catch(o){Jn("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=cp(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":li(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...di(e,"terminal",r),terminalStatus:n,terminalSummary:li(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:li(e.status,e.killReason),updatedAt:o,endedAt:o});lp("finalize",s),this.flow=ka(this.flow,s),this.finalized=!0}catch(o){Jn("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function Yn(t){if(!t.sessionKey?.trim())return Qn;try{let e=ha()?.fromToolContext;if(typeof e!="function")return Qn;let n=e(t);return mp(n)?new ui(n):Qn}catch(e){return Jn("resolve",e),Qn}}function fp(t){return t instanceof Error?t.message:String(t)}function Sa(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function gp(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function hp(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function yp(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function va(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!gp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=jn(n,t,S);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};let{workdir:o,harness:i,resolvedModel:s,permissionMode:l,planApproval:a,originChannel:d,originThreadId:u,originSessionKey:c,route:m,resumeSessionId:p,resolvedResumeId:f,clearedPersistedCodexResume:h,reasoningEffort:k,fastMode:v}=r,I=n.resume_session_id?S.resolve(n.resume_session_id)??S.getPersistedSession(n.resume_session_id):void 0,x=!n.fork_session&&I?nn(I):void 0;if(x?.kind==="direct")return{content:[{type:"text",text:`Session ${I.name} [${Sa(I,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 ${I.name} [${Sa(I,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 w=n.worktree_strategy??D.defaultWorktreeStrategy??"off",A=n.fork_session?void 0:x?.kind==="resume"||x?.kind==="relaunch"?x.stableSessionId:void 0;if(w!=="off"&&yp(S)&&S.checkRepoPolicyForLaunch(o,n.worktree_strategy).ok===!1)return{content:[{type:"text",text:S.requestRepoPolicyForLaunch({route:m,prompt:n.prompt,workdir:o,name:n.name,model:s,reasoningEffort:k,fastMode:v,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:p,resumeWorktreeFrom:f,sessionIdOverride:A,clearedPersistedCodexResume:h,forkSession:p?n.fork_session:!1,forceNewSession:n.force_new_session,permissionMode:l,planApproval:a,harness:i,worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo,originAgentId:t.agentId||void 0})}]};let y=S.spawn({prompt:n.prompt,sessionIdOverride:A,name:n.name,workdir:o,model:s,reasoningEffort:k,fastMode:v,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:p,resumeWorktreeFrom:f,forkSession:p?n.fork_session:!1,multiTurn:!0,permissionMode:l,planApproval:a,codexApprovalPolicy:i==="codex"?"never":void 0,originChannel:d,originThreadId:u,originAgentId:t.agentId||void 0,originSessionKey:c,route:m,harness:i,taskLifecycle:Yn(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:hp(S)?S.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:l??D.permissionMode,planApproval:a,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,clearedPersistedCodexResume:h},y):xn({prompt:n.prompt,workdir:o,harness:i,permissionMode:l??D.permissionMode,planApproval:a,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:h},{id:y.id,name:y.name,model:y.model,reasoningEffort:y.reasoningEffort??Le(i),fastMode:y.fastMode??v,worktreeStrategy:y.worktreeStrategy??n.worktree_strategy??D.defaultWorktreeStrategy??"off",repoIntegrationPolicy:y.repoIntegrationPolicy,repoProvider:y.repoProvider,worktreePath:y.worktreePath,originalWorkdir:y.originalWorkdir})}]}}catch(r){let o=fp(r),i=o.includes("Max sessions")?"":`
67
67
 
68
- Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}te();L();ie();import{existsSync as ki,readFileSync as Ga}from"fs";import{EventEmitter as qp}from"events";import{webcrypto as va}from"node:crypto";var Sa="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var pp=128,Ye,vt;function mp(t){if(t<0||t>1024)throw new RangeError("Wrong ID size");!Ye||Ye.length<t?(Ye=Buffer.allocUnsafe(t*pp),va.getRandomValues(Ye),vt=0):vt+t>Ye.length&&(va.getRandomValues(Ye),vt=0),vt+=t}function Zn(t=21){mp(t|=0);let e="";for(let n=vt-t;n<vt;n++)e+=Sa[Ye[n]&63];return e}ii();ie();Z();var Pa={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function J(t,e){return Object.hasOwn(t,e)}var wa=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function fp(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 de(t){return{...t,approvalExecutionState:fp(t)}}function ci(t,e){switch(e.type){case"initialize":return de({...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"?de({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?de({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):de({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return de({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return de({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return de({...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 de({...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 de({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return de({...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 de({...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 de({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return de({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return de({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":wa.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return de({...t,deliveryState:e.deliveryState})}}function ba(t,e){let n={...t,...J(e,"lifecycle")?{lifecycle:e.lifecycle}:{},...J(e,"approvalState")?{approvalState:e.approvalState}:{},...J(e,"approvalExecutionState")?{approvalExecutionState:e.approvalExecutionState}:{},...J(e,"worktreeState")?{worktreeState:e.worktreeState}:{},...J(e,"runtimeState")?{runtimeState:e.runtimeState}:{},...J(e,"deliveryState")?{deliveryState:e.deliveryState}:{},...J(e,"requestedPermissionMode")?{requestedPermissionMode:e.requestedPermissionMode}:{},...J(e,"currentPermissionMode")?{currentPermissionMode:e.currentPermissionMode}:{},...J(e,"pendingPlanApproval")?{pendingPlanApproval:e.pendingPlanApproval}:{},...J(e,"planApprovalContext")?{planApprovalContext:e.planApprovalContext}:{},...J(e,"planDecisionVersion")?{planDecisionVersion:e.planDecisionVersion}:{},...J(e,"actionablePlanDecisionVersion")?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...J(e,"canonicalPlanPromptVersion")?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...J(e,"approvalPromptRequiredVersion")?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...J(e,"approvalPromptVersion")?{approvalPromptVersion:e.approvalPromptVersion}:{},...J(e,"approvalPromptStatus")?{approvalPromptStatus:e.approvalPromptStatus}:{},...J(e,"approvalPromptTransport")?{approvalPromptTransport:e.approvalPromptTransport}:{},...J(e,"approvalPromptMessageKind")?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...J(e,"approvalPromptLastAttemptAt")?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...J(e,"approvalPromptDeliveredAt")?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...J(e,"approvalPromptFailedAt")?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{},...J(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"}),J(e,"pendingWorktreeDecisionSince")&&e.pendingWorktreeDecisionSince!==void 0||n.worktreeState==="pending_decision"?n=ci(n,{type:"worktree.decision_requested"}):wa.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),de(n)}var Xn=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 gp}from"crypto";import{appendFileSync as hp}from"fs";import{tmpdir as yp}from"os";import{join as kp}from"path";var Ra=2e3,Sp=/^[A-Za-z0-9_.-]+$/;function vp(t){return Sp.test(t)?t:`hashed+${gp("sha256").update(t,"utf8").digest("hex")}`}function Ze(t){return kp(yp(),`openclaw-agent-${vp(t)}.txt`)}function Pp(t,e){if(!e)return;let n=e.split(`
69
- `),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function Aa(t,e,n){Pp(t,n),t.length>Ra&&t.splice(0,t.length-Ra);try{hp(Ze(e),n,"utf-8")}catch{}return t}var er=class{timers=new Map;get size(){return this.timers.size}set(e,n,r){this.clear(e);let o=setTimeout(()=>{this.timers.get(e)===o&&this.timers.delete(e),r()},n);o.unref?.(),this.timers.set(e,o)}clear(e){let n=this.timers.get(e);n&&(clearTimeout(n),this.timers.delete(e))}clearAll(){for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}};var tr=class{constructor(e){this.deps=e}deps;waitingForInputFired=!1;lastTurnHadQuestion=!1;turnInProgress=!0;currentTurnText="";currentTurnPlanArtifact;beginUserTurn(){this.waitingForInputFired=!1,this.turnInProgress=!0,this.currentTurnText="",this.currentTurnPlanArtifact=void 0,this.lastTurnHadQuestion=!1}noteTextDelta(e,n){this.waitingForInputFired=!1,n||(this.lastTurnHadQuestion=!1),this.deps.appendOutput(e),this.currentTurnText+=this.currentTurnText?`
70
- ${e}`:e,this.deps.emitOutput(e)}noteToolCall(e){let{name:n,input:r,currentPermissionMode:o,permissionMode:i,planModeApproved:s}=e;if(n==="Write"){let l=r;typeof l?.file_path=="string"&&l.file_path.includes("/.claude/plans/")&&this.deps.setPlanFilePath(l.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:l}=e,a=o;(n==="plan"||r==="plan")&&!a&&!i&&(this.deps.markPendingPlanApproval("plan-mode"),a=!0);let d=a||this.lastTurnHadQuestion||!!s;if(this.turnInProgress=l,d&&!this.waitingForInputFired)this.waitingForInputFired=!0,a||this.deps.markAwaitingUserInput(),this.deps.emitTurnEnd(!0);else if(!l&&!d){if(this.deps.queueWorktreeFinalizationPrompt?.()){this.turnInProgress=!0;return}this.deps.completeTurn(),this.deps.emitTurnEnd(!1)}}finishTerminalTurn(){this.turnInProgress=!1}finishInterruptedTurn(e){this.turnInProgress=e,this.waitingForInputFired=!1,this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}resetAfterRun(){this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}};var 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}};he();var Kp=120*1e3;function pr(t){return t instanceof Error?t.message:String(t)}var mr=class extends qp{id;name;harnessSessionId;backendRef;harness;harnessHandle;prompt;workdir;model;reasoningEffort;fastMode;systemPrompt;allowedTools;permissionMode;requestedPermissionMode;planApproval;codexApprovalPolicy;currentPermissionMode;pendingModeSwitch;resumeSessionId;forkSession;worktreePath;originalWorkdir;worktreeBranch;worktreeStrategy;repoIntegrationPolicy;repoIntegrationPolicySource;repoProvider;worktreeBaseBranch;worktreePrTargetRepo;autoMergeParentSessionId;autoMergeConflictResolutionAttemptCount;autoMergeResolverSessionId;worktreePushRemote;worktreeDisposition;worktreePrUrl;worktreePrNumber;worktreeMerged;worktreeMergedAt;worktreeLifecycle;worktreeState="none";multiTurn;goalTaskId;messageStream;_status="starting";error;startedAt;completedAt;abortController;outputBuffer=[];result;costUsd=0;originChannel;originThreadId;originAgentId;originSessionKey;route;pendingInputState;pendingPlanApproval=!1;planApprovalContext;planDecisionVersion=0;actionablePlanDecisionVersion;canonicalPlanPromptVersion;approvalPromptRequiredVersion;approvalPromptVersion;approvalPromptStatus="not_sent";approvalPromptTransport="none";approvalPromptMessageKind="none";approvalPromptLastAttemptAt;approvalPromptDeliveredAt;approvalPromptFailedAt;planFilePath;killReason="unknown";planModeApproved=!1;turnRuntime;harnessEvents;worktreeFinalizationPromptIssued=!1;lifecycle="starting";approvalState="not_required";approvalExecutionState="not_plan_gated";approvalRationale;latestPlanArtifact;latestPlanArtifactVersion;runtimeState="live";deliveryState="idle";canUseTool;autoRespondCount=0;timers=new er;constructor(e,n){super(),this.id=e.sessionIdOverride??Zn(8),this.name=n,this.harness=e.harness?Xt(e.harness):ra(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??at(this.harness.name),this.reasoningEffort=e.reasoningEffort??Le(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??lt(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??D.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??D.planApproval,this.codexApprovalPolicy=this.harness.name==="codex"?"never":void 0,this.currentPermissionMode=this.permissionMode,this.originChannel=e.originChannel,this.originThreadId=e.originThreadId,this.originAgentId=e.originAgentId,this.originSessionKey=e.originSessionKey,this.route=e.route?{...e.route}:void 0,this.backendRef=e.backendRef?{...e.backendRef}:void 0,this.resumeSessionId=e.resumeSessionId,this.forkSession=e.forkSession,this.multiTurn=e.multiTurn??!0,this.goalTaskId=e.goalTaskId,this.worktreeStrategy=e.worktreeStrategy,this.repoIntegrationPolicy=e.repoIntegrationPolicy,this.repoIntegrationPolicySource=e.repoIntegrationPolicySource,this.repoProvider=e.repoProvider,this.worktreeBaseBranch=e.worktreeBaseBranch,e.worktreePrTargetRepo&&(this.worktreePrTargetRepo=e.worktreePrTargetRepo),e.autoMergeParentSessionId&&(this.autoMergeParentSessionId=e.autoMergeParentSessionId),e.autoMergeConflictResolutionAttemptCount!==void 0&&(this.autoMergeConflictResolutionAttemptCount=e.autoMergeConflictResolutionAttemptCount),e.autoMergeResolverSessionId&&(this.autoMergeResolverSessionId=e.autoMergeResolverSessionId),this.canUseTool=e.canUseTool,this.startedAt=Date.now(),this.abortController=new AbortController,this.turnRuntime=new tr({appendOutput:r=>Aa(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??=Pt(r.worktreePath),this.worktreeStrategy&&this.worktreeStrategy!=="off"&&this.applyControlEvent({type:"worktree.state_set",worktreeState:"provisioned"}))},noteRunStarted:r=>{this.backendRef&&(this.backendRef={...this.backendRef,runId:r})},transitionRunning:()=>{this._status==="starting"&&this.transition("running")},noteTextDelta:(r,o)=>this.turnRuntime.noteTextDelta(r,o),noteToolCall:r=>this.turnRuntime.noteToolCall(r),setPendingInputState:r=>{this.pendingInputState=r},notePendingInput:()=>this.turnRuntime.notePendingInput(),clearResolvedPendingInput:(r,o)=>this.turnRuntime.clearResolvedPendingInput(r,o),notePlanArtifact:r=>this.turnRuntime.notePlanArtifact(r.artifact,r.finalized),noteSettingsChanged:r=>this.turnRuntime.noteSettingsChanged(r),setCurrentPermissionMode:r=>{this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r})},handleRunCompleted:r=>{let o=r.outcome??(r.success?"completed":"failed");this.result={subtype:o==="interrupted"?"interrupted":r.success?"success":"error",duration_ms:r.duration_ms,total_cost_usd:r.total_cost_usd,num_turns:r.num_turns,result:r.result,is_error:o==="failed",session_id:r.session_id},this.costUsd=r.total_cost_usd;let i=this.multiTurn&&this.messageStream&&o==="interrupted",s=this.multiTurn&&this.messageStream&&o==="completed";i?(this.resetIdleTimer(),this.turnRuntime.finishInterruptedTurn(this.messageStream?.hasPending()===!0)):s?(this.resetIdleTimer(),this.turnRuntime.finishSuccessfulTurn({currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,pendingPlanApproval:this.pendingPlanApproval,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState,hasPendingMessages:this.messageStream?.hasPending()===!0})):(this.turnRuntime.finishTerminalTurn(),this.transitionToTerminal(o==="completed"?"completed":"failed")),this.turnRuntime.resetAfterRun(),this.pendingInputState=void 0}}),this.applyControlEvent({type:"initialize",hasWorktree:!!(this.worktreeStrategy&&this.worktreeStrategy!=="off")}),(e.planModeApproved!==void 0||e.approvalState!==void 0||e.approvalExecutionState!==void 0||e.approvalRationale!==void 0||e.pendingPlanApproval!==void 0||e.planApprovalContext!==void 0||e.planDecisionVersion!==void 0||e.actionablePlanDecisionVersion!==void 0||e.canonicalPlanPromptVersion!==void 0||e.approvalPromptRequiredVersion!==void 0||e.approvalPromptVersion!==void 0||e.approvalPromptStatus!==void 0||e.approvalPromptTransport!==void 0||e.approvalPromptMessageKind!==void 0||e.approvalPromptLastAttemptAt!==void 0||e.approvalPromptDeliveredAt!==void 0||e.approvalPromptFailedAt!==void 0)&&this.applyControlPatch({...e.planModeApproved!==void 0?{planModeApproved:e.planModeApproved}:{},...e.approvalState!==void 0?{approvalState:e.approvalState}:{},...e.approvalExecutionState!==void 0?{approvalExecutionState:e.approvalExecutionState}:{},...e.pendingPlanApproval!==void 0?{pendingPlanApproval:e.pendingPlanApproval}:{},...e.planApprovalContext!==void 0?{planApprovalContext:e.planApprovalContext}:{},...e.planDecisionVersion!==void 0?{planDecisionVersion:e.planDecisionVersion}:{},...e.actionablePlanDecisionVersion!==void 0?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...e.canonicalPlanPromptVersion!==void 0?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...e.approvalPromptRequiredVersion!==void 0?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...e.approvalPromptVersion!==void 0?{approvalPromptVersion:e.approvalPromptVersion}:{},...e.approvalPromptStatus!==void 0?{approvalPromptStatus:e.approvalPromptStatus}:{},...e.approvalPromptTransport!==void 0?{approvalPromptTransport:e.approvalPromptTransport}:{},...e.approvalPromptMessageKind!==void 0?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...e.approvalPromptLastAttemptAt!==void 0?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...e.approvalPromptDeliveredAt!==void 0?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...e.approvalPromptFailedAt!==void 0?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{}}),this.approvalRationale=e.approvalRationale}get status(){return this._status}get harnessName(){return this.harness.name}get backendKind(){return this.harness.backendKind}get backendCapabilities(){return this.harness.capabilities}get backendConversationId(){return $(this)}approvalSnapshot(){return{requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,approvalExecutionState:this.approvalExecutionState,approvalRationale:this.approvalRationale,planModeApproved:this.controlStateSnapshot().planModeApproved,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planApproval:this.planApproval,codexApprovalPolicy:this.codexApprovalPolicy}}worktreeSnapshot(){return{worktreePath:this.worktreePath,worktreeBranch:this.worktreeBranch,worktreeStrategy:this.worktreeStrategy,repoIntegrationPolicy:this.repoIntegrationPolicy,repoIntegrationPolicySource:this.repoIntegrationPolicySource,repoProvider:this.repoProvider,worktreeBaseBranch:this.worktreeBaseBranch,worktreePrTargetRepo:this.worktreePrTargetRepo,autoMergeParentSessionId:this.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:this.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:this.autoMergeResolverSessionId,worktreeLifecycle:this.worktreeLifecycle}}backendSnapshot(){return{harnessSessionId:this.harnessSessionId,backendRef:this.backendRef,harness:this.harnessName,backendKind:this.backendKind,backendConversationId:this.backendConversationId}}routingSnapshot(){return{route:this.route,originAgentId:this.originAgentId,originChannel:this.originChannel,originThreadId:this.originThreadId,originSessionKey:this.originSessionKey}}get waitingForInputFired(){return this.turnRuntime.waitingForInputFired}set waitingForInputFired(e){this.turnRuntime.waitingForInputFired=e}get turnInProgress(){return this.turnRuntime.turnInProgress}set turnInProgress(e){this.turnRuntime.turnInProgress=e}get currentTurnPlanArtifact(){return this.turnRuntime.currentTurnPlanArtifact}set currentTurnPlanArtifact(e){this.turnRuntime.currentTurnPlanArtifact=e}get duration(){return(this.completedAt??Date.now())-this.startedAt}get phase(){return this.lifecycle}get isExplicitlyResumable(){return this.status!=="running"&&this.status!=="completed"&&this.killReason!=="done"&&!!this.backendConversationId}transition(e){if(!Pa[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=Xe(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(i=>`- ${i}`).join(`
68
+ Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}te();L();ie();import{existsSync as ki,readFileSync as Ha}from"fs";import{EventEmitter as Hp}from"events";import{webcrypto as wa}from"node:crypto";var Pa="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var kp=128,Ye,vt;function Sp(t){if(t<0||t>1024)throw new RangeError("Wrong ID size");!Ye||Ye.length<t?(Ye=Buffer.allocUnsafe(t*kp),wa.getRandomValues(Ye),vt=0):vt+t>Ye.length&&(wa.getRandomValues(Ye),vt=0),vt+=t}function Zn(t=21){Sp(t|=0);let e="";for(let n=vt-t;n<vt;n++)e+=Pa[Ye[n]&63];return e}ii();ie();Z();var ba={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function J(t,e){return Object.hasOwn(t,e)}var Ra=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function vp(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 de(t){return{...t,approvalExecutionState:vp(t)}}function ci(t,e){switch(e.type){case"initialize":return de({...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"?de({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?de({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):de({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return de({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return de({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return de({...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 de({...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 de({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return de({...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 de({...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 de({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return de({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return de({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":Ra.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return de({...t,deliveryState:e.deliveryState})}}function Aa(t,e){let n={...t,...J(e,"lifecycle")?{lifecycle:e.lifecycle}:{},...J(e,"approvalState")?{approvalState:e.approvalState}:{},...J(e,"approvalExecutionState")?{approvalExecutionState:e.approvalExecutionState}:{},...J(e,"worktreeState")?{worktreeState:e.worktreeState}:{},...J(e,"runtimeState")?{runtimeState:e.runtimeState}:{},...J(e,"deliveryState")?{deliveryState:e.deliveryState}:{},...J(e,"requestedPermissionMode")?{requestedPermissionMode:e.requestedPermissionMode}:{},...J(e,"currentPermissionMode")?{currentPermissionMode:e.currentPermissionMode}:{},...J(e,"pendingPlanApproval")?{pendingPlanApproval:e.pendingPlanApproval}:{},...J(e,"planApprovalContext")?{planApprovalContext:e.planApprovalContext}:{},...J(e,"planDecisionVersion")?{planDecisionVersion:e.planDecisionVersion}:{},...J(e,"actionablePlanDecisionVersion")?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...J(e,"canonicalPlanPromptVersion")?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...J(e,"approvalPromptRequiredVersion")?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...J(e,"approvalPromptVersion")?{approvalPromptVersion:e.approvalPromptVersion}:{},...J(e,"approvalPromptStatus")?{approvalPromptStatus:e.approvalPromptStatus}:{},...J(e,"approvalPromptTransport")?{approvalPromptTransport:e.approvalPromptTransport}:{},...J(e,"approvalPromptMessageKind")?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...J(e,"approvalPromptLastAttemptAt")?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...J(e,"approvalPromptDeliveredAt")?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...J(e,"approvalPromptFailedAt")?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{},...J(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"}),J(e,"pendingWorktreeDecisionSince")&&e.pendingWorktreeDecisionSince!==void 0||n.worktreeState==="pending_decision"?n=ci(n,{type:"worktree.decision_requested"}):Ra.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),de(n)}var Xn=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 Pp}from"crypto";import{appendFileSync as wp}from"fs";import{tmpdir as bp}from"os";import{join as Rp}from"path";var Ia=2e3,Ap=/^[A-Za-z0-9_.-]+$/;function Ip(t){return Ap.test(t)?t:`hashed+${Pp("sha256").update(t,"utf8").digest("hex")}`}function Ze(t){return Rp(bp(),`openclaw-agent-${Ip(t)}.txt`)}function xp(t,e){if(!e)return;let n=e.split(`
69
+ `),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function xa(t,e,n){xp(t,n),t.length>Ia&&t.splice(0,t.length-Ia);try{wp(Ze(e),n,"utf-8")}catch{}return t}var er=class{timers=new Map;get size(){return this.timers.size}set(e,n,r){this.clear(e);let o=setTimeout(()=>{this.timers.get(e)===o&&this.timers.delete(e),r()},n);o.unref?.(),this.timers.set(e,o)}clear(e){let n=this.timers.get(e);n&&(clearTimeout(n),this.timers.delete(e))}clearAll(){for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}};var tr=class{constructor(e){this.deps=e}deps;waitingForInputFired=!1;lastTurnHadQuestion=!1;turnInProgress=!0;currentTurnText="";currentTurnPlanArtifact;beginUserTurn(){this.waitingForInputFired=!1,this.turnInProgress=!0,this.currentTurnText="",this.currentTurnPlanArtifact=void 0,this.lastTurnHadQuestion=!1}noteTextDelta(e,n){this.waitingForInputFired=!1,n||(this.lastTurnHadQuestion=!1),this.deps.appendOutput(e),this.currentTurnText+=this.currentTurnText?`
70
+ ${e}`:e,this.deps.emitOutput(e)}noteToolCall(e){let{name:n,input:r,currentPermissionMode:o,permissionMode:i,planModeApproved:s}=e;if(n==="Write"){let l=r;typeof l?.file_path=="string"&&l.file_path.includes("/.claude/plans/")&&this.deps.setPlanFilePath(l.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:l}=e,a=o;(n==="plan"||r==="plan")&&!a&&!i&&(this.deps.markPendingPlanApproval("plan-mode"),a=!0);let d=a||this.lastTurnHadQuestion||!!s;if(this.turnInProgress=l,d&&!this.waitingForInputFired)this.waitingForInputFired=!0,a||this.deps.markAwaitingUserInput(),this.deps.emitTurnEnd(!0);else if(!l&&!d){if(this.deps.queueWorktreeFinalizationPrompt?.()){this.turnInProgress=!0;return}this.deps.completeTurn(),this.deps.emitTurnEnd(!1)}}finishTerminalTurn(){this.turnInProgress=!1}finishInterruptedTurn(e){this.turnInProgress=e,this.waitingForInputFired=!1,this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}resetAfterRun(){this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}};var 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}};he();var zp=120*1e3;function pr(t){return t instanceof Error?t.message:String(t)}var mr=class extends Hp{id;name;harnessSessionId;backendRef;harness;harnessHandle;prompt;workdir;model;reasoningEffort;fastMode;systemPrompt;allowedTools;permissionMode;requestedPermissionMode;planApproval;codexApprovalPolicy;currentPermissionMode;pendingModeSwitch;resumeSessionId;forkSession;worktreePath;originalWorkdir;worktreeBranch;worktreeStrategy;repoIntegrationPolicy;repoIntegrationPolicySource;repoProvider;worktreeBaseBranch;worktreePrTargetRepo;autoMergeParentSessionId;autoMergeConflictResolutionAttemptCount;autoMergeResolverSessionId;worktreePushRemote;worktreeDisposition;worktreePrUrl;worktreePrNumber;worktreeMerged;worktreeMergedAt;worktreeLifecycle;worktreeState="none";multiTurn;goalTaskId;messageStream;_status="starting";error;startedAt;completedAt;abortController;outputBuffer=[];result;costUsd=0;originChannel;originThreadId;originAgentId;originSessionKey;route;pendingInputState;pendingPlanApproval=!1;planApprovalContext;planDecisionVersion=0;actionablePlanDecisionVersion;canonicalPlanPromptVersion;approvalPromptRequiredVersion;approvalPromptVersion;approvalPromptStatus="not_sent";approvalPromptTransport="none";approvalPromptMessageKind="none";approvalPromptLastAttemptAt;approvalPromptDeliveredAt;approvalPromptFailedAt;planFilePath;killReason="unknown";planModeApproved=!1;turnRuntime;harnessEvents;worktreeFinalizationPromptIssued=!1;lifecycle="starting";approvalState="not_required";approvalExecutionState="not_plan_gated";approvalRationale;latestPlanArtifact;latestPlanArtifactVersion;runtimeState="live";deliveryState="idle";canUseTool;autoRespondCount=0;timers=new er;constructor(e,n){super(),this.id=e.sessionIdOverride??Zn(8),this.name=n,this.harness=e.harness?Xt(e.harness):ia(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??at(this.harness.name),this.reasoningEffort=e.reasoningEffort??Le(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??lt(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??D.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??D.planApproval,this.codexApprovalPolicy=this.harness.name==="codex"?"never":void 0,this.currentPermissionMode=this.permissionMode,this.originChannel=e.originChannel,this.originThreadId=e.originThreadId,this.originAgentId=e.originAgentId,this.originSessionKey=e.originSessionKey,this.route=e.route?{...e.route}:void 0,this.backendRef=e.backendRef?{...e.backendRef}:void 0,this.resumeSessionId=e.resumeSessionId,this.forkSession=e.forkSession,this.multiTurn=e.multiTurn??!0,this.goalTaskId=e.goalTaskId,this.worktreeStrategy=e.worktreeStrategy,this.repoIntegrationPolicy=e.repoIntegrationPolicy,this.repoIntegrationPolicySource=e.repoIntegrationPolicySource,this.repoProvider=e.repoProvider,this.worktreeBaseBranch=e.worktreeBaseBranch,e.worktreePrTargetRepo&&(this.worktreePrTargetRepo=e.worktreePrTargetRepo),e.autoMergeParentSessionId&&(this.autoMergeParentSessionId=e.autoMergeParentSessionId),e.autoMergeConflictResolutionAttemptCount!==void 0&&(this.autoMergeConflictResolutionAttemptCount=e.autoMergeConflictResolutionAttemptCount),e.autoMergeResolverSessionId&&(this.autoMergeResolverSessionId=e.autoMergeResolverSessionId),this.canUseTool=e.canUseTool,this.startedAt=Date.now(),this.abortController=new AbortController,this.turnRuntime=new tr({appendOutput:r=>xa(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??=Pt(r.worktreePath),this.worktreeStrategy&&this.worktreeStrategy!=="off"&&this.applyControlEvent({type:"worktree.state_set",worktreeState:"provisioned"}))},noteRunStarted:r=>{this.backendRef&&(this.backendRef={...this.backendRef,runId:r})},transitionRunning:()=>{this._status==="starting"&&this.transition("running")},noteTextDelta:(r,o)=>this.turnRuntime.noteTextDelta(r,o),noteToolCall:r=>this.turnRuntime.noteToolCall(r),setPendingInputState:r=>{this.pendingInputState=r},notePendingInput:()=>this.turnRuntime.notePendingInput(),clearResolvedPendingInput:(r,o)=>this.turnRuntime.clearResolvedPendingInput(r,o),notePlanArtifact:r=>this.turnRuntime.notePlanArtifact(r.artifact,r.finalized),noteSettingsChanged:r=>this.turnRuntime.noteSettingsChanged(r),setCurrentPermissionMode:r=>{this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r})},handleRunCompleted:r=>{let o=r.outcome??(r.success?"completed":"failed");this.result={subtype:o==="interrupted"?"interrupted":r.success?"success":"error",duration_ms:r.duration_ms,total_cost_usd:r.total_cost_usd,num_turns:r.num_turns,result:r.result,is_error:o==="failed",session_id:r.session_id},this.costUsd=r.total_cost_usd;let i=this.multiTurn&&this.messageStream&&o==="interrupted",s=this.multiTurn&&this.messageStream&&o==="completed";i?(this.resetIdleTimer(),this.turnRuntime.finishInterruptedTurn(this.messageStream?.hasPending()===!0)):s?(this.resetIdleTimer(),this.turnRuntime.finishSuccessfulTurn({currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,pendingPlanApproval:this.pendingPlanApproval,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState,hasPendingMessages:this.messageStream?.hasPending()===!0})):(this.turnRuntime.finishTerminalTurn(),this.transitionToTerminal(o==="completed"?"completed":"failed")),this.turnRuntime.resetAfterRun(),this.pendingInputState=void 0}}),this.applyControlEvent({type:"initialize",hasWorktree:!!(this.worktreeStrategy&&this.worktreeStrategy!=="off")}),(e.planModeApproved!==void 0||e.approvalState!==void 0||e.approvalExecutionState!==void 0||e.approvalRationale!==void 0||e.pendingPlanApproval!==void 0||e.planApprovalContext!==void 0||e.planDecisionVersion!==void 0||e.actionablePlanDecisionVersion!==void 0||e.canonicalPlanPromptVersion!==void 0||e.approvalPromptRequiredVersion!==void 0||e.approvalPromptVersion!==void 0||e.approvalPromptStatus!==void 0||e.approvalPromptTransport!==void 0||e.approvalPromptMessageKind!==void 0||e.approvalPromptLastAttemptAt!==void 0||e.approvalPromptDeliveredAt!==void 0||e.approvalPromptFailedAt!==void 0)&&this.applyControlPatch({...e.planModeApproved!==void 0?{planModeApproved:e.planModeApproved}:{},...e.approvalState!==void 0?{approvalState:e.approvalState}:{},...e.approvalExecutionState!==void 0?{approvalExecutionState:e.approvalExecutionState}:{},...e.pendingPlanApproval!==void 0?{pendingPlanApproval:e.pendingPlanApproval}:{},...e.planApprovalContext!==void 0?{planApprovalContext:e.planApprovalContext}:{},...e.planDecisionVersion!==void 0?{planDecisionVersion:e.planDecisionVersion}:{},...e.actionablePlanDecisionVersion!==void 0?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...e.canonicalPlanPromptVersion!==void 0?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...e.approvalPromptRequiredVersion!==void 0?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...e.approvalPromptVersion!==void 0?{approvalPromptVersion:e.approvalPromptVersion}:{},...e.approvalPromptStatus!==void 0?{approvalPromptStatus:e.approvalPromptStatus}:{},...e.approvalPromptTransport!==void 0?{approvalPromptTransport:e.approvalPromptTransport}:{},...e.approvalPromptMessageKind!==void 0?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...e.approvalPromptLastAttemptAt!==void 0?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...e.approvalPromptDeliveredAt!==void 0?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...e.approvalPromptFailedAt!==void 0?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{}}),this.approvalRationale=e.approvalRationale}get status(){return this._status}get harnessName(){return this.harness.name}get backendKind(){return this.harness.backendKind}get backendCapabilities(){return this.harness.capabilities}get backendConversationId(){return $(this)}approvalSnapshot(){return{requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,approvalExecutionState:this.approvalExecutionState,approvalRationale:this.approvalRationale,planModeApproved:this.controlStateSnapshot().planModeApproved,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planApproval:this.planApproval,codexApprovalPolicy:this.codexApprovalPolicy}}worktreeSnapshot(){return{worktreePath:this.worktreePath,worktreeBranch:this.worktreeBranch,worktreeStrategy:this.worktreeStrategy,repoIntegrationPolicy:this.repoIntegrationPolicy,repoIntegrationPolicySource:this.repoIntegrationPolicySource,repoProvider:this.repoProvider,worktreeBaseBranch:this.worktreeBaseBranch,worktreePrTargetRepo:this.worktreePrTargetRepo,autoMergeParentSessionId:this.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:this.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:this.autoMergeResolverSessionId,worktreeLifecycle:this.worktreeLifecycle}}backendSnapshot(){return{harnessSessionId:this.harnessSessionId,backendRef:this.backendRef,harness:this.harnessName,backendKind:this.backendKind,backendConversationId:this.backendConversationId}}routingSnapshot(){return{route:this.route,originAgentId:this.originAgentId,originChannel:this.originChannel,originThreadId:this.originThreadId,originSessionKey:this.originSessionKey}}get waitingForInputFired(){return this.turnRuntime.waitingForInputFired}set waitingForInputFired(e){this.turnRuntime.waitingForInputFired=e}get turnInProgress(){return this.turnRuntime.turnInProgress}set turnInProgress(e){this.turnRuntime.turnInProgress=e}get currentTurnPlanArtifact(){return this.turnRuntime.currentTurnPlanArtifact}set currentTurnPlanArtifact(e){this.turnRuntime.currentTurnPlanArtifact=e}get duration(){return(this.completedAt??Date.now())-this.startedAt}get phase(){return this.lifecycle}get isExplicitlyResumable(){return this.status!=="running"&&this.status!=="completed"&&this.killReason!=="done"&&!!this.backendConversationId}transition(e){if(!ba[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=Xe(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(i=>`- ${i}`).join(`
71
71
  `),r=e.length>20?`
72
72
  - ...and ${e.length-20} more`:"",o=["Your worktree still has uncommitted changes, so this session cannot finish yet.","",`Worktree: ${this.worktreePath}`,`Branch: ${this.worktreeBranch??"(unknown)"}`,"","Dirty entries:",`${n}${r}`,"","Before finishing, run `git status --short` in the worktree and do exactly one of these:","1. If these are real task changes, commit them on the worktree branch with `git add` and `git commit`.","2. If these are temporary or unrelated artifacts, remove or restore them so the worktree is clean.","3. If no repository changes were intended, leave the worktree clean and say that no changes were needed.","","Do not finish again until `git status --short` is clean or all real task changes are committed."].join(`
73
- `);return this.messageStream.push(this.harness.buildUserMessage(o,this.backendConversationId??"")),!0}async start(){try{let e;this.multiTurn?(this.messageStream=new Xn,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:Rs(),canUseTool:this.canUseTool});this.harnessHandle=n,this.setTimer("startup",Kp,()=>{this._status==="starting"&&this.kill("startup-timeout")})}catch(e){let n=e instanceof Error?e.message:String(e);this.transitionToTerminal("failed",{error:n});return}this.consumeMessages(this.harnessHandle.messages).catch(e=>{let n=e instanceof Error?e.message:String(e),r=e instanceof Error?e.stack:void 0;console.error(`[Session ${this.id}] consumeMessages error: ${n}`,r),this.isActive&&this.transitionToTerminal("failed",{error:n})})}async sendMessage(e){if(this._status!=="running")throw new Error(`Session is not running (status: ${this._status})`);this.resetIdleTimer(),this.turnRuntime.beginUserTurn(),this.applyControlEvent({type:"turn.started"});let n=e;if(this.pendingModeSwitch){let r=this.pendingModeSwitch,o=!1,i=!1;if(this.harnessHandle?.setPermissionMode)try{await this.harnessHandle.setPermissionMode(r),this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r}),this.pendingModeSwitch=void 0,i=!0,o=!0}catch(s){throw console.error(`[Session ${this.id}] setPermissionMode(${r}) FAILED: ${pr(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${pr(s)}`)}else this.pendingModeSwitch=void 0,i=!0,o=!0,`${this.id}${this.currentPermissionMode}`;i&&(this.clearPendingPlanApproval(),r!=="plan"&&this.applyControlEvent({type:"plan.approved"})),o&&(n=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
73
+ `);return this.messageStream.push(this.harness.buildUserMessage(o,this.backendConversationId??"")),!0}async start(){try{let e;this.multiTurn?(this.messageStream=new Xn,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:As(),canUseTool:this.canUseTool});this.harnessHandle=n,this.setTimer("startup",zp,()=>{this._status==="starting"&&this.kill("startup-timeout")})}catch(e){let n=e instanceof Error?e.message:String(e);this.transitionToTerminal("failed",{error:n});return}this.consumeMessages(this.harnessHandle.messages).catch(e=>{let n=e instanceof Error?e.message:String(e),r=e instanceof Error?e.stack:void 0;console.error(`[Session ${this.id}] consumeMessages error: ${n}`,r),this.isActive&&this.transitionToTerminal("failed",{error:n})})}async sendMessage(e){if(this._status!=="running")throw new Error(`Session is not running (status: ${this._status})`);this.resetIdleTimer(),this.turnRuntime.beginUserTurn(),this.applyControlEvent({type:"turn.started"});let n=e;if(this.pendingModeSwitch){let r=this.pendingModeSwitch,o=!1,i=!1;if(this.harnessHandle?.setPermissionMode)try{await this.harnessHandle.setPermissionMode(r),this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r}),this.pendingModeSwitch=void 0,i=!0,o=!0}catch(s){throw console.error(`[Session ${this.id}] setPermissionMode(${r}) FAILED: ${pr(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${pr(s)}`)}else this.pendingModeSwitch=void 0,i=!0,o=!0,`${this.id}${this.currentPermissionMode}`;i&&(this.clearPendingPlanApproval(),r!=="plan"&&this.applyControlEvent({type:"plan.approved"})),o&&(n=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
74
74
 
75
75
  ${e}`)}else if((this.pendingPlanApproval||this.approvalState==="changes_requested")&&!this.planModeApproved&&(this.approvalState!=="changes_requested"&&this.applyControlEvent({type:"plan.changes_requested"}),n=`[SYSTEM: The user wants changes to your plan. Revise the plan based on their feedback below, then re-submit your revised plan for approval. Do NOT start implementing yet.]
76
76
 
77
- ${e}`,this.harnessHandle?.setPermissionMode))try{await this.harnessHandle.setPermissionMode("plan"),this.currentPermissionMode="plan",this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:"plan"})}catch(r){`${this.id}${pr(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.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}${pr(e)}`}),this.abortController.abort(),this.applyControlEvent({type:"terminal.entered",suspended:this.lifecycle==="suspended"})}transitionToTerminal(e,n={}){this.isActive&&(this.turnInProgress=!1,n.reason&&(this.killReason=n.reason),n.error!==void 0&&(this.error=n.error),this.completedAt=Date.now(),this.applyControlEvent({type:"terminal.entered",suspended:e==="killed"&&n.reason==="idle-timeout"}),this.transition(e),this.teardown())}async consumeMessages(e){for await(let n of e){if(!this.isActive)break;this.resetIdleTimer(),this.harnessEvents.applyMessage(n,{pendingPlanApproval:this.pendingPlanApproval,currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState})}}controlStateSnapshot(){return{status:this._status,lifecycle:this.lifecycle,approvalState:this.approvalState,approvalExecutionState:this.approvalExecutionState,worktreeState:this.worktreeState,runtimeState:this.runtimeState,deliveryState:this.deliveryState,requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planModeApproved:this.planModeApproved}}applyControlEvent(e){let n=ci(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=ba(this.controlStateSnapshot(),e);this.applyControlState(n)}setControlField(e,n){this.applyControlPatch({[e]:n})}applyControlState(e){let n=this.lifecycle;this.lifecycle=e.lifecycle,this.approvalState=e.approvalState,this.approvalExecutionState=e.approvalExecutionState,this.worktreeState=e.worktreeState,this.runtimeState=e.runtimeState,this.deliveryState=e.deliveryState,this.pendingPlanApproval=e.pendingPlanApproval,this.planApprovalContext=e.planApprovalContext,this.planDecisionVersion=e.planDecisionVersion,this.actionablePlanDecisionVersion=e.actionablePlanDecisionVersion,this.canonicalPlanPromptVersion=e.canonicalPlanPromptVersion,this.approvalPromptRequiredVersion=e.approvalPromptRequiredVersion,this.approvalPromptVersion=e.approvalPromptVersion,this.approvalPromptStatus=e.approvalPromptStatus,this.approvalPromptTransport=e.approvalPromptTransport,this.approvalPromptMessageKind=e.approvalPromptMessageKind,this.approvalPromptLastAttemptAt=e.approvalPromptLastAttemptAt,this.approvalPromptDeliveredAt=e.approvalPromptDeliveredAt,this.approvalPromptFailedAt=e.approvalPromptFailedAt,this.planModeApproved=e.planModeApproved,n!==this.lifecycle&&this.emit("lifecycleChange",this,this.lifecycle,n)}};var Up=50,Vp=1,Gp=new Set(["starting","running","completed","failed","killed"]),jp=5,Hp=1440*60*1e3,fr=new Set(["merged","released","dismissed","no_change"]);function zp(t){let e=Number(t);return!Number.isFinite(e)||e<Vp?Up:Math.floor(e)}function Qp(t){return typeof t=="string"&&Gp.has(t)}function Jp(t){let e=t.split(`
78
- `);return e.at(-1)===""&&e.pop(),e}function Si(t){return t.backendRef?.conversationId??t.harnessSessionId}function Yp(t,e){return e&&fr.has(e)&&(!t||!fr.has(t))?e:t??e}function Zp(t,e){return e&&fr.has(e.state)&&(!t||!fr.has(t.state))?e:t??e}function ja(t,e,n){let r=Ga(t,"utf-8"),o=Jp(r);return e.full?o:o.slice(-n)}function Xp(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=Ze(t.id);if(!ki(r))return null;try{return ja(r,e,n)}catch{return null}}function em(t){let e=Re(t.duration),n=` | Cost: $${t.costUsd.toFixed(4)}`,r=t.phase?` | Phase: ${t.phase}`:"",o=t.lifecycle&&t.lifecycle!==t.phase?` | Lifecycle: ${t.lifecycle}`:"";return[`Session: ${t.name} [${t.id}] | Status: ${t.status.toUpperCase()}${r}${o}${n} | Duration: ${e}`,`${"─".repeat(60)}`].join(`
79
- `)}function Ha(t,e){let n=t.name||t.sessionId||Si(t)||"unknown",r=t.lifecycle?` | Phase: ${t.lifecycle}`:"";return[`Session: ${n} | Status: ${t.status.toUpperCase()}${r} | Cost: $${t.costUsd.toFixed(4)}`,e,`${"─".repeat(60)}`].join(`
80
- `)}function tm(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function nm(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 Va(t,e){let n=Ha(t,nm(t)),r=Si(t),o=r?`
77
+ ${e}`,this.harnessHandle?.setPermissionMode))try{await this.harnessHandle.setPermissionMode("plan"),this.currentPermissionMode="plan",this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:"plan"})}catch(r){`${this.id}${pr(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.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}${pr(e)}`}),this.abortController.abort(),this.applyControlEvent({type:"terminal.entered",suspended:this.lifecycle==="suspended"})}transitionToTerminal(e,n={}){this.isActive&&(this.turnInProgress=!1,n.reason&&(this.killReason=n.reason),n.error!==void 0&&(this.error=n.error),this.completedAt=Date.now(),this.applyControlEvent({type:"terminal.entered",suspended:e==="killed"&&n.reason==="idle-timeout"}),this.transition(e),this.teardown())}async consumeMessages(e){for await(let n of e){if(!this.isActive)break;this.resetIdleTimer(),this.harnessEvents.applyMessage(n,{pendingPlanApproval:this.pendingPlanApproval,currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState})}}controlStateSnapshot(){return{status:this._status,lifecycle:this.lifecycle,approvalState:this.approvalState,approvalExecutionState:this.approvalExecutionState,worktreeState:this.worktreeState,runtimeState:this.runtimeState,deliveryState:this.deliveryState,requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planModeApproved:this.planModeApproved}}applyControlEvent(e){let n=ci(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=Aa(this.controlStateSnapshot(),e);this.applyControlState(n)}setControlField(e,n){this.applyControlPatch({[e]:n})}applyControlState(e){let n=this.lifecycle;this.lifecycle=e.lifecycle,this.approvalState=e.approvalState,this.approvalExecutionState=e.approvalExecutionState,this.worktreeState=e.worktreeState,this.runtimeState=e.runtimeState,this.deliveryState=e.deliveryState,this.pendingPlanApproval=e.pendingPlanApproval,this.planApprovalContext=e.planApprovalContext,this.planDecisionVersion=e.planDecisionVersion,this.actionablePlanDecisionVersion=e.actionablePlanDecisionVersion,this.canonicalPlanPromptVersion=e.canonicalPlanPromptVersion,this.approvalPromptRequiredVersion=e.approvalPromptRequiredVersion,this.approvalPromptVersion=e.approvalPromptVersion,this.approvalPromptStatus=e.approvalPromptStatus,this.approvalPromptTransport=e.approvalPromptTransport,this.approvalPromptMessageKind=e.approvalPromptMessageKind,this.approvalPromptLastAttemptAt=e.approvalPromptLastAttemptAt,this.approvalPromptDeliveredAt=e.approvalPromptDeliveredAt,this.approvalPromptFailedAt=e.approvalPromptFailedAt,this.planModeApproved=e.planModeApproved,n!==this.lifecycle&&this.emit("lifecycleChange",this,this.lifecycle,n)}};var Qp=50,Jp=1,Yp=new Set(["starting","running","completed","failed","killed"]),Zp=5,Xp=1440*60*1e3,fr=new Set(["merged","released","dismissed","no_change"]);function em(t){let e=Number(t);return!Number.isFinite(e)||e<Jp?Qp:Math.floor(e)}function tm(t){return typeof t=="string"&&Yp.has(t)}function nm(t){let e=t.split(`
78
+ `);return e.at(-1)===""&&e.pop(),e}function Si(t){return t.backendRef?.conversationId??t.harnessSessionId}function rm(t,e){return e&&fr.has(e)&&(!t||!fr.has(t))?e:t??e}function om(t,e){return e&&fr.has(e.state)&&(!t||!fr.has(t.state))?e:t??e}function za(t,e,n){let r=Ha(t,"utf-8"),o=nm(r);return e.full?o:o.slice(-n)}function im(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=Ze(t.id);if(!ki(r))return null;try{return za(r,e,n)}catch{return null}}function sm(t){let e=Re(t.duration),n=` | Cost: $${t.costUsd.toFixed(4)}`,r=t.phase?` | Phase: ${t.phase}`:"",o=t.lifecycle&&t.lifecycle!==t.phase?` | Lifecycle: ${t.lifecycle}`:"";return[`Session: ${t.name} [${t.id}] | Status: ${t.status.toUpperCase()}${r}${o}${n} | Duration: ${e}`,`${"─".repeat(60)}`].join(`
79
+ `)}function Qa(t,e){let n=t.name||t.sessionId||Si(t)||"unknown",r=t.lifecycle?` | Phase: ${t.lifecycle}`:"";return[`Session: ${n} | Status: ${t.status.toUpperCase()}${r} | Cost: $${t.costUsd.toFixed(4)}`,e,`${"─".repeat(60)}`].join(`
80
+ `)}function am(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function lm(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 ja(t,e){let n=Qa(t,lm(t)),r=Si(t),o=r?`
81
81
  Backend session: ${r}`:"";return`${n}
82
- (no persisted output available: ${e})${o}`}function rm(t){let e=[];return t.error&&e.push(`Error: ${t.error}`),t.result?.result&&e.push(`Result: ${t.result.result}`),t.result&&e.push(`Result status: ${t.result.subtype}`),e.length>0?`
82
+ (no persisted output available: ${e})${o}`}function dm(t){let e=[];return t.error&&e.push(`Error: ${t.error}`),t.result?.result&&e.push(`Result: ${t.result.result}`),t.result&&e.push(`Result status: ${t.result.subtype}`),e.length>0?`
83
83
  (no output yet)
84
84
  ${e.join(`
85
85
  `)}`:`
86
- (no output yet)`}function gr(t,e,n={}){let r=zp(n.lines),o=t.resolve(e);if(!o){let d=t.getPersistedSession(e);if(d?.outputPath&&ki(d.outputPath))try{let u=ja(d.outputPath,n,r).join(`
87
- `),c=Ha(d,tm(d));return u?`${c}
86
+ (no output yet)`}function gr(t,e,n={}){let r=em(n.lines),o=t.resolve(e);if(!o){let d=t.getPersistedSession(e);if(d?.outputPath&&ki(d.outputPath))try{let u=za(d.outputPath,n,r).join(`
87
+ `),c=Qa(d,am(d));return u?`${c}
88
88
  ${u}`:`${c}
89
- (output file was empty)`}catch(u){let c=u instanceof Error?u.message:String(u);return`Error: Session "${e}" was cleaned up (expired) and output file could not be read: ${c}`}return d?.outputPath?Va(d,`output file is missing at ${d.outputPath}`):d?Va(d,"no outputPath is stored for this recovered session"):`Error: Session "${e}" not found.`}let i=Xp(o,n,r),s=i&&i.length>0?i:n.full?o.getOutput():o.getOutput(r),l=em(o),a=s.length===0?`${l}${rm(o)}`:`${l}
89
+ (output file was empty)`}catch(u){let c=u instanceof Error?u.message:String(u);return`Error: Session "${e}" was cleaned up (expired) and output file could not be read: ${c}`}return d?.outputPath?ja(d,`output file is missing at ${d.outputPath}`):d?ja(d,"no outputPath is stored for this recovered session"):`Error: Session "${e}" not found.`}let i=im(o,n,r),s=i&&i.length>0?i:n.full?o.getOutput():o.getOutput(r),l=sm(o),a=s.length===0?`${l}${dm(o)}`:`${l}
90
90
  ${s.join(`
91
- `)}`;if(o.pendingPlanApproval&&o.planFilePath)try{if(ki(o.planFilePath)){let d=Ga(o.planFilePath,"utf-8"),u="─".repeat(60);return`${a}
91
+ `)}`;if(o.pendingPlanApproval&&o.planFilePath)try{if(ki(o.planFilePath)){let d=Ha(o.planFilePath,"utf-8"),u="─".repeat(60);return`${a}
92
92
  ${u}
93
93
  Plan file: ${o.planFilePath}
94
94
  ${u}
95
- ${d}`}}catch{}return a}function hr(t,e="all",n,r={}){let o=t.listPersistedSessions()??[],s=om(t.list("all"),o);if(e!=="all"&&(s=s.filter(l=>l.status===e)),n&&(s=s.filter(l=>l.originChannel===n)),r.full){let l=Date.now()-Hp;s=s.filter(a=>(a.startedAt??0)>=l)}else s=s.slice(0,jp);return s.length===0?"No sessions found.":s.map(l=>ua(l)).join(`
95
+ ${d}`}}catch{}return a}function hr(t,e="all",n,r={}){let o=t.listPersistedSessions()??[],s=um(t.list("all"),o);if(e!=="all"&&(s=s.filter(l=>l.status===e)),n&&(s=s.filter(l=>l.originChannel===n)),r.full){let l=Date.now()-Xp;s=s.filter(a=>(a.startedAt??0)>=l)}else s=s.slice(0,Zp);return s.length===0?"No sessions found.":s.map(l=>pa(l)).join(`
96
96
 
97
- `)}function om(t,e){let n=new Map;for(let r of e){if(!Qp(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=Si(r),l=r.sessionId??`persisted:${s??r.harnessSessionId}`;n.set(l,{id:r.sessionId??s??r.harnessSessionId,name:r.name||r.sessionId||s||r.harnessSessionId,status:r.status,startedAt:r.createdAt??0,completedAt:r.completedAt,duration:Math.max(0,o-i),prompt:r.prompt??"",workdir:r.workdir??"(unknown)",costUsd:r.costUsd??0,multiTurn:!0,phase:r.lifecycle??r.status,lifecycle:r.lifecycle,resumable:r.resumable,harness:r.harness,model:r.model,backendRef:r.backendRef,harnessSessionId:r.harnessSessionId,requestedPermissionMode:r.requestedPermissionMode,currentPermissionMode:r.currentPermissionMode,approvalExecutionState:r.approvalExecutionState,originChannel:r.originChannel,originThreadId:r.originThreadId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,worktreeStrategy:r.worktreeStrategy,worktreeState:r.worktreeState,worktreeLifecycle:r.worktreeLifecycle,worktreeMerged:r.worktreeMerged,worktreeMergedAt:r.worktreeMergedAt,worktreePrUrl:r.worktreePrUrl,recovered:!0})}for(let r of t){let o=n.get(r.id);n.set(r.id,{id:r.id,name:r.name,status:r.status,startedAt:r.startedAt,completedAt:r.completedAt,duration:r.duration,prompt:r.prompt,workdir:r.originalWorkdir??r.workdir,costUsd:r.costUsd,multiTurn:r.multiTurn,phase:r.phase,lifecycle:r.lifecycle,resumable:r.isExplicitlyResumable,harness:r.harnessName,model:r.model,backendRef:r.backendRef,harnessSessionId:r.harnessSessionId,requestedPermissionMode:r.requestedPermissionMode,currentPermissionMode:r.currentPermissionMode,approvalExecutionState:r.approvalExecutionState,originChannel:r.originChannel,originThreadId:r.originThreadId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,worktreeStrategy:r.worktreeStrategy,worktreeState:Yp(r.worktreeState,o?.worktreeState),worktreeLifecycle:Zp(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 im(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 za(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=im(n),o=t?.workspaceDir?ze(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:hr(S,r,o,{full:i})}]}}}}te();L();function yr(t,e,n){let r=t.resolve(e);if(!r){let o=t.getPersistedSession(e);if(!o)return`Error: Session "${e}" not found.`;if(o.status==="killed"&&o.lifecycle==="suspended"){let i=n==="completed";if(t.updatePersistedSession(e,{status:i?"completed":"killed",lifecycle:"terminal",runtimeState:"stopped",resumable:!1,killReason:i?"done":"user"}))return i?`Recovered session ${o.name} [${o.sessionId??o.harnessSessionId}] marked as completed. No live process was running.`:`Recovered session ${o.name} [${o.sessionId??o.harnessSessionId}] dismissed. No live process was running.`}return`Session ${o.name} [${o.sessionId??o.harnessSessionId}] is a persisted ${o.status} record with no live process to kill.`}return r.status==="completed"||r.status==="failed"||r.status==="killed"?`Session ${r.name} [${r.id}] is already ${r.status}. No action needed.`:n==="completed"?(r.complete(),`Session ${r.name} [${r.id}] marked as completed.`):(t.kill(r.id),`Session ${r.name} [${r.id}] has been terminated.`)}function sm(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 Qa(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 S?sm(n)?{content:[{type:"text",text:yr(S,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."}]}}}}te();L();function am(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function kr(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 S?am(n)?{content:[{type:"text",text:gr(S,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."}]}}}}te();L();ie();Z();var lm=10;function Pi(t){return t instanceof Error?t.message:String(t)}function tt(t){return K(t)??t.harnessSessionId??"unknown-session"}function dm(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return Vn(t)??K(t)??$(t)}function Ja(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!$(t)}function um(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 un(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='${tt(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='${tt(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='${tt(t)}', fork_session=true, prompt='<new task>').`:`Use agent_respond(session='${tt(t)}', message='<next instruction>') to continue the running session.`,o=n?` ${n}`:"";return{text:`Resume unavailable for session ${t.name} [${tt(t)}] (${e}).${o} ${r}`,isError:!0}}async function Ya(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:Vn(e),workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,worktreeStrategy:e.worktreeStrategy,multiTurn:!0,originChannel:e.originChannel,originThreadId:e.originThreadId,originAgentId:e.originAgentId,originSessionKey:e.originSessionKey,route:e.route,permissionMode:e.currentPermissionMode,requestedPermissionMode:e.requestedPermissionMode??e.currentPermissionMode,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy,harness:"harnessName"in e?e.harnessName:e.harness},o=await t.spawnAndAwaitRunning(r,{notifyLaunch:!1});return t.notifySession(o,`▶️ [${o.name}] Relaunched fresh`),{text:`Session ${e.name} was relaunched fresh — it was killed during startup before the harness initialized. New session: ${o.name} [${o.id}].`}}catch(r){return{text:`Error relaunching session ${e.name} [${tt(e)}]: ${Pi(r)}`,isError:!0}}}var cm=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
97
+ `)}function um(t,e){let n=new Map;for(let r of e){if(!tm(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=Si(r),l=r.sessionId??`persisted:${s??r.harnessSessionId}`;n.set(l,{id:r.sessionId??s??r.harnessSessionId,name:r.name||r.sessionId||s||r.harnessSessionId,status:r.status,startedAt:r.createdAt??0,completedAt:r.completedAt,duration:Math.max(0,o-i),prompt:r.prompt??"",workdir:r.workdir??"(unknown)",costUsd:r.costUsd??0,multiTurn:!0,phase:r.lifecycle??r.status,lifecycle:r.lifecycle,resumable:r.resumable,harness:r.harness,model:r.model,backendRef:r.backendRef,harnessSessionId:r.harnessSessionId,requestedPermissionMode:r.requestedPermissionMode,currentPermissionMode:r.currentPermissionMode,approvalExecutionState:r.approvalExecutionState,originChannel:r.originChannel,originThreadId:r.originThreadId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,worktreeStrategy:r.worktreeStrategy,worktreeState:r.worktreeState,worktreeLifecycle:r.worktreeLifecycle,worktreeMerged:r.worktreeMerged,worktreeMergedAt:r.worktreeMergedAt,worktreePrUrl:r.worktreePrUrl,recovered:!0})}for(let r of t){let o=n.get(r.id);n.set(r.id,{id:r.id,name:r.name,status:r.status,startedAt:r.startedAt,completedAt:r.completedAt,duration:r.duration,prompt:r.prompt,workdir:r.originalWorkdir??r.workdir,costUsd:r.costUsd,multiTurn:r.multiTurn,phase:r.phase,lifecycle:r.lifecycle,resumable:r.isExplicitlyResumable,harness:r.harnessName,model:r.model,backendRef:r.backendRef,harnessSessionId:r.harnessSessionId,requestedPermissionMode:r.requestedPermissionMode,currentPermissionMode:r.currentPermissionMode,approvalExecutionState:r.approvalExecutionState,originChannel:r.originChannel,originThreadId:r.originThreadId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,worktreeStrategy:r.worktreeStrategy,worktreeState:rm(r.worktreeState,o?.worktreeState),worktreeLifecycle:om(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 cm(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 Ja(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=cm(n),o=t?.workspaceDir?ze(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:hr(S,r,o,{full:i})}]}}}}te();L();function yr(t,e,n){let r=t.resolve(e);if(!r){let o=t.getPersistedSession(e);if(!o)return`Error: Session "${e}" not found.`;if(o.status==="killed"&&o.lifecycle==="suspended"){let i=n==="completed";if(t.updatePersistedSession(e,{status:i?"completed":"killed",lifecycle:"terminal",runtimeState:"stopped",resumable:!1,killReason:i?"done":"user"}))return i?`Recovered session ${o.name} [${o.sessionId??o.harnessSessionId}] marked as completed. No live process was running.`:`Recovered session ${o.name} [${o.sessionId??o.harnessSessionId}] dismissed. No live process was running.`}return`Session ${o.name} [${o.sessionId??o.harnessSessionId}] is a persisted ${o.status} record with no live process to kill.`}return r.status==="completed"||r.status==="failed"||r.status==="killed"?`Session ${r.name} [${r.id}] is already ${r.status}. No action needed.`:n==="completed"?(r.complete(),`Session ${r.name} [${r.id}] marked as completed.`):(t.kill(r.id),`Session ${r.name} [${r.id}] has been terminated.`)}function pm(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 Ya(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 S?pm(n)?{content:[{type:"text",text:yr(S,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."}]}}}}te();L();function mm(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function kr(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 S?mm(n)?{content:[{type:"text",text:gr(S,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."}]}}}}te();L();ie();Z();var fm=10;function Pi(t){return t instanceof Error?t.message:String(t)}function tt(t){return K(t)??t.harnessSessionId??"unknown-session"}function gm(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return Vn(t)??K(t)??$(t)}function Za(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!$(t)}function hm(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 un(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='${tt(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='${tt(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='${tt(t)}', fork_session=true, prompt='<new task>').`:`Use agent_respond(session='${tt(t)}', message='<next instruction>') to continue the running session.`,o=n?` ${n}`:"";return{text:`Resume unavailable for session ${t.name} [${tt(t)}] (${e}).${o} ${r}`,isError:!0}}async function Xa(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:Vn(e),workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,worktreeStrategy:e.worktreeStrategy,multiTurn:!0,originChannel:e.originChannel,originThreadId:e.originThreadId,originAgentId:e.originAgentId,originSessionKey:e.originSessionKey,route:e.route,permissionMode:e.currentPermissionMode,requestedPermissionMode:e.requestedPermissionMode??e.currentPermissionMode,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy,harness:"harnessName"in e?e.harnessName:e.harness},o=await t.spawnAndAwaitRunning(r,{notifyLaunch:!1});return t.notifySession(o,`▶️ [${o.name}] Relaunched fresh`),{text:`Session ${e.name} was relaunched fresh — it was killed during startup before the harness initialized. New session: ${o.name} [${o.id}].`}}catch(r){return{text:`Error relaunching session ${e.name} [${tt(e)}]: ${Pi(r)}`,isError:!0}}}var ym=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
98
98
 
99
- `;function Za(t){let e=t?.replace(/\s+/g," ").trim();if(e)return se(e,240)}function vi(t){if(t.approvalState==="changes_requested"&&!Sr(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 Sr(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function pm(t){return vi(t)?!1:Sr(t)||t.currentPermissionMode==="plan"}function mm(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 fm(t){return(t.planDecisionVersion??0)+1}function Xa(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:fm(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 el(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function wi(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=Xa(o,"rejected");return n?(el(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 bi(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),o){let s=Xa(o,"changes_requested");n&&el(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function gm(t,e,n,r={}){let o=nn(e);if(!(o.kind==="resume"||Ja(e)))return;let s=!!(r.approve&&pm(e)),l=s?Za(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?Ya(t,e,n):un(e,o.reason);let a={prompt:s?cm+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:dm(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:l,planModeApproved:!0}:{},harness:"harnessName"in e?e.harnessName:e.harness},d=await t.spawnAndAwaitRunning(a,{notifyLaunch:!1});return s?(t.notifySession(d,`👍 [${d.name}] Plan approved (resumed)`,"plan-approved"),{text:`Plan approved for session ${d.name} [${d.id}]. Session resumed in bypassPermissions mode. Use agent_output to see the response.`}):(t.notifySession(d,`▶️ [${d.name}] Auto-resumed`),{text:`Auto-resumed session ${d.name} [${d.id}]. Use agent_output to see the response.`})}catch(a){return un(e,"missing_backend_state",`Backend resume failed: ${Pi(a)}`)}}async function ve(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"}:nn(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?um(e.message):void 0;if(s==="approve")return ve(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return bi(t,n?.id??r?.sessionId??e.session);if(s==="reject")return wi(t,n?.id??r?.sessionId??e.session);if(e.approve){let a=vi(o);if(a)return{text:a,isError:!0}}if(i.kind==="resume"||Ja(o)){let a=await gm(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(a)return a}else{if(i.kind==="relaunch")return Ya(t,o,e.message);if(i.kind==="unavailable")return un(o,i.reason)}if(!n)return tn(r)?un(r,"completed"):{text:`Error: Session ${r.name} [${tt(r)}] is not running (status: ${r.status}). Cannot send a message to a non-running session.`,isError:!0};if(n.status!=="running")return tn(n)?un(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 l=D.maxAutoResponds??lm;if(e.userInitiated)n.resetAutoRespond();else if(n.autoRespondCount>=l)return{text:`⚠️ Auto-respond limit reached (${n.autoRespondCount}/${l}). Ask the user to provide the answer for session ${n.name}. Then call agent_respond with their answer and set userInitiated: true to reset the counter.`};try{if(e.approve){let f=vi(n);if(f)return{text:f,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let h=se(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${h}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let f=se(e.message,80);return{text:[`Pending input answered for session ${n.name} [${n.id}].`,` Message: "${f}"`,"Use agent_output to see the response."].join(`
100
- `)}}let d=!1;e.interrupt&&(d=await n.interrupt());let u=!!(e.approve&&Sr(n)),c=u?Za(e.approvalRationale):void 0,m="";if(e.approve&&Sr(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=c):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?m=`
99
+ `;function el(t){let e=t?.replace(/\s+/g," ").trim();if(e)return se(e,240)}function vi(t){if(t.approvalState==="changes_requested"&&!Sr(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 Sr(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function km(t){return vi(t)?!1:Sr(t)||t.currentPermissionMode==="plan"}function Sm(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 vm(t){return(t.planDecisionVersion??0)+1}function tl(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:vm(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 nl(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function wi(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=tl(o,"rejected");return n?(nl(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 bi(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),o){let s=tl(o,"changes_requested");n&&nl(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function Pm(t,e,n,r={}){let o=nn(e);if(!(o.kind==="resume"||Za(e)))return;let s=!!(r.approve&&km(e)),l=s?el(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?Xa(t,e,n):un(e,o.reason);let a={prompt:s?ym+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:gm(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:l,planModeApproved:!0}:{},harness:"harnessName"in e?e.harnessName:e.harness},d=await t.spawnAndAwaitRunning(a,{notifyLaunch:!1});return s?(t.notifySession(d,`👍 [${d.name}] Plan approved (resumed)`,"plan-approved"),{text:`Plan approved for session ${d.name} [${d.id}]. Session resumed in bypassPermissions mode. Use agent_output to see the response.`}):(t.notifySession(d,`▶️ [${d.name}] Auto-resumed`),{text:`Auto-resumed session ${d.name} [${d.id}]. Use agent_output to see the response.`})}catch(a){return un(e,"missing_backend_state",`Backend resume failed: ${Pi(a)}`)}}async function ve(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"}:nn(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?hm(e.message):void 0;if(s==="approve")return ve(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return bi(t,n?.id??r?.sessionId??e.session);if(s==="reject")return wi(t,n?.id??r?.sessionId??e.session);if(e.approve){let a=vi(o);if(a)return{text:a,isError:!0}}if(i.kind==="resume"||Za(o)){let a=await Pm(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(a)return a}else{if(i.kind==="relaunch")return Xa(t,o,e.message);if(i.kind==="unavailable")return un(o,i.reason)}if(!n)return tn(r)?un(r,"completed"):{text:`Error: Session ${r.name} [${tt(r)}] is not running (status: ${r.status}). Cannot send a message to a non-running session.`,isError:!0};if(n.status!=="running")return tn(n)?un(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 l=D.maxAutoResponds??fm;if(e.userInitiated)n.resetAutoRespond();else if(n.autoRespondCount>=l)return{text:`⚠️ Auto-respond limit reached (${n.autoRespondCount}/${l}). Ask the user to provide the answer for session ${n.name}. Then call agent_respond with their answer and set userInitiated: true to reset the counter.`};try{if(e.approve){let f=vi(n);if(f)return{text:f,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let h=se(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${h}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let f=se(e.message,80);return{text:[`Pending input answered for session ${n.name} [${n.id}].`,` Message: "${f}"`,"Use agent_output to see the response."].join(`
100
+ `)}}let d=!1;e.interrupt&&(d=await n.interrupt());let u=!!(e.approve&&Sr(n)),c=u?el(e.approvalRationale):void 0,m="";if(e.approve&&Sr(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=c):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?m=`
101
101
  ℹ️ approve=true was set but session is already in bypassPermissions mode.`:e.approve?m=`
102
102
  ⚠️ approve=true was set but session has no pending plan approval.`:(n.pendingPlanApproval||n.approvalState==="changes_requested")&&(m=`
103
- ℹ️ Session has a pending plan — sending as revision feedback. The agent will revise and re-submit. Set approve=true to approve instead.`),await n.sendMessage(e.message),u&&mm(t,n),u)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let f=se(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${f}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let p=se(e.message,80);return u?{text:`Plan approved for session ${n.name} [${n.id}]. Use agent_output to see the response.`}:{text:[`Message sent to session ${n.name} [${n.id}].`,d?" (redirected active turn first)":e.interrupt?" (no active turn to interrupt)":"",` Message: "${p}"`,m,"Use agent_output to see the response."].filter(Boolean).join(`
104
- `)}}catch(a){return{text:`Error sending message to session ${n.name} [${n.id}]: ${Pi(a)}`,isError:!0}}}function hm(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 tl(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!hm(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, message, interrupt?, userInitiated?, approve?, approval_rationale? }."}]};let r=await ve(S,{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}]}}}}te();L();function ym(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function nl(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!ym(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=S.requestPlanApprovalFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}te();L();function km(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_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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!km(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=S.requestWorktreeDecisionFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}te();L();ie();var Ri=["off","manual","ask","delegate","auto-merge","auto-pr"],vr=new Set(Ri),Sm=["pr-required","pr-allowed","never-pr","manual"],ol=new Set(Sm),vm=["low","medium","high","xhigh","max"],il=new Set(vm);function Pm(t){return typeof t=="string"&&vr.has(t)}var wm=g.Union(Ri.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 bm(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||Pm(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 Rm(t,e){let n=dt(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 Am(t,e){if(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=Rm(t,e);return!n?.provider||!n.target?{content:[{type:"text",text:"Error: Could not resolve a direct delivery route for the plan offer."}]}:(S.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 sl(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(wm),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 bm(n)?Am(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}te();L();function al(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=S.getMetrics(),o=S.list("running").length;return{content:[{type:"text",text:zn(r,o)}]}}}}te();L();bt();import{execFileSync as Im}from"child_process";var Ii=[{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."}],xm=new Map(Ii.map(t=>[t.policy,t]));function cn(t){return t?Ii:Ii.filter(e=>e.policy==="never-pr"||e.policy==="manual")}function ll(t){return xm.get(t)??{policy:t,label:t,title:t,description:"Custom repo integration policy."}}function Tt(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 Ai(t,e){try{return Im("git",e,{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function dl(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 Tm(t){return dl(t)?.startsWith("https://github.com/")?"github":"unsupported"}function pn(t){let e=Ai(t,["rev-parse","--show-toplevel"]);if(!e)return;let n=Ai(e,["remote","get-url","origin"])??Ai(e,["remote","get-url","upstream"]),r=dl(n),o=Tm(r);return{key:r?`${e}|${r}`:e,repoRoot:e,remoteUrl:r,provider:o}}function ul(t){if(t?.remoteUrl)return t.remoteUrl==="https://github.com/goldmar/openclaw-code-agent"?"pr-required":void 0}function xi(t,e,n="stored",r=new Date().toISOString()){return{key:t.key,policy:e,repoRoot:t.repoRoot,remoteUrl:t.remoteUrl,provider:t.provider,createdAt:r,updatedAt:r,source:n}}function Ti(t){return t.provider==="github"&&Ae()}function cl(t){let e=t.requestedStrategy,n={merge:t.policy!=="pr-required",pr:t.policy!=="never-pr"&&t.prAvailable};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"?{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 Ci(t,e,n=t.provider==="github"){let r=cn(n);return[`Repo integration policy is not set for ${t.repoRoot}.`,"","OCA will create isolated worktrees, but it needs one repo policy before worktree follow-through can run.",`Requested worktree strategy: ${e}`,`Provider: ${t.provider}${n?"":" (PR automation unavailable)"}`,"","Choose one available policy:",...r.map(o=>`- ${o.title}: ${o.description}`),"","If buttons are unavailable, set it manually. OCA will continue the pending launch automatically when exactly one matching launch is waiting; otherwise run the intended launch again:",...r.map(o=>`- agent_repo_policy(workdir="${t.repoRoot}", policy="${o.policy}")`)].join(`
105
- `)}function Cm(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function mn(t){return t?[`Repo policy: ${t.policy}`,`Repo: ${t.repoRoot}`,`Provider: ${t.provider}`,...t.remoteUrl?[`Remote: ${t.remoteUrl}`]:[],`Updated: ${t.updatedAt}`].join(`
106
- `):"No stored repo policy found."}function pl(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(!S)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 l=S.cleanupRepoPolicies();return{content:[{type:"text",text:l.length===0?"No stale repo policies found.":[`Removed ${l.length} stale repo ${l.length===1?"policy":"policies"}.`,...l.map(d=>`${d.policy} | ${d.provider} | ${d.repoRoot}`)].join(`
103
+ ℹ️ Session has a pending plan — sending as revision feedback. The agent will revise and re-submit. Set approve=true to approve instead.`),await n.sendMessage(e.message),u&&Sm(t,n),u)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let f=se(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${f}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let p=se(e.message,80);return u?{text:`Plan approved for session ${n.name} [${n.id}]. Use agent_output to see the response.`}:{text:[`Message sent to session ${n.name} [${n.id}].`,d?" (redirected active turn first)":e.interrupt?" (no active turn to interrupt)":"",` Message: "${p}"`,m,"Use agent_output to see the response."].filter(Boolean).join(`
104
+ `)}}catch(a){return{text:`Error sending message to session ${n.name} [${n.id}]: ${Pi(a)}`,isError:!0}}}function wm(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 rl(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!wm(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, message, interrupt?, userInitiated?, approve?, approval_rationale? }."}]};let r=await ve(S,{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}]}}}}te();L();function bm(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function ol(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!bm(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=S.requestPlanApprovalFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}te();L();function Rm(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function il(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Rm(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=S.requestWorktreeDecisionFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}te();L();ie();var Ri=["off","manual","ask","delegate","auto-merge","auto-pr"],vr=new Set(Ri),Am=["pr-required","pr-allowed","never-pr","manual"],sl=new Set(Am),Im=["low","medium","high","xhigh","max"],al=new Set(Im);function xm(t){return typeof t=="string"&&vr.has(t)}var Tm=g.Union(Ri.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 Cm(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||xm(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 Mm(t,e){let n=dt(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 _m(t,e){if(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=Mm(t,e);return!n?.provider||!n.target?{content:[{type:"text",text:"Error: Could not resolve a direct delivery route for the plan offer."}]}:(S.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 ll(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(Tm),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 Cm(n)?_m(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}te();L();function dl(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=S.getMetrics(),o=S.list("running").length;return{content:[{type:"text",text:zn(r,o)}]}}}}te();L();bt();import{execFileSync as $m}from"child_process";var Ii=[{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."}],Em=new Map(Ii.map(t=>[t.policy,t]));function cn(t){return t?Ii:Ii.filter(e=>e.policy==="never-pr"||e.policy==="manual")}function ul(t){return Em.get(t)??{policy:t,label:t,title:t,description:"Custom repo integration policy."}}function Tt(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 xi(t){let{policy:e,prAvailable:n}=t;return{merge:e!=="pr-required"&&e!=="manual",pr:e!=="never-pr"&&e!=="manual"&&n}}function Ai(t,e){try{return $m("git",e,{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function cl(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 Dm(t){return cl(t)?.startsWith("https://github.com/")?"github":"unsupported"}function pn(t){let e=Ai(t,["rev-parse","--show-toplevel"]);if(!e)return;let n=Ai(e,["remote","get-url","origin"])??Ai(e,["remote","get-url","upstream"]),r=cl(n),o=Dm(r);return{key:r?`${e}|${r}`:e,repoRoot:e,remoteUrl:r,provider:o}}function pl(t){if(t?.remoteUrl)return t.remoteUrl==="https://github.com/goldmar/openclaw-code-agent"?"pr-required":void 0}function Ti(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 Ci(t){return t.provider==="github"&&Ae()}function ml(t){let e=t.requestedStrategy,n=xi(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"?{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 Mi(t,e,n=t.provider==="github"){let r=cn(n);return[`Repo integration policy is not set for ${t.repoRoot}.`,"","OCA will create isolated worktrees, but it needs one repo policy before worktree follow-through can run.",`Requested worktree strategy: ${e}`,`Provider: ${t.provider}${n?"":" (PR automation unavailable)"}`,"","Choose one available policy:",...r.map(o=>`- ${o.title}: ${o.description}`),"","If buttons are unavailable, set it manually. OCA will continue the pending launch automatically when exactly one matching launch is waiting; otherwise run the intended launch again:",...r.map(o=>`- agent_repo_policy(workdir="${t.repoRoot}", policy="${o.policy}")`)].join(`
105
+ `)}function Om(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function mn(t){return t?[`Repo policy: ${t.policy}`,`Repo: ${t.repoRoot}`,`Provider: ${t.provider}`,...t.remoteUrl?[`Remote: ${t.remoteUrl}`]:[],`Updated: ${t.updatedAt}`].join(`
106
+ `):"No stored repo policy found."}function fl(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(!S)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 l=S.cleanupRepoPolicies();return{content:[{type:"text",text:l.length===0?"No stale repo policies found.":[`Removed ${l.length} stale repo ${l.length===1?"policy":"policies"}.`,...l.map(d=>`${d.policy} | ${d.provider} | ${d.repoRoot}`)].join(`
107
107
  `)}]}}if(r.list===!0){let l=S.listRepoPolicies();return{content:[{type:"text",text:l.length===0?"No stored repo policies.":l.map(d=>`${d.policy} | ${d.provider} | ${d.repoRoot}${d.remoteUrl?` | ${d.remoteUrl}`:""}`).join(`
108
- `)}]}}let o=r.workdir??t?.workspaceDir;if(!o)return{content:[{type:"text",text:"Error: workdir is required when no workspace directory is available."}]};if(r.reset===!0)return{content:[{type:"text",text:S.resetRepoPolicy(o)?`Repo policy reset for ${o}.`:`No stored repo policy found for ${o}.`}]};if(r.policy!==void 0){if(!Cm(r.policy))return{content:[{type:"text",text:"Error: policy must be one of pr-required, pr-allowed, never-pr, manual."}]};if(typeof S.resolveRepoPolicy=="function"){let d=S.resolveRepoPolicy(o);if(d.identity){let u=Tt(r.policy,d.prAvailable);if(u)return{content:[{type:"text",text:`Error: ${u}`}]}}}let l=S.setRepoPolicy(o,r.policy);if(!l)return{content:[{type:"text",text:`Error: ${o} is not a git repository.`}]};let a;try{a=typeof S.continueLaunchAfterManualRepoPolicy=="function"?S.continueLaunchAfterManualRepoPolicy(l.repoRoot,r.policy):{kind:"none"}}catch(d){let u=d instanceof Error?d.message:String(d);return{content:[{type:"text",text:[mn(l),"",`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(`
108
+ `)}]}}let o=r.workdir??t?.workspaceDir;if(!o)return{content:[{type:"text",text:"Error: workdir is required when no workspace directory is available."}]};if(r.reset===!0)return{content:[{type:"text",text:S.resetRepoPolicy(o)?`Repo policy reset for ${o}.`:`No stored repo policy found for ${o}.`}]};if(r.policy!==void 0){if(!Om(r.policy))return{content:[{type:"text",text:"Error: policy must be one of pr-required, pr-allowed, never-pr, manual."}]};if(typeof S.resolveRepoPolicy=="function"){let d=S.resolveRepoPolicy(o);if(d.identity){let u=Tt(r.policy,d.prAvailable);if(u)return{content:[{type:"text",text:`Error: ${u}`}]}}}let l=S.setRepoPolicy(o,r.policy);if(!l)return{content:[{type:"text",text:`Error: ${o} is not a git repository.`}]};let a;try{a=typeof S.continueLaunchAfterManualRepoPolicy=="function"?S.continueLaunchAfterManualRepoPolicy(l.repoRoot,r.policy):{kind:"none"}}catch(d){let u=d instanceof Error?d.message:String(d);return{content:[{type:"text",text:[mn(l),"",`Repo policy saved, but the deferred launch failed: ${u}`,"The pending launch context was kept so you can retry the same agent_repo_policy call or run the intended launch again."].join(`
109
109
  `)}]}}return a.kind==="launched"?{content:[{type:"text",text:[mn(l),"",a.text].join(`
110
110
  `)}]}:a.kind==="ambiguous"?{content:[{type:"text",text:[mn(l),"",`Repo policy saved, but ${a.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
111
111
  `)}]}:{content:[{type:"text",text:mn(l)}]}}let i=S.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:mn(s)}]}:{content:[{type:"text",text:["Repo policy: unknown",`Repo: ${i.identity.repoRoot}`,`Provider: ${i.provider}${i.prAvailable?"":" (PR automation unavailable)"}`,...i.identity.remoteUrl?[`Remote: ${i.identity.remoteUrl}`]:[]].join(`
112
- `)}]}}}}te();ie();L();he();fn();hn();import{existsSync as xr}from"fs";function _m(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function $m(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 Em(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 Tr(t){return{name:"agent_merge",description:"Merge a worktree branch back to the base branch. Resolves session (active or persisted), gets worktree path, and performs the merge. On conflict, spawns a conflict-resolver session using the configured default harness.",parameters: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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!_m(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=Mt(S,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:l,branchName:a}=r;if(!s||!l)return{content:[{type:"text",text:`Error: Session "${n.session}" does not have a worktree.`}]};if(!a)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.`}]};xr(s)||`${s}${l}`;let d=l;if(!xr(l))return{content:[{type:"text",text:`Error: originalWorkdir "${l}" does not exist.`}]};let u=n.base_branch??Te(d),c=u,m=n.strategy??"merge",p=n.push===!0,f=n.delete_branch!==!1,h=S.resolveRepoPolicy(d);if(h?.policy==="pr-required")return{content:[{type:"text",text:`❌ Merge blocked: repo policy requires a pull request for ${h.identity?.repoRoot??d}. Use agent_pr if PR automation is available.`}]};if(i?.worktreeLifecycle?.state==="merged"||i?.worktreeMerged)return{content:[{type:"text",text:`ℹ️ Session "${n.session}" is already merged.`}]};if((xr(s)?an(d,a,c):void 0)===0&&At(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${a} has no commits ahead of ${c}.`,`Worktree: ${s}`,"Resume or inspect the session, then commit real task changes or clean temporary files before retrying agent_merge."].join(`
113
- `)}]};let v={content:[{type:"text",text:"❌ Merge did not run (internal error)"}]};return await S.enqueueMerge(d,async()=>{let I=S.getPersistedSession(n.session);if(I?.worktreeLifecycle?.state==="merged"||I?.worktreeMerged){v={content:[{type:"text",text:`ℹ️ Session "${n.session}" was already merged while waiting in queue.`}]};return}let x=Ee(d,a,u),w=cr(d,a,c,m,s),A=It(w);if(w.success){let y=$m({mergeResult:w,repoDir:d,baseBranch:c});if(p&&!ur(d,c)){let N=`⚠️ Merged ${a} → ${c} locally, but failed to push ${c}`;S.notifyWorktreeOutcome(r.notificationTarget,N,{detailLines:[`Branch ${a} was merged into ${c} in the local repository.`,`Pushing ${c} failed; remote state may not include the merge.`,"Cleanup was skipped so the branch/worktree remains available for follow-up.",...y,...A]}),v={content:[{type:"text",text:Ce(N,w)}]};return}let b=!1,V=!1,E=!xr(s);V=E?!0:ce(d,s),lr(d),f&&(b=Se(d,a));let T=Em({deleteBranchRequested:f,branchDeleted:b,worktreeCleanedUp:V,worktreeAlreadyAbsent:E});if(I){let N=new Date().toISOString();for(let oe of gn({...r,persistedSession:I}))S.updatePersistedSession(oe,{...Ct({worktreeBaseBranch:u,worktreePrTargetRepo:I.worktreePrTargetRepo,worktreePushRemote:I.worktreePushRemote},{mergedAt:N,updatedAt:N,resolvedAt:N,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let C=et({kind:"merge",branch:a,base:u,filesChanged:x?.filesChanged,insertions:x?.insertions,deletions:x?.deletions});S.notifyWorktreeOutcome(r.notificationTarget,C,{detailLines:[w.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",p?`Pushed ${c}.`:`Did not push ${c}; push was not requested.`,T.detailLine,...y,...A]});let W=`✅ ${w.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${a} → ${c}.${p?" Pushed.":""}${T.summaryFragment}`;w.stashPopConflict?W+=`
112
+ `)}]}}}}te();ie();L();he();fn();hn();import{existsSync as xr}from"fs";function Nm(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Lm(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 Bm(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 Tr(t){return{name:"agent_merge",description:"Merge a worktree branch back to the base branch. Resolves session (active or persisted), gets worktree path, and performs the merge. On conflict, spawns a conflict-resolver session using the configured default harness.",parameters: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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Nm(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=Mt(S,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:l,branchName:a}=r;if(!s||!l)return{content:[{type:"text",text:`Error: Session "${n.session}" does not have a worktree.`}]};if(!a)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.`}]};xr(s)||`${s}${l}`;let d=l;if(!xr(l))return{content:[{type:"text",text:`Error: originalWorkdir "${l}" does not exist.`}]};let u=n.base_branch??Te(d),c=u,m=n.strategy??"merge",p=n.push===!0,f=n.delete_branch!==!1,h=S.resolveRepoPolicy(d);if(h?.policy==="pr-required")return{content:[{type:"text",text:`❌ Merge blocked: repo policy requires a pull request for ${h.identity?.repoRoot??d}. Use agent_pr if PR automation is available.`}]};if(i?.worktreeLifecycle?.state==="merged"||i?.worktreeMerged)return{content:[{type:"text",text:`ℹ️ Session "${n.session}" is already merged.`}]};if((xr(s)?an(d,a,c):void 0)===0&&At(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${a} has no commits ahead of ${c}.`,`Worktree: ${s}`,"Resume or inspect the session, then commit real task changes or clean temporary files before retrying agent_merge."].join(`
113
+ `)}]};let v={content:[{type:"text",text:"❌ Merge did not run (internal error)"}]};return await S.enqueueMerge(d,async()=>{let I=S.getPersistedSession(n.session);if(I?.worktreeLifecycle?.state==="merged"||I?.worktreeMerged){v={content:[{type:"text",text:`ℹ️ Session "${n.session}" was already merged while waiting in queue.`}]};return}let x=Ee(d,a,u),w=cr(d,a,c,m,s),A=It(w);if(w.success){let y=Lm({mergeResult:w,repoDir:d,baseBranch:c});if(p&&!ur(d,c)){let N=`⚠️ Merged ${a} → ${c} locally, but failed to push ${c}`;S.notifyWorktreeOutcome(r.notificationTarget,N,{detailLines:[`Branch ${a} was merged into ${c} in the local repository.`,`Pushing ${c} failed; remote state may not include the merge.`,"Cleanup was skipped so the branch/worktree remains available for follow-up.",...y,...A]}),v={content:[{type:"text",text:Ce(N,w)}]};return}let b=!1,V=!1,E=!xr(s);V=E?!0:ce(d,s),lr(d),f&&(b=Se(d,a));let T=Bm({deleteBranchRequested:f,branchDeleted:b,worktreeCleanedUp:V,worktreeAlreadyAbsent:E});if(I){let N=new Date().toISOString();for(let oe of gn({...r,persistedSession:I}))S.updatePersistedSession(oe,{...Ct({worktreeBaseBranch:u,worktreePrTargetRepo:I.worktreePrTargetRepo,worktreePushRemote:I.worktreePushRemote},{mergedAt:N,updatedAt:N,resolvedAt:N,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let C=et({kind:"merge",branch:a,base:u,filesChanged:x?.filesChanged,insertions:x?.insertions,deletions:x?.deletions});S.notifyWorktreeOutcome(r.notificationTarget,C,{detailLines:[w.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",p?`Pushed ${c}.`:`Did not push ${c}; push was not requested.`,T.detailLine,...y,...A]});let W=`✅ ${w.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${a} → ${c}.${p?" Pushed.":""}${T.summaryFragment}`;w.stashPopConflict?W+=`
114
114
  ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${w.stashRef??"stash@{0}"}\` in ${d} to review stashed changes.`:w.stashed&&(W+=`
115
115
  (Pre-existing changes on ${c} were auto-stashed and restored.)`),W=Ce(W,w),v={content:[{type:"text",text:W}]}}else if(w.rebaseConflict)v={content:[{type:"text",text:Ce(`⚠️ Rebase conflicts — manual resolution required:
116
116
 
117
117
  ${w.error}`,w)}]};else if(w.conflictFiles&&w.conflictFiles.length>0){let y=["Resolve merge conflicts in the following files and commit the resolution:","",...w.conflictFiles.map(b=>`- ${b}`),"",`After resolving, commit with message: "Resolve merge conflicts from ${a}"`].join(`
118
- `);try{let b=S.spawn({prompt:y,workdir:d,name:`${n.session}-conflict-resolver`,harness:ae(),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});v={content:[{type:"text",text:Ce(`⚠️ Merge conflicts in ${w.conflictFiles.length} file(s) — spawned conflict resolver session: ${b.name}`,w)}]}}catch(b){v={content:[{type:"text",text:Ce(`❌ Merge conflicts detected, but failed to spawn resolver: ${b instanceof Error?b.message:String(b)}`,w)}]}}}else{let y=w.dirtyError?`❌ Merge blocked: ${w.error}`:`❌ Merge failed: ${w.error??"unknown error"}`;v={content:[{type:"text",text:Ce(y,w)}]}}}),v}}}Er();te();L();Z();he();hn();function qm(t){return!!t&&typeof t=="object"}function Pl(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!qm(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 S.dismissWorktree(r)}]};let l=Rr(S);if(r&&(l=l.filter(p=>Ar(p,r)),l.length===0)){let p=Mt(S,r);if(!p.persistedSession&&!p.activeSession)return{content:[{type:"text",text:`Error: Session "${r}" not found.`}]}}if(n.workdir&&(l=l.filter(p=>p.workdir===n.workdir)),l.length===0)return{content:[{type:"text",text:"No managed worktrees matched the requested scope."}]};let a=[],d=[],u=[],c=[];for(let p of l){let{persistedSession:f,activeSession:h,resolvedLifecycle:k}=br(S,p,{baseBranch:n.base_branch});if(!k.cleanupSafe){if(s){let v=k.reasons.length>0?k.reasons.map(Ir).join(", "):nt(k.derivedState);d.push(`${p.name} [kept: ${v}]`)}continue}if(a.push(`${p.name} (${nt(k.derivedState)})`),!i)try{let v=p.workdir;if(!((f??h)&&le(f??h))&&p.worktreePath&&ce(v,p.worktreePath,{destructive:!1}),p.worktreeBranch&&Se(v,p.worktreeBranch),f){let x=k.derivedState==="merged"||k.derivedState==="released"?k.derivedState:k.lifecycle.state,w=new Date().toISOString(),A=x==="merged"?f.worktreeMergedAt:x==="dismissed"?f.worktreeDismissedAt:void 0;S.updatePersistedSession(p.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeMerged:x==="merged"?!0:f.worktreeMerged,worktreeMergedAt:x==="merged"?f.worktreeMergedAt??w:f.worktreeMergedAt,worktreeLifecycle:{...f.worktreeLifecycle??k.lifecycle,state:x,updatedAt:w,resolvedAt:f.worktreeLifecycle?.resolvedAt??A??w,resolutionSource:f.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??k.lifecycle.baseBranch??f.worktreeBaseBranch,targetRepo:f.worktreePrTargetRepo,pushRemote:f.worktreePushRemote,notes:k.reasons}})}u.push(`${p.name} (${nt(k.derivedState)})`)}catch(v){c.push(`${p.name}: ${v instanceof Error?v.message:String(v)}`)}}let m=[o==="clean_safe"?"Clean all safe:":o==="preview_all"?"Worktree lifecycle review:":"Clean all safe preview:"];return m.push(` SAFE ${i?"NOW":"FOUND"} (${a.length}): ${a.join(", ")||"(none)"}`),s&&m.push(` KEPT (${d.length}): ${d.join(", ")||"(none)"}`),i||(m.push(` CLEANED (${u.length}): ${u.join(", ")||"(none)"}`),m.push(` FAILURES (${c.length}): ${c.join(", ")||"(none)"}`)),{content:[{type:"text",text:m.join(`
119
- `)}]}}}}te();L();hn();function Km(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 wl(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Km(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n&&typeof n=="object"?n.session:void 0,o=Rr(S);if(r&&(o=o.filter(s=>Ar(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:l,resolvedLifecycle:a}=br(S,s),d=a.cleanupSafe?"safe now":a.preserve?"preserve":"blocked";i.push(`Session: ${s.name} [${s.id}]`),i.push(` Branch: ${s.worktreeBranch??"(unknown)"} → ${a.lifecycle.baseBranch??l?.worktreeBaseBranch??"main"}`),i.push(` Repo: ${s.workdir}`),i.push(` Lifecycle:${nt(a.lifecycle.state)}`),a.derivedState!==a.lifecycle.state&&i.push(` Derived: ${nt(a.derivedState)}`),i.push(` Cleanup: ${d}`),a.evidence.prUrl&&i.push(` PR: ${a.evidence.prUrl} (${a.evidence.prState??"unknown"})`),(a.evidence.branchAheadCount!=null||a.evidence.baseAheadCount!=null)&&i.push(` Ahead: ${a.evidence.branchAheadCount??0} ahead / ${a.evidence.baseAheadCount??0} behind`),i.push(` Reasons: ${a.reasons.length>0?a.reasons.map(Ir).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
120
- `).trim()}]}}}}te();L();ie();import{existsSync as Um}from"fs";function Vm(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function Dr(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(!Um(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=Vm(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??ae(),l=t.model??at(s),a=Tn(s);if(!l&&(s!=="opencode"||a&&a.length>0))return{kind:"error",text:`Error: No default model configured for harness "${s}". Set plugins.entries["openclaw-code-agent"].config.harnesses.${s}.defaultModel or pass model explicitly.`};if(l&&!Gn(l,a))return{kind:"error",text:`Error: Model "${l}" is not allowed. Permitted models: ${a?.join(", ")}`};let d=e.sessionKey||void 0,u=Cn(e),c=zt(e,u||ze(r)),m=dt(e,c,d);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:l,reasoningEffort:Le(s),fastMode:lt(s),systemPrompt:t.systemPrompt,allowedTools:t.allowedTools,maxIterations:t.maxIterations,permissionMode:t.permissionMode??"bypassPermissions",harness:s,loopMode:i,completionPromise:t.completionPromise,originChannel:c,originThreadId:m?.threadId,originAgentId:e.agentId||void 0,originSessionKey:d,route:m,verifierCommands:o}}function Or(t,e){return["Goal task launched.",` Name: ${t.name}`,` ID: ${t.id}`,` Dir: ${t.workdir}`,` Session: ${t.sessionName} [${t.sessionId}]`,` Harness: ${e.harness}`,` Model: ${e.model??"default"}`,...e.fastMode?[" Fast mode: enabled"]:[],` Loop mode: ${t.loopMode}`,` Max controller iterations: ${t.maxIterations}`,` Goal: "${e.goal.length>100?`${e.goal.slice(0,100)}...`:e.goal}"`,...t.loopMode==="ralph"?[` Completion promise: ${t.completionPromise}`]:[" Verifiers:",...e.verifierCommands.map(r=>` - ${r.command}`)],"","Controller iteration progress advances only when the goal controller starts another agent turn; internal agent review passes are reported in the completion summary.","","Use goal_status to follow progress or goal_stop to terminate the task."].join(`
121
- `)}function Gm(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function bl(t){return{name:"goal_launch",description:"Launch an explicit goal loop. Use this only when the user specifically asks for a goal task, Ralph-style autonomous loop, iterative loop, autonomous repair loop, or keep-going-until-checks-pass workflow. This is not the default session path.",parameters:g.Object({goal:g.String({description:"End goal for the autonomous task"}),verifier_commands:g.Optional(g.Array(g.String({description:"Shell command that must pass for the goal to be considered complete"}),{minItems:1,description:"Verifier commands run after each coding turn"})),name:g.Optional(g.String({description:"Short task name (kebab-case preferred)"})),workdir:g.Optional(g.String({description:"Working directory (defaults to cwd / configured workspace)"})),model:g.Optional(g.String({description:"Model name to use"})),system_prompt:g.Optional(g.String({description:"Additional system prompt"})),allowed_tools:g.Optional(g.Array(g.String(),{description:"Allowed tools for the underlying agent session"})),max_iterations:g.Optional(g.Number({description:"Maximum verifier-driven repair iterations",minimum:1})),goal_mode:g.Optional(g.Union([g.Literal("ralph"),g.Literal("verifier")],{description:"Loop strategy. 'ralph' repeats until a completion promise appears. 'verifier' repeats until verifier commands pass. Defaults to 'ralph' when no verifiers are provided, otherwise 'verifier'."})),completion_promise:g.Optional(g.String({description:"Exact completion promise for Ralph-mode loops. Defaults to 'DONE'."})),permission_mode:g.Optional(g.Union([g.Literal("default"),g.Literal("plan"),g.Literal("bypassPermissions")],{description:"Permission mode for the underlying agent session. Defaults to bypassPermissions for autonomous goal loops."})),harness:g.Optional(g.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode')."}))}),async execute(e,n){if(!j)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!Gm(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=Dr({goal:n.goal,verifierCommands:n.verifier_commands,name:n.name,workdir:n.workdir,model:n.model,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,maxIterations:n.max_iterations,permissionMode:n.permission_mode,harness:n.harness,goalMode:n.goal_mode,completionPromise:n.completion_promise},t);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};try{let o=await j.launchTask({goal:r.goal,name:r.name,workdir:r.workdir,model:r.model,reasoningEffort:r.reasoningEffort,fastMode:r.fastMode,systemPrompt:r.systemPrompt,allowedTools:r.allowedTools,maxIterations:r.maxIterations,permissionMode:r.permissionMode,loopMode:r.loopMode,completionPromise:r.completionPromise,originChannel:r.originChannel,originThreadId:r.originThreadId,originAgentId:r.originAgentId,originSessionKey:r.originSessionKey,route:r.route,harness:r.harness,verifierCommands:r.verifierCommands});return{content:[{type:"text",text:Or(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}te();function Oi(t,e){return t.split(`
122
- `).map(n=>`${e}${n}`)}function Rl(t,e){return t.length<=e?t:`${t.slice(0,e-3).trimEnd()}...`}function jm(t,e=8,n=600){let r=t.map(i=>i.trimEnd()).filter(i=>i.trim().length>0);if(r.length===0)return;let o=r.slice(-e).join(`
123
- `);return o.length<=n?o:`...${o.slice(-(n-3))}`}function Hm(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=>Rl(o,180))}function zm(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=>Rl(n,180))}function Wr(t){let e=[],n=zm(t.verifierSummary),r=Hm(t.output,t.completionPromise);if(n.length===0&&r.length===0)return;t.completionDetected===!0&&e.push("Completion was claimed, but the loop is continuing after verification.");for(let i of n)e.push(`Verifier: ${i}`);let o=Math.max(0,3-e.length);if(o>0)for(let i of r.slice(-o))e.push(`Agent: ${i}`);return["Iteration summary:",...e.map(i=>`- ${i}`)].join(`
124
- `)}function Wi(t){if(t)return{phase:t.phase,awaitingInput:t.isAwaitingInput??!!t.pendingInputState,latestOutput:jm(t.getOutput(20))}}function Ni(t,e,n){let r=t.loopMode??"verifier",o=[`${t.name} [${t.id}]`,` Status: ${t.status}`,...r==="ralph"?[" Loop mode: ralph",` Iteration: ${t.iteration}/${t.maxIterations}`]:[` Repair iteration: ${t.iteration}/${t.maxIterations}`],` Workdir: ${t.workdir}`];return r==="ralph"&&t.completionPromise&&o.push(` Completion promise: ${t.completionPromise}`),t.sessionId&&o.push(` Session: ${t.sessionName??"(unknown)"} [${t.sessionId}]`),e?.phase&&o.push(` Phase: ${e.phase}`),e?.awaitingInput!==void 0&&o.push(` Awaiting input: ${e.awaitingInput?"yes":"no"}`),n&&o.push(...Oi(n," ")),t.lastVerifierSummary&&(o.push(" Last verifier:"),o.push(...Oi(t.lastVerifierSummary," "))),e?.latestOutput&&(o.push(" Latest activity:"),o.push(...Oi(e.latestOutput," "))),t.waitingForUserReason&&o.push(` Waiting on user: ${t.waitingForUserReason}`),t.failureReason&&o.push(` Failure: ${t.failureReason}`),o.join(`
125
- `)}var Pe="Error: GoalController not initialized. The code-agent service must be running.";function Nr(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 Ni(i,Wi(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 Ni(i,Wi(s))}).join(`
126
-
127
- `)}function Lr(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 Br(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.`}}L();function Al(t){return{name:"goal_status",description:"Show status for explicit goal tasks managed by the goal controller. Use this to inspect one goal task or list all goal tasks.",parameters:g.Object({task:g.Optional(g.String({description:"Task name or ID. Omit to list all tasks."}))}),async execute(e,n){if(!j)return{content:[{type:"text",text:Pe}]};let r=n&&typeof n=="object"&&typeof n.task=="string"?n.task:void 0;return{content:[{type:"text",text:Nr(j,o=>S?.resolve(o),r)}]}}}}te();L();function Qm(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function Il(t){return{name:"goal_stop",description:"Stop an explicit goal task and kill its underlying agent session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"})}),async execute(e,n){if(!j)return{content:[{type:"text",text:Pe}]};if(!Qm(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=j.stopTask(n.task);return{content:[{type:"text",text:Lr(r,n.task)}]}}}}te();L();function Jm(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function xl(t){return{name:"goal_edit",description:"Edit the goal text for an active goal task without stopping or relaunching its session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"}),goal:g.String({description:"Replacement goal text"})}),async execute(e,n){if(!j)return{content:[{type:"text",text:Pe}]};if(!Jm(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=j.editTask(n.task,n.goal);return{content:[{type:"text",text:Br(r,n.task)}]}}}}L();Er();import{createHash as Ym}from"crypto";var ye="code-agent";var Zm=new Set(["1","true","yes","on"]);function Bi(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&Zm.has(t))}function $t(t){if(!(typeof t!="string"||t.length===0))return Ym("sha256").update(t).digest("hex").slice(0,12)}function Tl(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function z(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=Tl(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>$t(Tl(r))):void 0,buttonStyles:n.length>0?n.map(r=>typeof r.style=="string"?r.style:void 0):void 0}}function Ue(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Ml(t){let e=Ue(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(n)return n.map(r=>Ue(r)?.type).filter(r=>typeof r=="string"&&r.length>0)}function _l(t){let e=Ue(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(!n)return;let r=n.map(o=>{let i=Ue(o);return i?.type!=="buttons"||!Array.isArray(i.buttons)?[]:i.buttons}).filter(o=>o.length>0);return r.length>0?r:void 0}function Fi(t){let e=_l(t);return{presentationBlockTypes:Ml(t),...z(e)}}function qi(t){let e=Ue(t),n=e?.interactive,r=Ue(e?.channelData),o=Ue(r?.telegram),i=Array.isArray(o?.buttons)?o.buttons:void 0;return{renderedPayloadKeys:e?Object.keys(e).sort():void 0,interactiveBlockTypes:Ml(n),...Cl("interactive",z(_l(n))),...Cl("telegramChannelData",z(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function $l(t){let e=Ue(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:Li(e.messageId),chatId:Li(e.chatId),telegramThreadId:Li(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function Li(t){return typeof t=="string"||typeof t=="number"?t:void 0}function Cl(t,e){let n={};for(let[r,o]of Object.entries(e))o!==void 0&&(n[`${t}${r.charAt(0).toUpperCase()}${r.slice(1)}`]=o);return n}function B(t,e){if(!Bi())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:ye,...n})}`}function Xm(t){let e=t.trim().replace(new RegExp(`^${ye}:`),"");return e||null}async function Fr(t,e=!1){if(t.channel==="telegram")try{return(await X(t,{alreadyAcknowledged:e,forceTelegramMarkupEdit:!0})).textDelivered}catch(r){let o=r instanceof Error?r.message:String(r);return`${o}`,!1}let n=t.respond;if(typeof n.clearComponents=="function")try{return await n.clearComponents(),!1}catch(r){if(Et(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}function qr(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 El(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return Ki(qr(t))}function Ki(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function ef(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function tf(...t){let e;for(let n of t)n!=null&&(e=e==null?n:Math.max(e,n));return e}function nf(t){if(t.actionablePlanDecisionVersion!=null)return t.actionablePlanDecisionVersion;let e=tf(t.approvalPromptRequiredVersion,t.approvalPromptVersion);return e??t.canonicalPlanPromptVersion??t.planDecisionVersion}function rf(t,e){if(!ef(t.kind))return;if(!e)return"This plan decision is stale because the session is no longer available.";let n=nf(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 of(t){let e="callback"in t?t.callback?.payload??t.callback?.data:void 0,n="interaction"in t?t.interaction?.payload:void 0;return e??n??""}function Et(t){let e=t instanceof Error?t.message:String(t);return/message is not modified/i.test(e)}function sf(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function X(t,e={}){let n=t.respond,{alreadyAcknowledged:r=!1,forceTelegramMarkupEdit:o=!1,text:i}=e;if(t.channel==="telegram"){if(typeof i=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:i,buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0}}catch(l){if(Et(l))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0};let a=l instanceof Error?l.message:String(l);`${a}`}if(o&&typeof n.editButtons=="function")try{return await n.editButtons({buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}catch(l){if(Et(l))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1};let a=l instanceof Error?l.message:String(l);`${a}`}let s="callback"in t&&typeof t.callback?.messageText=="string"?t.callback.messageText:void 0;if(o&&typeof s=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:s,buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}catch(l){if(Et(l))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1};let a=l instanceof Error?l.message:String(l);`${a}`}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}if(typeof n.clearComponents=="function")try{return await n.clearComponents(typeof i=="string"?{text:i}:void 0),{textDelivered:typeof i=="string"}}catch(s){if(Et(s))return{textDelivered:typeof i=="string"};if(sf(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 l=s instanceof Error?s.message:String(s);`${l}`}}}if(typeof i=="string"&&typeof n.editMessage=="function"){try{await n.editMessage({text:i})}catch(s){if(Et(s))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0};let l=s instanceof Error?s.message:String(s);return`${l}`,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 af(t){let e=t.respond;if(typeof e.acknowledge!="function")return!1;try{return await e.acknowledge(),!0}catch(n){let r=n instanceof Error?n.message:String(n);return`${r}`,!1}}async function U(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}function Dl(t="telegram",e={}){let n=e.makeAgentMergeTool??Tr,r=e.makeAgentPrTool??Sn;return B("callback_handler_registered",{channel:t,namespace:ye}),{channel:t,namespace:ye,handler:async o=>{let i=await af(o);if(!o.auth.isAuthorizedSender)return await U(o,"⛔ Unauthorized."),{handled:!0};let s=of(o),l=Xm(s);if(B("callback_received",{channel:o.channel,namespace:ye,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:$t(l),isAuthorizedSender:o.auth.isAuthorizedSender}),!l)return await U(o,"⚠️ Unrecognized callback payload."),{handled:!0};if(!S)return await U(o,"⚠️ Code agent service not running."),{handled:!0};let a=S.getActionToken(l);if(B("callback_token_lookup_completed",{channel:o.channel,namespace:ye,tokenHash:$t(l),tokenFound:!!a,actionKind:a?.kind,sessionId:a?.sessionId,planDecisionVersion:a?.planDecisionVersion}),!a)return await X(o,{alreadyAcknowledged:i}),o.channel!=="telegram"&&await U(o,"⚠️ This action is stale or has already been used."),{handled:!0};let d=a.sessionId,u=S.resolve?.(d)??S.getPersistedSession?.(d),c=u?.name??d,m=rf(a,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:ye,tokenHash:$t(l),actionKind:a.kind,sessionId:d,sessionName:c,planDecisionVersion:a.planDecisionVersion,valid:!m}),m)return await X(o,{alreadyAcknowledged:i}),await U(o,`⚠️ ${m}`),{handled:!0};let p=S.consumeActionToken(l);if(B("callback_token_consume_completed",{channel:o.channel,namespace:ye,tokenHash:$t(l),consumed:!!p,actionKind:p?.kind,sessionId:p?.sessionId,planDecisionVersion:p?.planDecisionVersion}),!p)return await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:a.kind==="plan-offer-start"||a.kind==="plan-offer-dismiss"}),o.channel!=="telegram"&&await U(o,"⚠️ This action is stale or has already been used."),{handled:!0};switch(p.kind){case"worktree-merge":{let f=await n().execute("callback",{session:d}),h=qr(f);if(El(f)){await Fr(o,i);break}await U(o,h);break}case"worktree-decide-later":{let f=S.snoozeWorktreeDecision(d,{notifyUser:!1});if(Ki(f)){let k=`⏭️ Snoozed 24h for [${c}]`;await Fr(o,i),await U(o,k)}else await U(o,f);break}case"worktree-dismiss":{let f=await S.dismissWorktree(d),h=Ki(f);h&&await Fr(o,i),await U(o,h?"✅ Discarded":f);break}case"worktree-create-pr":case"worktree-update-pr":{let f=await r().execute("callback",{session:d}),h=qr(f);if(El(f)){await Fr(o,i);break}await U(o,h);break}case"worktree-view-pr":{await X(o,{alreadyAcknowledged:i});let f=S.getPersistedSession?.(d),h=a.targetUrl??f?.worktreePrUrl;await U(o,h?`PR: ${h}`:"⚠️ PR URL is no longer available.");break}case"plan-approve":{await X(o,{alreadyAcknowledged:i}),S.clearPlanDecisionTokens(d);let f=await ve(S,{session:d,message:"Approved. Go ahead.",approve:!0,userInitiated:!0});f.isError&&await U(o,`⚠️ ${f.text}`);break}case"plan-reject":{await X(o,{alreadyAcknowledged:i});let f=wi(S,d);await U(o,`❌ ${f.text}`);break}case"plan-request-changes":{await X(o,{alreadyAcknowledged:i});let f=bi(S,d);await U(o,`✏️ ${f.text}`);break}case"plan-offer-start":{if(!p.launchPrompt||!p.launchWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,"⚠️ This action is missing the plan launch context.");break}let f;try{f=S.launchPlanOffer({route:p.route,prompt:p.launchPrompt,workdir:p.launchWorkdir,name:p.launchName,worktreeStrategy:p.launchWorktreeStrategy})}catch(h){let k=h instanceof Error?h.message:String(h);await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`⚠️ Failed to start planning session: ${k}`);break}await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`▶️ Planning session started: ${f.name} [${f.id}]`);break}case"plan-offer-dismiss":{await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!p.repoPolicy||!p.repoPolicyWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,"⚠️ This action is missing the repo policy context.");break}if(!p.launchPrompt||!p.launchWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,"⚠️ This action is missing the launch context.");break}if(typeof S.resolveRepoPolicy=="function"){let k=S.resolveRepoPolicy(p.repoPolicyWorkdir);if(k.identity){let v=Tt(p.repoPolicy,k.prAvailable);if(v){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`⚠️ ${v}`);break}}}let f=S.setRepoPolicy(p.repoPolicyWorkdir,p.repoPolicy);if(!f){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`⚠️ Could not resolve a git repository for ${p.repoPolicyWorkdir}.`);break}S.clearRepoPolicyChoiceTokens(p.sessionId);let h;try{h=S.launchAfterRepoPolicyChoice({route:p.route,prompt:p.launchPrompt,workdir:p.launchWorkdir,name:p.launchName,model:p.launchModel,reasoningEffort:p.launchReasoningEffort,fastMode:p.launchFastMode,systemPrompt:p.launchSystemPrompt,allowedTools:p.launchAllowedTools,resumeSessionId:p.launchResumeSessionId,resumeWorktreeFrom:p.launchResumeWorktreeFrom,sessionIdOverride:p.launchSessionIdOverride,clearedPersistedCodexResume:p.launchClearedPersistedCodexResume,forkSession:p.launchForkSession,forceNewSession:p.launchForceNewSession,permissionMode:p.launchPermissionMode,planApproval:p.launchPlanApproval,harness:p.launchHarness,worktreeStrategy:p.launchWorktreeStrategy,worktreeBaseBranch:p.launchWorktreeBaseBranch,worktreePrTargetRepo:p.launchWorktreePrTargetRepo,originAgentId:p.launchOriginAgentId}).text}catch(k){let v=k instanceof Error?k.message:String(k);await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`⚠️ Repo policy saved, but launch failed: ${v}`);break}await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,[`✅ Repo policy saved: ${ll(f.policy).title}.`,"",h].join(`
128
- `));break}case"session-restart":case"session-resume":{await X(o,{alreadyAcknowledged:i});let f=await ve(S,{session:d,message:"Continue where you left off.",userInitiated:!0});await U(o,f.isError?`⚠️ ${f.text}`:`▶️ ${f.text}`);break}case"view-output":{await X(o,{alreadyAcknowledged:i});let f=await kr().execute("callback",{session:d,lines:50});await U(o,qr(f));break}case"question-answer":{if(await X(o,{alreadyAcknowledged:i}),a.optionIndex==null){await U(o,"⚠️ Invalid question-answer action.");break}let f=await S.resolvePendingInputOption(d,a.optionIndex,{requestId:a.pendingInputRequestId,questionId:a.pendingInputQuestionId});await U(o,f?"✅ Answer submitted.":"⚠️ That question button is no longer active. Use the latest question prompt.");break}default:{await X(o,{alreadyAcknowledged:i}),await U(o,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}L();ie();function Dt(t){return Ol(t).map(e=>e.value)}function Ol(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:lf(n),raw:n,start:r,end:r+n.length}})}function rt(t){let[e]=Ol(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function lf(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function df(t){return t instanceof Error?t.message:String(t)}function uf(t){let e=Dt(t),n,r=e;return e[0]==="--name"&&e[1]&&(n=e[1],r=e.slice(2)),{name:n,prompt:r.join(" ").trim()}}function Wl(t){t.registerCommand({name:"agent",description:"Launch a coding agent session. Usage: /agent [--name <name>] <prompt>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!S)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}=uf(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=jn({prompt:o,name:r},e,S);if(i.kind!=="resolved")return{text:i.text};let s=S.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:Yn(e)});return{text:S.formatLaunchResult({prompt:o,workdir:i.workdir,harness:i.harness,permissionMode:i.permissionMode??D.permissionMode,planApproval:i.planApproval},s)}}catch(i){let s=df(i),l=s.includes("Max sessions")?"":`
129
-
130
- Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${l}`}}}})}L();function Nl(t){t.registerCommand({name:"agent_sessions",description:"List coding agent sessions. Usage: /agent_sessions [--full]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!S)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").split(/\s+/).includes("--full");return{text:hr(S,"all",void 0,{full:n})}}})}L();function Ll(t){t.registerCommand({name:"agent_kill",description:"Kill a coding agent session by name or ID",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!S)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=e.args?.trim();return n?{text:yr(S,n,"killed")}:{text:"Usage: /agent_kill <name-or-id>"}}})}L();function Bl(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(!S)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>
131
- /agent_respond --interrupt <id-or-name> <message>`};let r=!1,o=n,i=rt(o);i?.value==="--interrupt"&&(r=!0,o=i.rest);let s=rt(o);if(!s)return{text:"Error: Missing message. Usage: /agent_respond <id-or-name> <message>"};let l=s.value,a=s.rest;return a.trim()?{text:(await ve(S,{session:l,message:a,interrupt:r,userInitiated:!0})).text}:{text:"Error: Empty message. Usage: /agent_respond <id-or-name> <message>"}}})}L();function Fl(t){t.registerCommand({name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics",acceptsArgs:!1,requireAuth:!0,handler:()=>{if(!S)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let e=S.getMetrics(),n=S.list("running").length;return{text:zn(e,n)}}})}L();function cf(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function ql(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(!S)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let r=rt((e.args??"").trim())?.value;if(r==="list"){let l=S.listRepoPolicies();return{text:l.length===0?"No stored repo policies.":l.map(a=>`${a.policy} | ${a.provider} | ${a.repoRoot}`).join(`
118
+ `);try{let b=S.spawn({prompt:y,workdir:d,name:`${n.session}-conflict-resolver`,harness:ae(),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});v={content:[{type:"text",text:Ce(`⚠️ Merge conflicts in ${w.conflictFiles.length} file(s) — spawned conflict resolver session: ${b.name}`,w)}]}}catch(b){v={content:[{type:"text",text:Ce(`❌ Merge conflicts detected, but failed to spawn resolver: ${b instanceof Error?b.message:String(b)}`,w)}]}}}else{let y=w.dirtyError?`❌ Merge blocked: ${w.error}`:`❌ Merge failed: ${w.error??"unknown error"}`;v={content:[{type:"text",text:Ce(y,w)}]}}}),v}}}Er();te();L();Z();he();hn();function Hm(t){return!!t&&typeof t=="object"}function bl(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Hm(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 S.dismissWorktree(r)}]};let l=Rr(S);if(r&&(l=l.filter(p=>Ar(p,r)),l.length===0)){let p=Mt(S,r);if(!p.persistedSession&&!p.activeSession)return{content:[{type:"text",text:`Error: Session "${r}" not found.`}]}}if(n.workdir&&(l=l.filter(p=>p.workdir===n.workdir)),l.length===0)return{content:[{type:"text",text:"No managed worktrees matched the requested scope."}]};let a=[],d=[],u=[],c=[];for(let p of l){let{persistedSession:f,activeSession:h,resolvedLifecycle:k}=br(S,p,{baseBranch:n.base_branch});if(!k.cleanupSafe){if(s){let v=k.reasons.length>0?k.reasons.map(Ir).join(", "):nt(k.derivedState);d.push(`${p.name} [kept: ${v}]`)}continue}if(a.push(`${p.name} (${nt(k.derivedState)})`),!i)try{let v=p.workdir;if(!((f??h)&&le(f??h))&&p.worktreePath&&ce(v,p.worktreePath,{destructive:!1}),p.worktreeBranch&&Se(v,p.worktreeBranch),f){let x=k.derivedState==="merged"||k.derivedState==="released"?k.derivedState:k.lifecycle.state,w=new Date().toISOString(),A=x==="merged"?f.worktreeMergedAt:x==="dismissed"?f.worktreeDismissedAt:void 0;S.updatePersistedSession(p.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeMerged:x==="merged"?!0:f.worktreeMerged,worktreeMergedAt:x==="merged"?f.worktreeMergedAt??w:f.worktreeMergedAt,worktreeLifecycle:{...f.worktreeLifecycle??k.lifecycle,state:x,updatedAt:w,resolvedAt:f.worktreeLifecycle?.resolvedAt??A??w,resolutionSource:f.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??k.lifecycle.baseBranch??f.worktreeBaseBranch,targetRepo:f.worktreePrTargetRepo,pushRemote:f.worktreePushRemote,notes:k.reasons}})}u.push(`${p.name} (${nt(k.derivedState)})`)}catch(v){c.push(`${p.name}: ${v instanceof Error?v.message:String(v)}`)}}let m=[o==="clean_safe"?"Clean all safe:":o==="preview_all"?"Worktree lifecycle review:":"Clean all safe preview:"];return m.push(` SAFE ${i?"NOW":"FOUND"} (${a.length}): ${a.join(", ")||"(none)"}`),s&&m.push(` KEPT (${d.length}): ${d.join(", ")||"(none)"}`),i||(m.push(` CLEANED (${u.length}): ${u.join(", ")||"(none)"}`),m.push(` FAILURES (${c.length}): ${c.join(", ")||"(none)"}`)),{content:[{type:"text",text:m.join(`
119
+ `)}]}}}}te();L();hn();function zm(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 Rl(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(!S)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!zm(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n&&typeof n=="object"?n.session:void 0,o=Rr(S);if(r&&(o=o.filter(s=>Ar(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:l,resolvedLifecycle:a}=br(S,s),d=a.cleanupSafe?"safe now":a.preserve?"preserve":"blocked";i.push(`Session: ${s.name} [${s.id}]`),i.push(` Branch: ${s.worktreeBranch??"(unknown)"} → ${a.lifecycle.baseBranch??l?.worktreeBaseBranch??"main"}`),i.push(` Repo: ${s.workdir}`),i.push(` Lifecycle:${nt(a.lifecycle.state)}`),a.derivedState!==a.lifecycle.state&&i.push(` Derived: ${nt(a.derivedState)}`),i.push(` Cleanup: ${d}`),a.evidence.prUrl&&i.push(` PR: ${a.evidence.prUrl} (${a.evidence.prState??"unknown"})`),(a.evidence.branchAheadCount!=null||a.evidence.baseAheadCount!=null)&&i.push(` Ahead: ${a.evidence.branchAheadCount??0} ahead / ${a.evidence.baseAheadCount??0} behind`),i.push(` Reasons: ${a.reasons.length>0?a.reasons.map(Ir).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
120
+ `).trim()}]}}}}te();L();ie();import{existsSync as Qm}from"fs";function Jm(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function Dr(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(!Qm(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=Jm(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??ae(),l=t.model??at(s),a=Tn(s);if(!l&&(s!=="opencode"||a&&a.length>0))return{kind:"error",text:`Error: No default model configured for harness "${s}". Set plugins.entries["openclaw-code-agent"].config.harnesses.${s}.defaultModel or pass model explicitly.`};if(l&&!Gn(l,a))return{kind:"error",text:`Error: Model "${l}" is not allowed. Permitted models: ${a?.join(", ")}`};let d=e.sessionKey||void 0,u=Cn(e),c=zt(e,u||ze(r)),m=dt(e,c,d);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:l,reasoningEffort:Le(s),fastMode:lt(s),systemPrompt:t.systemPrompt,allowedTools:t.allowedTools,maxIterations:t.maxIterations,permissionMode:t.permissionMode??"bypassPermissions",harness:s,loopMode:i,completionPromise:t.completionPromise,originChannel:c,originThreadId:m?.threadId,originAgentId:e.agentId||void 0,originSessionKey:d,route:m,verifierCommands:o}}function Or(t,e){return["Goal task launched.",` Name: ${t.name}`,` ID: ${t.id}`,` Dir: ${t.workdir}`,` Session: ${t.sessionName} [${t.sessionId}]`,` Harness: ${e.harness}`,` Model: ${e.model??"default"}`,...e.fastMode?[" Fast mode: enabled"]:[],` Loop mode: ${t.loopMode}`,` Max controller iterations: ${t.maxIterations}`,` Goal: "${e.goal.length>100?`${e.goal.slice(0,100)}...`:e.goal}"`,...t.loopMode==="ralph"?[` Completion promise: ${t.completionPromise}`]:[" Verifiers:",...e.verifierCommands.map(r=>` - ${r.command}`)],"","Controller iteration progress advances only when the goal controller starts another agent turn; internal agent review passes are reported in the completion summary.","","Use goal_status to follow progress or goal_stop to terminate the task."].join(`
121
+ `)}function Ym(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function Al(t){return{name:"goal_launch",description:"Launch an explicit goal loop. Use this only when the user specifically asks for a goal task, Ralph-style autonomous loop, iterative loop, autonomous repair loop, or keep-going-until-checks-pass workflow. This is not the default session path.",parameters:g.Object({goal:g.String({description:"End goal for the autonomous task"}),verifier_commands:g.Optional(g.Array(g.String({description:"Shell command that must pass for the goal to be considered complete"}),{minItems:1,description:"Verifier commands run after each coding turn"})),name:g.Optional(g.String({description:"Short task name (kebab-case preferred)"})),workdir:g.Optional(g.String({description:"Working directory (defaults to cwd / configured workspace)"})),model:g.Optional(g.String({description:"Model name to use"})),system_prompt:g.Optional(g.String({description:"Additional system prompt"})),allowed_tools:g.Optional(g.Array(g.String(),{description:"Allowed tools for the underlying agent session"})),max_iterations:g.Optional(g.Number({description:"Maximum verifier-driven repair iterations",minimum:1})),goal_mode:g.Optional(g.Union([g.Literal("ralph"),g.Literal("verifier")],{description:"Loop strategy. 'ralph' repeats until a completion promise appears. 'verifier' repeats until verifier commands pass. Defaults to 'ralph' when no verifiers are provided, otherwise 'verifier'."})),completion_promise:g.Optional(g.String({description:"Exact completion promise for Ralph-mode loops. Defaults to 'DONE'."})),permission_mode:g.Optional(g.Union([g.Literal("default"),g.Literal("plan"),g.Literal("bypassPermissions")],{description:"Permission mode for the underlying agent session. Defaults to bypassPermissions for autonomous goal loops."})),harness:g.Optional(g.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode')."}))}),async execute(e,n){if(!j)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!Ym(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=Dr({goal:n.goal,verifierCommands:n.verifier_commands,name:n.name,workdir:n.workdir,model:n.model,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,maxIterations:n.max_iterations,permissionMode:n.permission_mode,harness:n.harness,goalMode:n.goal_mode,completionPromise:n.completion_promise},t);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};try{let o=await j.launchTask({goal:r.goal,name:r.name,workdir:r.workdir,model:r.model,reasoningEffort:r.reasoningEffort,fastMode:r.fastMode,systemPrompt:r.systemPrompt,allowedTools:r.allowedTools,maxIterations:r.maxIterations,permissionMode:r.permissionMode,loopMode:r.loopMode,completionPromise:r.completionPromise,originChannel:r.originChannel,originThreadId:r.originThreadId,originAgentId:r.originAgentId,originSessionKey:r.originSessionKey,route:r.route,harness:r.harness,verifierCommands:r.verifierCommands});return{content:[{type:"text",text:Or(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}te();function Wi(t,e){return t.split(`
122
+ `).map(n=>`${e}${n}`)}function Il(t,e){return t.length<=e?t:`${t.slice(0,e-3).trimEnd()}...`}function Zm(t,e=8,n=600){let r=t.map(i=>i.trimEnd()).filter(i=>i.trim().length>0);if(r.length===0)return;let o=r.slice(-e).join(`
123
+ `);return o.length<=n?o:`...${o.slice(-(n-3))}`}function Xm(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=>Il(o,180))}function ef(t){let e=(t??"").split(/\r?\n/).map(n=>n.trim()).filter(n=>n.length>0);return e.length===0?[]:e.slice(0,2).map(n=>Il(n,180))}function Wr(t){let e=[],n=ef(t.verifierSummary),r=Xm(t.output,t.completionPromise);if(n.length===0&&r.length===0)return;t.completionDetected===!0&&e.push("Completion was claimed, but the loop is continuing after verification.");for(let i of n)e.push(`Verifier: ${i}`);let o=Math.max(0,3-e.length);if(o>0)for(let i of r.slice(-o))e.push(`Agent: ${i}`);return["Iteration summary:",...e.map(i=>`- ${i}`)].join(`
124
+ `)}function Ni(t){if(t)return{phase:t.phase,awaitingInput:t.isAwaitingInput??!!t.pendingInputState,latestOutput:Zm(t.getOutput(20))}}function Li(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(...Wi(n," ")),t.lastVerifierSummary&&(o.push(" Last verifier:"),o.push(...Wi(t.lastVerifierSummary," "))),e?.latestOutput&&(o.push(" Latest activity:"),o.push(...Wi(e.latestOutput," "))),t.waitingForUserReason&&o.push(` Waiting on user: ${t.waitingForUserReason}`),t.failureReason&&o.push(` Failure: ${t.failureReason}`),o.join(`
125
+ `)}var Pe="Error: GoalController not initialized. The code-agent service must be running.";function Nr(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 Li(i,Ni(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 Li(i,Ni(s))}).join(`
126
+
127
+ `)}function Lr(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 Br(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.`}}L();function xl(t){return{name:"goal_status",description:"Show status for explicit goal tasks managed by the goal controller. Use this to inspect one goal task or list all goal tasks.",parameters:g.Object({task:g.Optional(g.String({description:"Task name or ID. Omit to list all tasks."}))}),async execute(e,n){if(!j)return{content:[{type:"text",text:Pe}]};let r=n&&typeof n=="object"&&typeof n.task=="string"?n.task:void 0;return{content:[{type:"text",text:Nr(j,o=>S?.resolve(o),r)}]}}}}te();L();function tf(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function Tl(t){return{name:"goal_stop",description:"Stop an explicit goal task and kill its underlying agent session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"})}),async execute(e,n){if(!j)return{content:[{type:"text",text:Pe}]};if(!tf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=j.stopTask(n.task);return{content:[{type:"text",text:Lr(r,n.task)}]}}}}te();L();function nf(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function Cl(t){return{name:"goal_edit",description:"Edit the goal text for an active goal task without stopping or relaunching its session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"}),goal:g.String({description:"Replacement goal text"})}),async execute(e,n){if(!j)return{content:[{type:"text",text:Pe}]};if(!nf(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=j.editTask(n.task,n.goal);return{content:[{type:"text",text:Br(r,n.task)}]}}}}L();Er();import{createHash as rf}from"crypto";var ye="code-agent";var of=new Set(["1","true","yes","on"]);function Fi(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&of.has(t))}function $t(t){if(!(typeof t!="string"||t.length===0))return rf("sha256").update(t).digest("hex").slice(0,12)}function Ml(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function z(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=Ml(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>$t(Ml(r))):void 0,buttonStyles:n.length>0?n.map(r=>typeof r.style=="string"?r.style:void 0):void 0}}function Ue(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function $l(t){let e=Ue(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(n)return n.map(r=>Ue(r)?.type).filter(r=>typeof r=="string"&&r.length>0)}function El(t){let e=Ue(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(!n)return;let r=n.map(o=>{let i=Ue(o);return i?.type!=="buttons"||!Array.isArray(i.buttons)?[]:i.buttons}).filter(o=>o.length>0);return r.length>0?r:void 0}function qi(t){let e=El(t);return{presentationBlockTypes:$l(t),...z(e)}}function Ki(t){let e=Ue(t),n=e?.interactive,r=Ue(e?.channelData),o=Ue(r?.telegram),i=Array.isArray(o?.buttons)?o.buttons:void 0;return{renderedPayloadKeys:e?Object.keys(e).sort():void 0,interactiveBlockTypes:$l(n),..._l("interactive",z(El(n))),..._l("telegramChannelData",z(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function Dl(t){let e=Ue(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:Bi(e.messageId),chatId:Bi(e.chatId),telegramThreadId:Bi(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function Bi(t){return typeof t=="string"||typeof t=="number"?t:void 0}function _l(t,e){let n={};for(let[r,o]of Object.entries(e))o!==void 0&&(n[`${t}${r.charAt(0).toUpperCase()}${r.slice(1)}`]=o);return n}function B(t,e){if(!Fi())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:ye,...n})}`}function sf(t){let e=t.trim().replace(new RegExp(`^${ye}:`),"");return e||null}async function Fr(t,e=!1){if(t.channel==="telegram")try{return(await X(t,{alreadyAcknowledged:e,forceTelegramMarkupEdit:!0})).textDelivered}catch(r){let o=r instanceof Error?r.message:String(r);return`${o}`,!1}let n=t.respond;if(typeof n.clearComponents=="function")try{return await n.clearComponents(),!1}catch(r){if(Et(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}function qr(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 Ol(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return Ui(qr(t))}function Ui(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function af(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function lf(...t){let e;for(let n of t)n!=null&&(e=e==null?n:Math.max(e,n));return e}function df(t){if(t.actionablePlanDecisionVersion!=null)return t.actionablePlanDecisionVersion;let e=lf(t.approvalPromptRequiredVersion,t.approvalPromptVersion);return e??t.canonicalPlanPromptVersion??t.planDecisionVersion}function uf(t,e){if(!af(t.kind))return;if(!e)return"This plan decision is stale because the session is no longer available.";let n=df(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 cf(t){let e="callback"in t?t.callback?.payload??t.callback?.data:void 0,n="interaction"in t?t.interaction?.payload:void 0;return e??n??""}function Et(t){let e=t instanceof Error?t.message:String(t);return/message is not modified/i.test(e)}function pf(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function X(t,e={}){let n=t.respond,{alreadyAcknowledged:r=!1,forceTelegramMarkupEdit:o=!1,text:i}=e;if(t.channel==="telegram"){if(typeof i=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:i,buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0}}catch(l){if(Et(l))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0};let a=l instanceof Error?l.message:String(l);`${a}`}if(o&&typeof n.editButtons=="function")try{return await n.editButtons({buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}catch(l){if(Et(l))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1};let a=l instanceof Error?l.message:String(l);`${a}`}let s="callback"in t&&typeof t.callback?.messageText=="string"?t.callback.messageText:void 0;if(o&&typeof s=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:s,buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}catch(l){if(Et(l))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1};let a=l instanceof Error?l.message:String(l);`${a}`}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}if(typeof n.clearComponents=="function")try{return await n.clearComponents(typeof i=="string"?{text:i}:void 0),{textDelivered:typeof i=="string"}}catch(s){if(Et(s))return{textDelivered:typeof i=="string"};if(pf(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 l=s instanceof Error?s.message:String(s);`${l}`}}}if(typeof i=="string"&&typeof n.editMessage=="function"){try{await n.editMessage({text:i})}catch(s){if(Et(s))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0};let l=s instanceof Error?s.message:String(s);return`${l}`,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 mf(t){let e=t.respond;if(typeof e.acknowledge!="function")return!1;try{return await e.acknowledge(),!0}catch(n){let r=n instanceof Error?n.message:String(n);return`${r}`,!1}}async function U(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}function Wl(t="telegram",e={}){let n=e.makeAgentMergeTool??Tr,r=e.makeAgentPrTool??Sn;return B("callback_handler_registered",{channel:t,namespace:ye}),{channel:t,namespace:ye,handler:async o=>{let i=await mf(o);if(!o.auth.isAuthorizedSender)return await U(o,"⛔ Unauthorized."),{handled:!0};let s=cf(o),l=sf(s);if(B("callback_received",{channel:o.channel,namespace:ye,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:$t(l),isAuthorizedSender:o.auth.isAuthorizedSender}),!l)return await U(o,"⚠️ Unrecognized callback payload."),{handled:!0};if(!S)return await U(o,"⚠️ Code agent service not running."),{handled:!0};let a=S.getActionToken(l);if(B("callback_token_lookup_completed",{channel:o.channel,namespace:ye,tokenHash:$t(l),tokenFound:!!a,actionKind:a?.kind,sessionId:a?.sessionId,planDecisionVersion:a?.planDecisionVersion}),!a)return await X(o,{alreadyAcknowledged:i}),o.channel!=="telegram"&&await U(o,"⚠️ This action is stale or has already been used."),{handled:!0};let d=a.sessionId,u=S.resolve?.(d)??S.getPersistedSession?.(d),c=u?.name??d,m=uf(a,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:ye,tokenHash:$t(l),actionKind:a.kind,sessionId:d,sessionName:c,planDecisionVersion:a.planDecisionVersion,valid:!m}),m)return await X(o,{alreadyAcknowledged:i}),await U(o,`⚠️ ${m}`),{handled:!0};let p=S.consumeActionToken(l);if(B("callback_token_consume_completed",{channel:o.channel,namespace:ye,tokenHash:$t(l),consumed:!!p,actionKind:p?.kind,sessionId:p?.sessionId,planDecisionVersion:p?.planDecisionVersion}),!p)return await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:a.kind==="plan-offer-start"||a.kind==="plan-offer-dismiss"}),o.channel!=="telegram"&&await U(o,"⚠️ This action is stale or has already been used."),{handled:!0};switch(p.kind){case"worktree-merge":{let f=await n().execute("callback",{session:d}),h=qr(f);if(Ol(f)){await Fr(o,i);break}await U(o,h);break}case"worktree-decide-later":{let f=S.snoozeWorktreeDecision(d,{notifyUser:!1});if(Ui(f)){let k=`⏭️ Snoozed 24h for [${c}]`;await Fr(o,i),await U(o,k)}else await U(o,f);break}case"worktree-dismiss":{let f=await S.dismissWorktree(d),h=Ui(f);h&&await Fr(o,i),await U(o,h?"✅ Discarded":f);break}case"worktree-create-pr":case"worktree-update-pr":{let f=await r().execute("callback",{session:d}),h=qr(f);if(Ol(f)){await Fr(o,i);break}await U(o,h);break}case"worktree-view-pr":{await X(o,{alreadyAcknowledged:i});let f=S.getPersistedSession?.(d),h=a.targetUrl??f?.worktreePrUrl;await U(o,h?`PR: ${h}`:"⚠️ PR URL is no longer available.");break}case"plan-approve":{await X(o,{alreadyAcknowledged:i}),S.clearPlanDecisionTokens(d);let f=await ve(S,{session:d,message:"Approved. Go ahead.",approve:!0,userInitiated:!0});f.isError&&await U(o,`⚠️ ${f.text}`);break}case"plan-reject":{await X(o,{alreadyAcknowledged:i});let f=wi(S,d);await U(o,`❌ ${f.text}`);break}case"plan-request-changes":{await X(o,{alreadyAcknowledged:i});let f=bi(S,d);await U(o,`✏️ ${f.text}`);break}case"plan-offer-start":{if(!p.launchPrompt||!p.launchWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,"⚠️ This action is missing the plan launch context.");break}let f;try{f=S.launchPlanOffer({route:p.route,prompt:p.launchPrompt,workdir:p.launchWorkdir,name:p.launchName,worktreeStrategy:p.launchWorktreeStrategy})}catch(h){let k=h instanceof Error?h.message:String(h);await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`⚠️ Failed to start planning session: ${k}`);break}await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`▶️ Planning session started: ${f.name} [${f.id}]`);break}case"plan-offer-dismiss":{await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!p.repoPolicy||!p.repoPolicyWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,"⚠️ This action is missing the repo policy context.");break}if(!p.launchPrompt||!p.launchWorkdir){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,"⚠️ This action is missing the launch context.");break}if(typeof S.resolveRepoPolicy=="function"){let k=S.resolveRepoPolicy(p.repoPolicyWorkdir);if(k.identity){let v=Tt(p.repoPolicy,k.prAvailable);if(v){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`⚠️ ${v}`);break}}}let f=S.setRepoPolicy(p.repoPolicyWorkdir,p.repoPolicy);if(!f){await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`⚠️ Could not resolve a git repository for ${p.repoPolicyWorkdir}.`);break}S.clearRepoPolicyChoiceTokens(p.sessionId);let h;try{h=S.launchAfterRepoPolicyChoice({route:p.route,prompt:p.launchPrompt,workdir:p.launchWorkdir,name:p.launchName,model:p.launchModel,reasoningEffort:p.launchReasoningEffort,fastMode:p.launchFastMode,systemPrompt:p.launchSystemPrompt,allowedTools:p.launchAllowedTools,resumeSessionId:p.launchResumeSessionId,resumeWorktreeFrom:p.launchResumeWorktreeFrom,sessionIdOverride:p.launchSessionIdOverride,clearedPersistedCodexResume:p.launchClearedPersistedCodexResume,forkSession:p.launchForkSession,forceNewSession:p.launchForceNewSession,permissionMode:p.launchPermissionMode,planApproval:p.launchPlanApproval,harness:p.launchHarness,worktreeStrategy:p.launchWorktreeStrategy,worktreeBaseBranch:p.launchWorktreeBaseBranch,worktreePrTargetRepo:p.launchWorktreePrTargetRepo,originAgentId:p.launchOriginAgentId}).text}catch(k){let v=k instanceof Error?k.message:String(k);await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,`⚠️ Repo policy saved, but launch failed: ${v}`);break}await X(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await U(o,[`✅ Repo policy saved: ${ul(f.policy).title}.`,"",h].join(`
128
+ `));break}case"session-restart":case"session-resume":{await X(o,{alreadyAcknowledged:i});let f=await ve(S,{session:d,message:"Continue where you left off.",userInitiated:!0});await U(o,f.isError?`⚠️ ${f.text}`:`▶️ ${f.text}`);break}case"view-output":{await X(o,{alreadyAcknowledged:i});let f=await kr().execute("callback",{session:d,lines:50});await U(o,qr(f));break}case"question-answer":{if(await X(o,{alreadyAcknowledged:i}),a.optionIndex==null){await U(o,"⚠️ Invalid question-answer action.");break}let f=await S.resolvePendingInputOption(d,a.optionIndex,{requestId:a.pendingInputRequestId,questionId:a.pendingInputQuestionId});await U(o,f?"✅ Answer submitted.":"⚠️ That question button is no longer active. Use the latest question prompt.");break}default:{await X(o,{alreadyAcknowledged:i}),await U(o,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}L();ie();function Dt(t){return Nl(t).map(e=>e.value)}function Nl(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:ff(n),raw:n,start:r,end:r+n.length}})}function rt(t){let[e]=Nl(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function ff(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function gf(t){return t instanceof Error?t.message:String(t)}function hf(t){let e=Dt(t),n,r=e;return e[0]==="--name"&&e[1]&&(n=e[1],r=e.slice(2)),{name:n,prompt:r.join(" ").trim()}}function Ll(t){t.registerCommand({name:"agent",description:"Launch a coding agent session. Usage: /agent [--name <name>] <prompt>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!S)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}=hf(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=jn({prompt:o,name:r},e,S);if(i.kind!=="resolved")return{text:i.text};let s=S.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:Yn(e)});return{text:S.formatLaunchResult({prompt:o,workdir:i.workdir,harness:i.harness,permissionMode:i.permissionMode??D.permissionMode,planApproval:i.planApproval},s)}}catch(i){let s=gf(i),l=s.includes("Max sessions")?"":`
129
+
130
+ Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${l}`}}}})}L();function Bl(t){t.registerCommand({name:"agent_sessions",description:"List coding agent sessions. Usage: /agent_sessions [--full]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!S)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").split(/\s+/).includes("--full");return{text:hr(S,"all",void 0,{full:n})}}})}L();function Fl(t){t.registerCommand({name:"agent_kill",description:"Kill a coding agent session by name or ID",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!S)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=e.args?.trim();return n?{text:yr(S,n,"killed")}:{text:"Usage: /agent_kill <name-or-id>"}}})}L();function ql(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(!S)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>
131
+ /agent_respond --interrupt <id-or-name> <message>`};let r=!1,o=n,i=rt(o);i?.value==="--interrupt"&&(r=!0,o=i.rest);let s=rt(o);if(!s)return{text:"Error: Missing message. Usage: /agent_respond <id-or-name> <message>"};let l=s.value,a=s.rest;return a.trim()?{text:(await ve(S,{session:l,message:a,interrupt:r,userInitiated:!0})).text}:{text:"Error: Empty message. Usage: /agent_respond <id-or-name> <message>"}}})}L();function Kl(t){t.registerCommand({name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics",acceptsArgs:!1,requireAuth:!0,handler:()=>{if(!S)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let e=S.getMetrics(),n=S.list("running").length;return{text:zn(e,n)}}})}L();function yf(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function Ul(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(!S)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let r=rt((e.args??"").trim())?.value;if(r==="list"){let l=S.listRepoPolicies();return{text:l.length===0?"No stored repo policies.":l.map(a=>`${a.policy} | ${a.provider} | ${a.repoRoot}`).join(`
132
132
  `)}}if(r==="cleanup"){let l=S.cleanupRepoPolicies();return{text:l.length===0?"No stale repo policies found.":[`Removed ${l.length} stale repo ${l.length===1?"policy":"policies"}.`,...l.map(a=>`${a.policy} | ${a.provider} | ${a.repoRoot}`)].join(`
133
- `)}}let o=e.workspaceDir;if(!o)return{text:"Error: workspaceDir is required."};if(r==="reset")return{text:S.resetRepoPolicy(o)?`Repo policy reset for ${o}.`:`No stored repo policy found for ${o}.`};if(r&&cf(r)){if(typeof S.resolveRepoPolicy=="function"){let d=S.resolveRepoPolicy(o);if(d.identity){let u=Tt(r,d.prAvailable);if(u)return{text:`Error: ${u}`}}}let l=S.setRepoPolicy(o,r);if(!l)return{text:`Error: ${o} is not a git repository.`};let a=`Repo policy set to ${l.policy} for ${l.repoRoot}.`;try{if(typeof S.continueLaunchAfterManualRepoPolicy!="function")return{text:a};let d=S.continueLaunchAfterManualRepoPolicy(l.repoRoot,r);if(d.kind==="launched")return{text:[a,"",d.text].join(`
133
+ `)}}let o=e.workspaceDir;if(!o)return{text:"Error: workspaceDir is required."};if(r==="reset")return{text:S.resetRepoPolicy(o)?`Repo policy reset for ${o}.`:`No stored repo policy found for ${o}.`};if(r&&yf(r)){if(typeof S.resolveRepoPolicy=="function"){let d=S.resolveRepoPolicy(o);if(d.identity){let u=Tt(r,d.prAvailable);if(u)return{text:`Error: ${u}`}}}let l=S.setRepoPolicy(o,r);if(!l)return{text:`Error: ${o} is not a git repository.`};let a=`Repo policy set to ${l.policy} for ${l.repoRoot}.`;try{if(typeof S.continueLaunchAfterManualRepoPolicy!="function")return{text:a};let d=S.continueLaunchAfterManualRepoPolicy(l.repoRoot,r);if(d.kind==="launched")return{text:[a,"",d.text].join(`
134
134
  `)};if(d.kind==="ambiguous")return{text:[a,"",`Repo policy saved, but ${d.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
135
135
  `)}}catch(d){let u=d instanceof Error?d.message:String(d);return{text:[a,"",`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(`
136
136
  `)}}return{text:a}}let i=S.resolveRepoPolicy(o);if(!i.identity)return{text:`No git repository found for ${o}.`};let s=cn(i.prAvailable).map(l=>l.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(`
137
- `)}}})}L();var pf=50;function Kl(t){t.registerCommand({name:"agent_output",description:"Show recent output from a coding agent session. Usage: /agent_output <id-or-name> [--full] [--lines N]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!S)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=Dt(n),o="",i=!1,s=pf;for(let a=0;a<r.length;a++)if(r[a]==="--full")i=!0;else if(r[a]==="--lines"&&a+1<r.length){let d=parseInt(r[a+1],10);!isNaN(d)&&d>0&&(s=d),a++}else o||(o=r[a]);return o?{text:gr(S,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}L();var Ul="Usage: /goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function Vl(t){t.registerCommand({name:"goal",description:"Launch an explicit goal task (Ralph-style completion loop or verifier-driven loop)",acceptsArgs:!0,requireAuth:!0,handler:async e=>{if(!j)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:Ul};let r=Dt(n),o,i,s,l,a="bypassPermissions",d,u,c,m=[],p=[];for(let k=0;k<r.length;k++){let v=r[k];if(v==="--name"&&k+1<r.length)o=r[++k];else if(v==="--workdir"&&k+1<r.length)i=r[++k];else if(v==="--model"&&k+1<r.length)s=r[++k];else if(v==="--max-iterations"&&k+1<r.length){let I=parseInt(r[++k],10);!Number.isNaN(I)&&I>0&&(l=I)}else if(v==="--permission-mode"&&k+1<r.length){let I=r[++k];if(I==="default"||I==="plan"||I==="bypassPermissions")a=I;else return{text:`Error: Invalid permission mode "${I}".`}}else if(v==="--harness"&&k+1<r.length)d=r[++k];else if(v==="--mode"&&k+1<r.length){let I=r[++k];if(I==="ralph"||I==="verifier")u=I;else return{text:`Error: Invalid goal mode "${I}". Use ralph or verifier.`}}else if(v==="--completion-promise"&&k+1<r.length)c=r[++k];else if(v==="--verify"&&k+1<r.length){let I=r[++k].trim();if(!I)return{text:"Error: --verify commands must not be empty."};m.push(I)}else p.push(v)}let f=p.join(" ").trim();if(!f)return{text:Ul};let h=Dr({goal:f,verifierCommands:m,name:o,workdir:i,model:s,maxIterations:l,permissionMode:a,harness:d,goalMode:u,completionPromise:c},e);if(h.kind!=="resolved")return{text:h.text};try{let k=await j.launchTask({goal:h.goal,name:h.name,workdir:h.workdir,model:h.model,reasoningEffort:h.reasoningEffort,fastMode:h.fastMode,maxIterations:h.maxIterations,permissionMode:h.permissionMode,harness:h.harness,loopMode:h.loopMode,completionPromise:h.completionPromise,originChannel:h.originChannel,originThreadId:h.originThreadId,originAgentId:h.originAgentId,originSessionKey:h.originSessionKey,route:h.route,verifierCommands:h.verifierCommands});return{text:Or(k,h)}}catch(k){return{text:`Error launching goal task: ${k instanceof Error?k.message:String(k)}`}}}})}L();function Gl(t){t.registerCommand({name:"goal_status",description:"Show one goal task or list all explicit goal tasks. Usage: /goal_status [<task-id-or-name>]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!j)return{text:Pe};let n=(e.args??"").trim();return{text:Nr(j,r=>S?.resolve(r),n)}}})}L();function jl(t){t.registerCommand({name:"goal_stop",description:"Stop a goal task. Usage: /goal_stop <task-id-or-name>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!j)return{text:Pe};let n=(e.args??"").trim();if(!n)return{text:"Usage: /goal_stop <task-id-or-name>"};let r=j.stopTask(n);return{text:Lr(r,n)}}})}L();var Hl="Usage: /goal_edit <task-id-or-name> <replacement-goal>";function zl(t){t.registerCommand({name:"goal_edit",description:"Edit a running goal task. Usage: /goal_edit <task-id-or-name> <replacement-goal>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!j)return{text:Pe};let n=(e.args??"").trim();if(!n)return{text:Hl};let r=rt(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:Hl};let s=j.editTask(o,i);return{text:Br(s,o)}}})}import{execFile as If}from"child_process";import{createHash as dd}from"crypto";import{existsSync as vn,mkdirSync as mf,readFileSync as ff,renameSync as Yl,writeFileSync as gf}from"fs";import{homedir as hf}from"os";import{dirname as yf,join as Zl}from"path";var kf=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function Sf(t){let e=t.OPENCLAW_HOME?.trim();return e||Zl(hf(),".openclaw")}function vf(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||Zl(Sf(t),"code-agent-goal-tasks.json")}function Xl(t){return t instanceof Error?t.message:String(t)}function ed(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var Pf=100;function Ql(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function wf(t){if(!vn(t))return;let e=Date.now(),n=Ql(t,e);if(!vn(n))return n;for(let r=1;r<=Pf;r+=1){let o=Ql(t,e,r);if(!vn(o))return o}}function Jl(t,e){try{let n=wf(t);return n?(Yl(t,n),`${e}${n}`,!0):(vn(t),!1)}catch(n){return`${Xl(n)}`,!1}}function bf(t){if(!ed(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 Rf(t){if(!ed(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"||!kf.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:bf(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 Af(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=Rf(n);if(!r)return;e.push(r)}return e}var Kr=class{path;tasks=new Map;constructor(e=process.env){this.path=vf(e),this.load()}load(){try{if(!vn(this.path))return;let e=ff(this.path,"utf8"),n=JSON.parse(e),r=Af(n);if(!r){Jl(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;Jl(this.path,"corrupt or unreadable")&&this.save()}}save(){try{mf(yf(this.path),{recursive:!0});let e=`${this.path}.tmp`;gf(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),Yl(e,this.path)}catch(e){`${this.path}${Xl(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)}};be();var xf=8,ud=600*1e3,Tf=4e3,Ui=1200,Cf="DONE",Mf=["BASH_ENV","ENV"];function _f(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"goal-task"}function Ot(t,e){return t.length<=e?t:`${t.slice(0,e-3)}...`}function Ve(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(`
137
+ `)}}})}L();var kf=50;function Vl(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(!S)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=Dt(n),o="",i=!1,s=kf;for(let a=0;a<r.length;a++)if(r[a]==="--full")i=!0;else if(r[a]==="--lines"&&a+1<r.length){let d=parseInt(r[a+1],10);!isNaN(d)&&d>0&&(s=d),a++}else o||(o=r[a]);return o?{text:gr(S,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}L();var Gl="Usage: /goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function jl(t){t.registerCommand({name:"goal",description:"Launch an explicit goal task (Ralph-style completion loop or verifier-driven loop)",acceptsArgs:!0,requireAuth:!0,handler:async e=>{if(!j)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:Gl};let r=Dt(n),o,i,s,l,a="bypassPermissions",d,u,c,m=[],p=[];for(let k=0;k<r.length;k++){let v=r[k];if(v==="--name"&&k+1<r.length)o=r[++k];else if(v==="--workdir"&&k+1<r.length)i=r[++k];else if(v==="--model"&&k+1<r.length)s=r[++k];else if(v==="--max-iterations"&&k+1<r.length){let I=parseInt(r[++k],10);!Number.isNaN(I)&&I>0&&(l=I)}else if(v==="--permission-mode"&&k+1<r.length){let I=r[++k];if(I==="default"||I==="plan"||I==="bypassPermissions")a=I;else return{text:`Error: Invalid permission mode "${I}".`}}else if(v==="--harness"&&k+1<r.length)d=r[++k];else if(v==="--mode"&&k+1<r.length){let I=r[++k];if(I==="ralph"||I==="verifier")u=I;else return{text:`Error: Invalid goal mode "${I}". Use ralph or verifier.`}}else if(v==="--completion-promise"&&k+1<r.length)c=r[++k];else if(v==="--verify"&&k+1<r.length){let I=r[++k].trim();if(!I)return{text:"Error: --verify commands must not be empty."};m.push(I)}else p.push(v)}let f=p.join(" ").trim();if(!f)return{text:Gl};let h=Dr({goal:f,verifierCommands:m,name:o,workdir:i,model:s,maxIterations:l,permissionMode:a,harness:d,goalMode:u,completionPromise:c},e);if(h.kind!=="resolved")return{text:h.text};try{let k=await j.launchTask({goal:h.goal,name:h.name,workdir:h.workdir,model:h.model,reasoningEffort:h.reasoningEffort,fastMode:h.fastMode,maxIterations:h.maxIterations,permissionMode:h.permissionMode,harness:h.harness,loopMode:h.loopMode,completionPromise:h.completionPromise,originChannel:h.originChannel,originThreadId:h.originThreadId,originAgentId:h.originAgentId,originSessionKey:h.originSessionKey,route:h.route,verifierCommands:h.verifierCommands});return{text:Or(k,h)}}catch(k){return{text:`Error launching goal task: ${k instanceof Error?k.message:String(k)}`}}}})}L();function Hl(t){t.registerCommand({name:"goal_status",description:"Show one goal task or list all explicit goal tasks. Usage: /goal_status [<task-id-or-name>]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!j)return{text:Pe};let n=(e.args??"").trim();return{text:Nr(j,r=>S?.resolve(r),n)}}})}L();function zl(t){t.registerCommand({name:"goal_stop",description:"Stop a goal task. Usage: /goal_stop <task-id-or-name>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!j)return{text:Pe};let n=(e.args??"").trim();if(!n)return{text:"Usage: /goal_stop <task-id-or-name>"};let r=j.stopTask(n);return{text:Lr(r,n)}}})}L();var Ql="Usage: /goal_edit <task-id-or-name> <replacement-goal>";function Jl(t){t.registerCommand({name:"goal_edit",description:"Edit a running goal task. Usage: /goal_edit <task-id-or-name> <replacement-goal>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!j)return{text:Pe};let n=(e.args??"").trim();if(!n)return{text:Ql};let r=rt(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:Ql};let s=j.editTask(o,i);return{text:Br(s,o)}}})}import{execFile as $f}from"child_process";import{createHash as cd}from"crypto";import{existsSync as vn,mkdirSync as Sf,readFileSync as vf,renameSync as Xl,writeFileSync as Pf}from"fs";import{homedir as wf}from"os";import{dirname as bf,join as ed}from"path";var Rf=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function Af(t){let e=t.OPENCLAW_HOME?.trim();return e||ed(wf(),".openclaw")}function If(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||ed(Af(t),"code-agent-goal-tasks.json")}function td(t){return t instanceof Error?t.message:String(t)}function nd(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var xf=100;function Yl(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function Tf(t){if(!vn(t))return;let e=Date.now(),n=Yl(t,e);if(!vn(n))return n;for(let r=1;r<=xf;r+=1){let o=Yl(t,e,r);if(!vn(o))return o}}function Zl(t,e){try{let n=Tf(t);return n?(Xl(t,n),`${e}${n}`,!0):(vn(t),!1)}catch(n){return`${td(n)}`,!1}}function Cf(t){if(!nd(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 Mf(t){if(!nd(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"||!Rf.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:Cf(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 _f(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=Mf(n);if(!r)return;e.push(r)}return e}var Kr=class{path;tasks=new Map;constructor(e=process.env){this.path=If(e),this.load()}load(){try{if(!vn(this.path))return;let e=vf(this.path,"utf8"),n=JSON.parse(e),r=_f(n);if(!r){Zl(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;Zl(this.path,"corrupt or unreadable")&&this.save()}}save(){try{Sf(bf(this.path),{recursive:!0});let e=`${this.path}.tmp`;Pf(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),Xl(e,this.path)}catch(e){`${this.path}${td(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)}};be();var Ef=8,pd=600*1e3,Df=4e3,Vi=1200,Of="DONE",Wf=["BASH_ENV","ENV"];function Nf(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"goal-task"}function Ot(t,e){return t.length<=e?t:`${t.slice(0,e-3)}...`}function Ve(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(`
138
138
  `):n.slice(-e).join(`
139
- `)}function $f(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(`
140
- `):void 0}function td(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function nd(t){let e=t?.trim();return e&&e.length>0?e:Cf}function Ef(t){return t.route??Vt(t.originChannel,t.originThreadId,t.originSessionKey)}function Vi(t){return t.map((e,n)=>({label:e.label.trim()||`check-${n+1}`,command:e.command.trim(),timeoutMs:e.timeoutMs??ud})).filter(e=>e.command.length>0)}function Df(t){return t.loopMode==="verifier"}function Of(t){return Vi(t.verifierCommands).length>0}function rd(t){return Df(t)&&!Of(t)}function Ur(){return"Verifier-mode goal tasks require at least one verifier command."}function od(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${Ve(n.output,12)}`).join(`
141
- `);return dd("sha1").update(e).digest("hex")}function Wf(t){return dd("sha1").update(Ve(t,24)).digest("hex")}function id(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 Nf(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(`
139
+ `)}function Lf(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(`
140
+ `):void 0}function rd(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function od(t){let e=t?.trim();return e&&e.length>0?e:Of}function Bf(t){return t.route??Vt(t.originChannel,t.originThreadId,t.originSessionKey)}function Gi(t){return t.map((e,n)=>({label:e.label.trim()||`check-${n+1}`,command:e.command.trim(),timeoutMs:e.timeoutMs??pd})).filter(e=>e.command.length>0)}function Ff(t){return t.loopMode==="verifier"}function qf(t){return Gi(t.verifierCommands).length>0}function id(t){return Ff(t)&&!qf(t)}function Ur(){return"Verifier-mode goal tasks require at least one verifier command."}function sd(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${Ve(n.output,12)}`).join(`
141
+ `);return cd("sha1").update(e).digest("hex")}function Kf(t){return cd("sha1").update(Ve(t,24)).digest("hex")}function ad(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 Uf(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(`
142
142
  `);let e=t.verifierCommands.map(n=>`- ${n.label}: ${n.command}`).join(`
143
143
  `);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(`
144
- `)}function sd(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(`
144
+ `)}function ld(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(`
145
145
  `):["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(`
146
- `)}function Lf(t,e){let n=e.steps.filter(o=>!o.ok).map(o=>[`- ${o.label} failed (exit ${o.exitCode})`,Ve(o.output,18)].join(`
146
+ `)}function Vf(t,e){let n=e.steps.filter(o=>!o.ok).map(o=>[`- ${o.label} failed (exit ${o.exitCode})`,Ve(o.output,18)].join(`
147
147
  `)).join(`
148
148
 
149
149
  `);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(`
150
- `)}function Bf(t,e){let n=Ve(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(`
151
- `)}function Ff(t,e){let n=e.steps.filter(r=>!r.ok).map(r=>[`- ${r.label} failed (exit ${r.exitCode})`,Ve(r.output,18)].join(`
150
+ `)}function Gf(t,e){let n=Ve(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(`
151
+ `)}function jf(t,e){let n=e.steps.filter(r=>!r.ok).map(r=>[`- ${r.label} failed (exit ${r.exitCode})`,Ve(r.output,18)].join(`
152
152
  `)).join(`
153
153
 
154
154
  `);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(`
155
- `)}function qf(t,e){let n=e.trim();if(!n)return!1;let r=new RegExp(`(^|\\n)\\s*${td(n)}\\s*(\\n|$)`,"i"),o=new RegExp(`<promise>\\s*${td(n)}\\s*<\\/promise>`,"i");return r.test(t)||o.test(t)}function ad(t){return t.steps.map(e=>`${e.ok?"PASS":"FAIL"} ${e.label} (exit ${e.exitCode}, ${Math.round(e.durationMs)}ms)`).join(`
156
- `)}function ot(t){return t instanceof Error?t.message:String(t)}function ld(t){return t==="succeeded"||t==="failed"||t==="stopped"}function Kf(t){return Ot(t.error?.trim()||"Underlying session failed.",Ui)}function Uf(t=process.env){let e={...t};for(let n of Mf)delete e[n];return e}function Vf(t,e){return new Promise(n=>{let r=Date.now();If("bash",["-lc",e.command],{cwd:t,timeout:e.timeoutMs??ud,maxBuffer:1024*1024,env:Uf()},(o,i,s)=>{let l=Date.now()-r,a=typeof o?.code=="number"?o.code:o?1:0,d=`${i??""}${s?`
157
- ${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!o,exitCode:a,durationMs:l,output:Ot(d||"(no output)",Tf)})})})}var Vr=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 Kr}start(){this.started||(this.started=!0,!this.restorePromise&&(this.restorePromise=this.restoreRecoverableTasks().catch(e=>{`${ot(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=Vi(e.verifierCommands);if(n==="verifier"&&r.length===0)throw new Error(Ur());let i={id:Zn(8),name:_f(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??xf,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:nd(e.completionPromise),verifierCommands:r,repeatedFailureCount:0},s=await this.spawnTaskSession(i,Nf(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
155
+ `)}function Hf(t,e){let n=e.trim();if(!n)return!1;let r=new RegExp(`(^|\\n)\\s*${rd(n)}\\s*(\\n|$)`,"i"),o=new RegExp(`<promise>\\s*${rd(n)}\\s*<\\/promise>`,"i");return r.test(t)||o.test(t)}function dd(t){return t.steps.map(e=>`${e.ok?"PASS":"FAIL"} ${e.label} (exit ${e.exitCode}, ${Math.round(e.durationMs)}ms)`).join(`
156
+ `)}function ot(t){return t instanceof Error?t.message:String(t)}function ud(t){return t==="succeeded"||t==="failed"||t==="stopped"}function zf(t){return Ot(t.error?.trim()||"Underlying session failed.",Vi)}function Qf(t=process.env){let e={...t};for(let n of Wf)delete e[n];return e}function Jf(t,e){return new Promise(n=>{let r=Date.now();$f("bash",["-lc",e.command],{cwd:t,timeout:e.timeoutMs??pd,maxBuffer:1024*1024,env:Qf()},(o,i,s)=>{let l=Date.now()-r,a=typeof o?.code=="number"?o.code:o?1:0,d=`${i??""}${s?`
157
+ ${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!o,exitCode:a,durationMs:l,output:Ot(d||"(no output)",Df)})})})}var Vr=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 Kr}start(){this.started||(this.started=!0,!this.restorePromise&&(this.restorePromise=this.restoreRecoverableTasks().catch(e=>{`${ot(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=Gi(e.verifierCommands);if(n==="verifier"&&r.length===0)throw new Error(Ur());let i={id:Zn(8),name:Nf(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??Ef,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:od(e.completionPromise),verifierCommands:r,repeatedFailureCount:0},s=await this.spawnTaskSession(i,Uf(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
158
158
 
159
159
  Goal:
160
- ${Ot(i.goal,500)}`,"goal-task-started"),i}stopTask(e){let n=this.store.get(e);if(n)return ld(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(ld(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
160
+ ${Ot(i.goal,500)}`,"goal-task-started"),i}stopTask(e){let n=this.store.get(e);if(n)return ud(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(ud(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
161
161
 
162
162
  Goal:
163
- ${Ot(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:l}=ut({requestedResumeSessionId:o,activeSession:i?{harnessSessionId:i.harnessSessionId}:void 0,persistedSession:s?{harness:s.harness,backendRef:s.backendRef}:void 0}),a={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:Ef(e),permissionMode:e.permissionMode,multiTurn:!0,goalTaskId:e.id,harness:e.harness,resumeSessionId:l,resumeWorktreeFrom:o,worktreeStrategy:"off"};return this.sessionManager.spawnAndAwaitRunning(a,{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(`
164
- `));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(rd(e)){this.markTaskFailed(e,Ur());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,sd(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: ${ot(r)}`)}}}async runVerifiers(e){let n=Vi(e.verifierCommands);if(n.length===0){let s={status:"fail",steps:[{label:"verifier-config",command:"(none configured)",ok:!1,exitCode:1,durationMs:0,output:Ur()}],summary:"",fingerprint:""};return s.fingerprint=od(s),s.summary=ad(s),s}let r=[];for(let s of n)r.push(await Vf(e.workdir,s));let i={status:r.every(s=>s.ok)?"pass":"fail",steps:r,summary:"",fingerprint:""};return i.fingerprint=od(i),i.summary=ad(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}`,l=$f(o),a=l?`${s}
163
+ ${Ot(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:l}=ut({requestedResumeSessionId:o,activeSession:i?{harnessSessionId:i.harnessSessionId}:void 0,persistedSession:s?{harness:s.harness,backendRef:s.backendRef}:void 0}),a={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:Bf(e),permissionMode:e.permissionMode,multiTurn:!0,goalTaskId:e.id,harness:e.harness,resumeSessionId:l,resumeWorktreeFrom:o,worktreeStrategy:"off"};return this.sessionManager.spawnAndAwaitRunning(a,{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(`
164
+ `));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(id(e)){this.markTaskFailed(e,Ur());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,ld(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: ${ot(r)}`)}}}async runVerifiers(e){let n=Gi(e.verifierCommands);if(n.length===0){let s={status:"fail",steps:[{label:"verifier-config",command:"(none configured)",ok:!1,exitCode:1,durationMs:0,output:Ur()}],summary:"",fingerprint:""};return s.fingerprint=sd(s),s.summary=dd(s),s}let r=[];for(let s of n)r.push(await Jf(e.workdir,s));let i={status:r.every(s=>s.ok)?"pass":"fail",steps:r,summary:"",fingerprint:""};return i.fingerprint=sd(i),i.summary=dd(i),i}notify(e,n,r){this.sessionManager.emitGoalTaskUpdate(e,n,r)}notifyIterationStatus(e,n,r,o){let i=e.loopMode==="ralph"?"iteration":"repair iteration",s=/\b(?:repair\s+)?iteration\s+\d+\/\d+\b/i.test(n)?n:`${n} ${i} ${e.iteration}/${e.maxIterations}`,l=Lf(o),a=l?`${s}
165
165
 
166
- ${l}`:s;this.notify(e,a,"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}${ot(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=Ot(n,Ui),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`❌ [${e.name}] Goal task failed
166
+ ${l}`:s;this.notify(e,a,"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}${ot(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=Ot(n,Vi),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`❌ [${e.name}] Goal task failed
167
167
 
168
168
  ${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
169
169
 
170
- ${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=Ot(n,Ui),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`⛔ [${e.name}] Goal task stopped
170
+ ${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=Ot(n,Vi),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`⛔ [${e.name}] Goal task stopped
171
171
 
172
172
  ${e.failureReason}`,"goal-task-stopped")}async handleRunningSession(e,n){if(n.pendingPlanApproval){let s=await ve(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(`
173
- `),o=id(r);if(!o){this.markTaskFailedWaitingForUser(e,Ve(r,24)||"The session is waiting for user input.");return}let i=await ve(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: ${ot(o)}`)}}async handleTerminalSession(e,n){if(n.status==="failed"){this.markTaskFailed(e,Kf(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(`
174
- `);if(n.pendingPlanApproval){let l=await ve(this.sessionManager,{session:n.id,message:"Approved. Implement the plan.",approve:!0,userInitiated:!1});if(l.isError){this.markTaskFailed(e,l.text);return}let a=this.sessionManager.resolve(n.id);if(!a){this.markTaskFailed(e,"Failed to resolve the resumed goal task session after idle timeout plan approval.");return}this.attachSessionObservers(e,a),this.setTaskRunningWithSession(e,a),this.notifyIterationStatus(e,`🔄 [${e.name}] Goal task resumed after idle timeout`,a),this.scheduleTaskEvaluation(e.id,"idle-timeout-plan-resume",a.id);return}if(n.pendingInputState){let l=id(s);if(!l){this.markTaskFailed(e,`Goal task was waiting for user input and cannot continue autonomously: ${Ve(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: ${l}`].join(`
173
+ `),o=ad(r);if(!o){this.markTaskFailedWaitingForUser(e,Ve(r,24)||"The session is waiting for user input.");return}let i=await ve(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: ${ot(o)}`)}}async handleTerminalSession(e,n){if(n.status==="failed"){this.markTaskFailed(e,zf(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(`
174
+ `);if(n.pendingPlanApproval){let l=await ve(this.sessionManager,{session:n.id,message:"Approved. Implement the plan.",approve:!0,userInitiated:!1});if(l.isError){this.markTaskFailed(e,l.text);return}let a=this.sessionManager.resolve(n.id);if(!a){this.markTaskFailed(e,"Failed to resolve the resumed goal task session after idle timeout plan approval.");return}this.attachSessionObservers(e,a),this.setTaskRunningWithSession(e,a),this.notifyIterationStatus(e,`🔄 [${e.name}] Goal task resumed after idle timeout`,a),this.scheduleTaskEvaluation(e.id,"idle-timeout-plan-resume",a.id);return}if(n.pendingInputState){let l=ad(s);if(!l){this.markTaskFailed(e,`Goal task was waiting for user input and cannot continue autonomously: ${Ve(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: ${l}`].join(`
175
175
 
176
- `));return}await this.resumeAfterIdleTimeout(e,n,sd(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(`
177
- `),l=nd(e.completionPromise);if(qf(s,l)){if(e.verifierCommands.length===0){this.markTaskSucceeded(e,`Completion promise "${l}" detected in agent output.`);return}let m=await this.runVerifiers(e);if(e.lastVerifierSummary=m.summary,e.updatedAt=Date.now(),m.status==="pass"){this.markTaskSucceeded(e,[`Completion promise "${l}" detected.`,m.summary].join(`
176
+ `));return}await this.resumeAfterIdleTimeout(e,n,ld(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(`
177
+ `),l=od(e.completionPromise);if(Hf(s,l)){if(e.verifierCommands.length===0){this.markTaskSucceeded(e,`Completion promise "${l}" detected in agent output.`);return}let m=await this.runVerifiers(e);if(e.lastVerifierSummary=m.summary,e.updatedAt=Date.now(),m.status==="pass"){this.markTaskSucceeded(e,[`Completion promise "${l}" detected.`,m.summary].join(`
178
178
  `));return}if(e.lastVerifierFingerprint===m.fingerprint?e.repeatedFailureCount+=1:e.repeatedFailureCount=1,e.lastVerifierFingerprint=m.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}).`,m.summary].join(`
179
- `));return}e.iteration+=1;let p=Ff(e,m),f=Wr({output:s,verifierSummary:m.summary,completionPromise:l,completionDetected:!0});try{let h=await this.resumeTaskSession(e,p,n);this.setTaskRunningWithSession(e,h),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,f),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",h.id)}catch(h){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${ot(h)}`)}return}let d=Wf(s);if(e.lastVerifierFingerprint===d?e.repeatedFailureCount+=1:e.repeatedFailureCount=1,e.lastVerifierFingerprint=d,e.iteration+1>=e.maxIterations){this.markTaskFailed(e,[`Completion promise "${l}" was not emitted before hitting the iteration budget (${e.maxIterations}).`,"Latest output:",Ve(s,20)||"(no output)"].join(`
180
- `));return}e.iteration+=1;let u=Bf(e,s),c=Wr({output:s,completionPromise:l,completionDetected:!1});try{let m=await this.resumeTaskSession(e,u,n);this.setTaskRunningWithSession(e,m),this.notifyIterationStatus(e,`🔁 [${e.name}] Continued`,void 0,c),this.scheduleTaskEvaluation(e.id,"ralph-continue",m.id)}catch(m){this.markTaskFailed(e,`Failed to continue the Ralph goal task: ${ot(m)}`)}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(`
181
- `));return}e.iteration+=1;let o=Lf(e,r),i=Wr({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: ${ot(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(rd(e)){this.markTaskFailed(e,Ur());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 fu}from"crypto";ie();import{existsSync as Gf,realpathSync as jf}from"fs";import{resolve as Hf}from"path";function cd(t){if(!t)return;let e=Hf(t);try{if(Gf(e))return jf.native(e)}catch{}return e}function Gr(t,e){return!t||!e?!1:cd(t)===cd(e)}Z();ie();import{existsSync as zf}from"fs";Z();he();function pd(t){return t instanceof Error?t.message:String(t)}function Qf(t){let e=t.worktreeStrategy??D.defaultWorktreeStrategy;return!!e&&e!=="off"&&ai(en({harnessName:t.harness??ae(),backendRef:t.backendRef}))}function Jf(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(`
182
- `);return(t??"")+o}function Yf(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 l=ar(r.worktreePath);return r.workdir&&l&&Gr(r.workdir,l)?r.workdir:l??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 l=o&&Un(en({persistedHarness:r.harness,backendRef:r.backendRef}));return{originalWorkdir:i,canCreateManagedWorktreeForResumeWithoutPersistedPath:l}}if(!r.worktreeBranch)throw new Error(`Cannot resume session "${n}": persisted worktree metadata is missing worktreeBranch.`);let s=Un(en({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(zf(r.worktreePath))return`${r.worktreePath}`,{actualWorkdir:r.worktreePath,originalWorkdir:i??r.worktreePath,worktreePath:r.worktreePath,worktreeBranchName:r.worktreeBranch};if(!i)return`${r.worktreePath}`,{clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom};if(s)return`${r.worktreePath}`,{actualWorkdir:i,originalWorkdir:i,worktreeBranchName:r.worktreeBranch,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,restoredMissingNativeBackendWorktree:!0};try{lr(i);let l=fi(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${l}`,{actualWorkdir:l,originalWorkdir:i,worktreePath:l,worktreeBranchName:r.worktreeBranch}}catch(l){return`${pd(l)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function md(t,e,n){let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:l,clearedResumeWorktreeFrom:a,restoredMissingNativeBackendWorktree:d,canCreateManagedWorktreeForResumeWithoutPersistedPath:u,failedResumeWorktreeRestore:c}=Yf(t,n);l&&(t.resumeSessionId=void 0),a&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,o??=t.workdir;let m=!!(t.resumeSessionId??t.resumeWorktreeFrom),p=t.worktreeStrategy??D.defaultWorktreeStrategy;p&&(t.worktreeStrategy=p);let f=Qf(t),k=(!m||!!u)&&!d&&!i&&p&&p!=="off"&&!f;if(c&&p&&p!=="off")throw new Error(`Cannot launch session "${e}": worktree strategy "${p}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);if(f&&!pi(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${p}" requires a git worktree, but "${o}" is not a git repository.`);if(k&&pi(o)){if(!Ta(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=fi(o,e),r=i,s=Pt(i),!s)throw new Error(`created worktree at ${i} but failed to resolve branch name`);`${i}`}catch(v){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${pd(v)}`)}}else if(k)throw new Error(`Cannot launch session "${e}": worktree strategy "${p}" requires a git worktree, but "${o}" is not a git repository.`);if(m&&i&&(r=i),p&&p!=="off"&&!i)throw new Error(`Cannot launch session "${e}": worktree strategy "${p}" 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?Jf(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:l,clearedResumeWorktreeFrom:a,restoredMissingNativeBackendWorktree:d,failedResumeWorktreeRestore:c}}var jr=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return md(e,n,this.getPersistedSession)}hydrateSpawnedSession(e,n,r){r.worktreeStrategy&&r.worktreeStrategy!=="off"&&(e.originalWorkdir=n.originalWorkdir),n.worktreePath&&(e.worktreePath=n.worktreePath,e.worktreeBranch=n.worktreeBranchName,e.worktreeState="provisioned"),r.worktreePrTargetRepo&&(e.worktreePrTargetRepo=r.worktreePrTargetRepo)}};Z();var Hr=class{constructor(e){this.deps=e}deps;applySessionPatch(e,n){let r=this.normalizeCompletionWakePatch(n),o=this.deps.store.getPersistedSession(e);o&&(Object.assign(o,r),this.deps.store.assertPersistedEntry(o));let i=this.findActiveSessionForRef(e,o);return i&&this.applyPatchToActiveSession(i,r),!o&&!i?!1:(o&&this.deps.store.saveIndex(),!0)}normalizeCompletionWakePatch(e){return"completionWakeSucceededAt"in e&&e.completionWakeSucceededAt||"completionWakeSkippedAt"in e&&e.completionWakeSkippedAt?{...e,completionWakeSummaryRequired:void 0}:e}matchesExistingSession(e,n){if(!n)return!1;let r=$(e),o=$(n);return!!(n.sessionId&&e.id===n.sessionId||o&&o===r||n?.harnessSessionId&&e.harnessSessionId===n.harnessSessionId||n?.name&&e.name===n.name)}findActiveSessionForRef(e,n){let r=this.deps.resolveSession(e);if(r)return r;for(let o of this.deps.sessions.values())if(K(o)===e||$(o)===e||o.harnessSessionId===e||this.matchesExistingSession(o,n))return o}applyPatchToActiveSession(e,n){this.applyControlStatePatch(e,n),this.applySessionMetadataPatch(e,n),this.applyWorktreeMetadataPatch(e,n)}applyControlStatePatch(e,n){let r={};if(this.copyControlPatchField(r,n,"lifecycle"),this.copyControlPatchField(r,n,"approvalState"),this.copyControlPatchField(r,n,"approvalExecutionState"),this.copyControlPatchField(r,n,"worktreeState"),this.copyControlPatchField(r,n,"runtimeState"),this.copyControlPatchField(r,n,"deliveryState"),this.copyControlPatchField(r,n,"requestedPermissionMode"),this.copyControlPatchField(r,n,"currentPermissionMode"),this.copyControlPatchField(r,n,"pendingPlanApproval"),this.copyControlPatchField(r,n,"planApprovalContext"),this.copyControlPatchField(r,n,"planDecisionVersion"),this.copyControlPatchField(r,n,"actionablePlanDecisionVersion"),this.copyControlPatchField(r,n,"canonicalPlanPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptRequiredVersion"),this.copyControlPatchField(r,n,"approvalPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptStatus"),this.copyControlPatchField(r,n,"approvalPromptTransport"),this.copyControlPatchField(r,n,"approvalPromptMessageKind"),this.copyControlPatchField(r,n,"approvalPromptLastAttemptAt"),this.copyControlPatchField(r,n,"approvalPromptDeliveredAt"),this.copyControlPatchField(r,n,"approvalPromptFailedAt"),this.copyControlPatchField(r,n,"planModeApproved"),this.copyControlPatchField(r,n,"pendingWorktreeDecisionSince"),typeof e.applyControlPatch=="function"){e.applyControlPatch(r);return}this.assignIfPresent(e,"lifecycle",n,"lifecycle"),this.assignIfPresent(e,"approvalState",n,"approvalState"),this.assignIfPresent(e,"approvalExecutionState",n,"approvalExecutionState"),this.assignIfPresent(e,"worktreeState",n,"worktreeState"),this.assignIfPresent(e,"runtimeState",n,"runtimeState"),this.assignIfPresent(e,"deliveryState",n,"deliveryState"),this.assignIfPresent(e,"requestedPermissionMode",n,"requestedPermissionMode"),this.assignIfPresent(e,"currentPermissionMode",n,"currentPermissionMode"),this.assignIfPresent(e,"pendingPlanApproval",n,"pendingPlanApproval"),this.assignIfPresent(e,"planApprovalContext",n,"planApprovalContext"),this.assignIfPresent(e,"planDecisionVersion",n,"planDecisionVersion"),this.assignIfPresent(e,"actionablePlanDecisionVersion",n,"actionablePlanDecisionVersion"),this.assignIfPresent(e,"canonicalPlanPromptVersion",n,"canonicalPlanPromptVersion"),this.assignIfPresent(e,"approvalPromptRequiredVersion",n,"approvalPromptRequiredVersion"),this.assignIfPresent(e,"approvalPromptVersion",n,"approvalPromptVersion"),this.assignIfPresent(e,"approvalPromptStatus",n,"approvalPromptStatus"),this.assignIfPresent(e,"approvalPromptTransport",n,"approvalPromptTransport"),this.assignIfPresent(e,"approvalPromptMessageKind",n,"approvalPromptMessageKind"),this.assignIfPresent(e,"approvalPromptLastAttemptAt",n,"approvalPromptLastAttemptAt"),this.assignIfPresent(e,"approvalPromptDeliveredAt",n,"approvalPromptDeliveredAt"),this.assignIfPresent(e,"approvalPromptFailedAt",n,"approvalPromptFailedAt"),this.setControlFieldIfPresent(e,"planModeApproved",n)}applySessionMetadataPatch(e,n){this.assignIfDefined(e,"approvalRationale",n.approvalRationale)}applyWorktreeMetadataPatch(e,n){this.assignIfDefined(e,"worktreePath",n.worktreePath),this.assignIfDefined(e,"worktreeBranch",n.worktreeBranch),this.assignIfDefined(e,"worktreePrUrl",n.worktreePrUrl),this.assignIfDefined(e,"worktreePrNumber",n.worktreePrNumber),this.assignIfDefined(e,"worktreeMerged",n.worktreeMerged),this.assignIfDefined(e,"worktreeMergedAt",n.worktreeMergedAt),this.assignIfDefined(e,"worktreeDisposition",n.worktreeDisposition),this.assignIfDefined(e,"worktreePrTargetRepo",n.worktreePrTargetRepo),this.assignIfDefined(e,"worktreePushRemote",n.worktreePushRemote),this.assignIfDefined(e,"worktreeLifecycle",n.worktreeLifecycle),"autoMergeParentSessionId"in n&&(e.autoMergeParentSessionId=n.autoMergeParentSessionId),"autoMergeConflictResolutionAttemptCount"in n&&(e.autoMergeConflictResolutionAttemptCount=n.autoMergeConflictResolutionAttemptCount),"autoMergeResolverSessionId"in n&&(e.autoMergeResolverSessionId=n.autoMergeResolverSessionId)}assignIfDefined(e,n,r){r!==void 0&&(e[n]=r)}assignIfPresent(e,n,r,o){Object.hasOwn(r,o)&&(e[n]=r[o])}copyControlPatchField(e,n,r){Object.hasOwn(n,r)&&(e[r]=n[r])}setControlFieldIfPresent(e,n,r){Object.hasOwn(r,n)&&e.setControlField?.(n,r[n])}};Z();var Zf=new Set(["starting","running"]),zr=class{constructor(e,n){this.sessions=e;this.store=n}sessions;store;resolveActive(e){let n=this.sessions.get(e);return n||(this.findPreferredMatch(e,r=>r.name===e)??this.findPreferredMatch(e,r=>$(r)===e)??this.findPreferredMatch(e,r=>r.harnessSessionId===e))}getPersistedSession(e){return this.store.getPersistedSession(e)}resolveBackendConversationId(e){let n=this.resolveActive(e);return this.store.resolveBackendConversationId(e,n?$(n)??n.harnessSessionId:void 0)}findPreferredMatch(e,n){let r,o;for(let i of this.sessions.values())n(i,e)&&((!o||i.startedAt>o.startedAt)&&(o=i),Zf.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};Z();Z();he();import{existsSync as Xf}from"fs";var fd=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),Qr=class{constructor(e){this.deps=e}deps;async plan(e){let n=K(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=fd.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&fd.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),l=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(!l)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 a=le(e);if(a&&!Xf(i))return{kind:"no-change",repoDir:s,worktreePath:i,nativeBackendWorktree:a};let d=e.worktreeBaseBranch??Te(s),u=this.deps.getWorktreeCompletionState(s,i,l,d);if(u==="no-change")return{kind:"no-change",repoDir:s,worktreePath:i,nativeBackendWorktree:a};if(u==="merged")return{kind:"merged",repoDir:s,worktreePath:i,branchName:l,nativeBackendWorktree:a};if(u==="base-advanced")return{kind:"notify",label:"worktree-no-commits-ahead",message:`⚠️ [${e.name}] Auto-merge: branch '${l}' has no commits ahead of '${d}', but '${d}' has new commits — commits likely landed outside the worktree branch. Verify that commits were not made directly to '${d}' instead of the worktree branch. Worktree: ${i}`};if(u==="dirty-uncommitted")return{kind:"dirty-uncommitted",worktreePath:i,branchName:l,baseBranch:d};let c=Ee(s,l,d);if(!c)return`${l}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let m=e.repoIntegrationPolicy?void 0:this.deps.resolveRepoPolicy?.(s),p=cl({requestedStrategy:o,policy:e.repoIntegrationPolicy??m?.policy,prAvailable:e.repoIntegrationPolicy?this.deps.isPrAvailable(s):m?.prAvailable??this.deps.isPrAvailable(s)});return p.strategy?{kind:"decision",strategy:p.strategy,policyReason:p.reason,policyBlocked:p.blocked,allowedActions:p.allowedActions,repoDir:s,worktreePath:i,branchName:l,baseBranch:d,diffSummary:c,sessionRef:n??void 0}:{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}}}};fn();function eg(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 tg(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function ng(){return/https?:\/\/\S+/gi}function Jr(t){let e=eg(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function Gi(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 rg(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function og(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function ig(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function ji(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,l=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?[`${l}. Do NOT repeat the plugin's status line, and do NOT rely on the plugin to summarize the completed work for you.`]:[`${l}. 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.`],`${l+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 sg(t){let{contract:e,canonicalStatusDelivered:n}=t;return["Completion diagnostics:",`- Canonical completion status delivered to user: ${n?"yes":"no"}`,`- Plugin requested short factual follow-up summary: ${e.requiresShortFactualSummary?"yes":"no"}`,`- Contract applies to ordinary terminal/manual completions: ${e.appliesToOrdinaryTerminalCompletions?"yes":"no"}`]}function Hi(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=`$${(e.costUsd??0).toFixed(2)}`,s=Re(e.duration),l=rg(),a=d=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...Jr(e),"","Output preview:",r,"",...sg({contract:l,canonicalStatusDelivered:d}),"",...ji({sessionId:e.id,canonicalStatusDelivered:d,hasOriginRouteBlock:o})].join(`
183
- `);return{userMessage:`✅ [${e.name}] Completed | ${i} | ${s}${Hn({harness:e.harnessName,model:e.model})}`,wakeMessageOnNotifySuccess:a(!0),wakeMessageOnNotifyFailed:a(!1),followupContract:l}}function Wt(t){let e=og(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>gd(i).trim()).filter(i=>i.length>0),o=gd(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(`
184
- `)}function zi(t){let e=ig(),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(`
185
- `)}function gd(t){return t.replace(tg(),"PR #$1").replace(ng(),"[link omitted]")}function Qi(t){let{session:e,originThreadLine:n,errorSummary:r,preview:o,worktreeAutoCleaned:i,failedButtons:s}=t,l=o.trim()?["","Output preview:",o]:[],a=i?["","Note: Worktree and branch were auto-removed (zero cost, startup failure)."]:[],d=`$${(e.costUsd??0).toFixed(2)}`,u=Re(e.duration);return{userMessage:[`❌ [${e.name}] Failed | ${d} | ${u}${Hn({harness:e.harnessName,model:e.model})}`,` ⚠️ ${r}`].join(`
179
+ `));return}e.iteration+=1;let p=jf(e,m),f=Wr({output:s,verifierSummary:m.summary,completionPromise:l,completionDetected:!0});try{let h=await this.resumeTaskSession(e,p,n);this.setTaskRunningWithSession(e,h),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,f),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",h.id)}catch(h){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${ot(h)}`)}return}let d=Kf(s);if(e.lastVerifierFingerprint===d?e.repeatedFailureCount+=1:e.repeatedFailureCount=1,e.lastVerifierFingerprint=d,e.iteration+1>=e.maxIterations){this.markTaskFailed(e,[`Completion promise "${l}" was not emitted before hitting the iteration budget (${e.maxIterations}).`,"Latest output:",Ve(s,20)||"(no output)"].join(`
180
+ `));return}e.iteration+=1;let u=Gf(e,s),c=Wr({output:s,completionPromise:l,completionDetected:!1});try{let m=await this.resumeTaskSession(e,u,n);this.setTaskRunningWithSession(e,m),this.notifyIterationStatus(e,`🔁 [${e.name}] Continued`,void 0,c),this.scheduleTaskEvaluation(e.id,"ralph-continue",m.id)}catch(m){this.markTaskFailed(e,`Failed to continue the Ralph goal task: ${ot(m)}`)}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(`
181
+ `));return}e.iteration+=1;let o=Vf(e,r),i=Wr({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: ${ot(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(id(e)){this.markTaskFailed(e,Ur());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 hu}from"crypto";ie();import{existsSync as Yf,realpathSync as Zf}from"fs";import{resolve as Xf}from"path";function md(t){if(!t)return;let e=Xf(t);try{if(Yf(e))return Zf.native(e)}catch{}return e}function Gr(t,e){return!t||!e?!1:md(t)===md(e)}Z();ie();import{existsSync as eg}from"fs";Z();he();function fd(t){return t instanceof Error?t.message:String(t)}function tg(t){let e=t.worktreeStrategy??D.defaultWorktreeStrategy;return!!e&&e!=="off"&&ai(en({harnessName:t.harness??ae(),backendRef:t.backendRef}))}function ng(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(`
182
+ `);return(t??"")+o}function rg(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 l=ar(r.worktreePath);return r.workdir&&l&&Gr(r.workdir,l)?r.workdir:l??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 l=o&&Un(en({persistedHarness:r.harness,backendRef:r.backendRef}));return{originalWorkdir:i,canCreateManagedWorktreeForResumeWithoutPersistedPath:l}}if(!r.worktreeBranch)throw new Error(`Cannot resume session "${n}": persisted worktree metadata is missing worktreeBranch.`);let s=Un(en({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(eg(r.worktreePath))return`${r.worktreePath}`,{actualWorkdir:r.worktreePath,originalWorkdir:i??r.worktreePath,worktreePath:r.worktreePath,worktreeBranchName:r.worktreeBranch};if(!i)return`${r.worktreePath}`,{clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom};if(s)return`${r.worktreePath}`,{actualWorkdir:i,originalWorkdir:i,worktreeBranchName:r.worktreeBranch,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,restoredMissingNativeBackendWorktree:!0};try{lr(i);let l=fi(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${l}`,{actualWorkdir:l,originalWorkdir:i,worktreePath:l,worktreeBranchName:r.worktreeBranch}}catch(l){return`${fd(l)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function gd(t,e,n){let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:l,clearedResumeWorktreeFrom:a,restoredMissingNativeBackendWorktree:d,canCreateManagedWorktreeForResumeWithoutPersistedPath:u,failedResumeWorktreeRestore:c}=rg(t,n);l&&(t.resumeSessionId=void 0),a&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,o??=t.workdir;let m=!!(t.resumeSessionId??t.resumeWorktreeFrom),p=t.worktreeStrategy??D.defaultWorktreeStrategy;p&&(t.worktreeStrategy=p);let f=tg(t),k=(!m||!!u)&&!d&&!i&&p&&p!=="off"&&!f;if(c&&p&&p!=="off")throw new Error(`Cannot launch session "${e}": worktree strategy "${p}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);if(f&&!pi(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${p}" requires a git worktree, but "${o}" is not a git repository.`);if(k&&pi(o)){if(!Ma(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=fi(o,e),r=i,s=Pt(i),!s)throw new Error(`created worktree at ${i} but failed to resolve branch name`);`${i}`}catch(v){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${fd(v)}`)}}else if(k)throw new Error(`Cannot launch session "${e}": worktree strategy "${p}" requires a git worktree, but "${o}" is not a git repository.`);if(m&&i&&(r=i),p&&p!=="off"&&!i)throw new Error(`Cannot launch session "${e}": worktree strategy "${p}" 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?ng(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:l,clearedResumeWorktreeFrom:a,restoredMissingNativeBackendWorktree:d,failedResumeWorktreeRestore:c}}var jr=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return gd(e,n,this.getPersistedSession)}hydrateSpawnedSession(e,n,r){r.worktreeStrategy&&r.worktreeStrategy!=="off"&&(e.originalWorkdir=n.originalWorkdir),n.worktreePath&&(e.worktreePath=n.worktreePath,e.worktreeBranch=n.worktreeBranchName,e.worktreeState="provisioned"),r.worktreePrTargetRepo&&(e.worktreePrTargetRepo=r.worktreePrTargetRepo)}};Z();var Hr=class{constructor(e){this.deps=e}deps;applySessionPatch(e,n){let r=this.normalizeCompletionWakePatch(n),o=this.deps.store.getPersistedSession(e);o&&(Object.assign(o,r),this.deps.store.assertPersistedEntry(o));let i=this.findActiveSessionForRef(e,o);return i&&this.applyPatchToActiveSession(i,r),!o&&!i?!1:(o&&this.deps.store.saveIndex(),!0)}normalizeCompletionWakePatch(e){return"completionWakeSucceededAt"in e&&e.completionWakeSucceededAt||"completionWakeSkippedAt"in e&&e.completionWakeSkippedAt?{...e,completionWakeSummaryRequired:void 0}:e}matchesExistingSession(e,n){if(!n)return!1;let r=$(e),o=$(n);return!!(n.sessionId&&e.id===n.sessionId||o&&o===r||n?.harnessSessionId&&e.harnessSessionId===n.harnessSessionId||n?.name&&e.name===n.name)}findActiveSessionForRef(e,n){let r=this.deps.resolveSession(e);if(r)return r;for(let o of this.deps.sessions.values())if(K(o)===e||$(o)===e||o.harnessSessionId===e||this.matchesExistingSession(o,n))return o}applyPatchToActiveSession(e,n){this.applyControlStatePatch(e,n),this.applySessionMetadataPatch(e,n),this.applyWorktreeMetadataPatch(e,n)}applyControlStatePatch(e,n){let r={};if(this.copyControlPatchField(r,n,"lifecycle"),this.copyControlPatchField(r,n,"approvalState"),this.copyControlPatchField(r,n,"approvalExecutionState"),this.copyControlPatchField(r,n,"worktreeState"),this.copyControlPatchField(r,n,"runtimeState"),this.copyControlPatchField(r,n,"deliveryState"),this.copyControlPatchField(r,n,"requestedPermissionMode"),this.copyControlPatchField(r,n,"currentPermissionMode"),this.copyControlPatchField(r,n,"pendingPlanApproval"),this.copyControlPatchField(r,n,"planApprovalContext"),this.copyControlPatchField(r,n,"planDecisionVersion"),this.copyControlPatchField(r,n,"actionablePlanDecisionVersion"),this.copyControlPatchField(r,n,"canonicalPlanPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptRequiredVersion"),this.copyControlPatchField(r,n,"approvalPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptStatus"),this.copyControlPatchField(r,n,"approvalPromptTransport"),this.copyControlPatchField(r,n,"approvalPromptMessageKind"),this.copyControlPatchField(r,n,"approvalPromptLastAttemptAt"),this.copyControlPatchField(r,n,"approvalPromptDeliveredAt"),this.copyControlPatchField(r,n,"approvalPromptFailedAt"),this.copyControlPatchField(r,n,"planModeApproved"),this.copyControlPatchField(r,n,"pendingWorktreeDecisionSince"),typeof e.applyControlPatch=="function"){e.applyControlPatch(r);return}this.assignIfPresent(e,"lifecycle",n,"lifecycle"),this.assignIfPresent(e,"approvalState",n,"approvalState"),this.assignIfPresent(e,"approvalExecutionState",n,"approvalExecutionState"),this.assignIfPresent(e,"worktreeState",n,"worktreeState"),this.assignIfPresent(e,"runtimeState",n,"runtimeState"),this.assignIfPresent(e,"deliveryState",n,"deliveryState"),this.assignIfPresent(e,"requestedPermissionMode",n,"requestedPermissionMode"),this.assignIfPresent(e,"currentPermissionMode",n,"currentPermissionMode"),this.assignIfPresent(e,"pendingPlanApproval",n,"pendingPlanApproval"),this.assignIfPresent(e,"planApprovalContext",n,"planApprovalContext"),this.assignIfPresent(e,"planDecisionVersion",n,"planDecisionVersion"),this.assignIfPresent(e,"actionablePlanDecisionVersion",n,"actionablePlanDecisionVersion"),this.assignIfPresent(e,"canonicalPlanPromptVersion",n,"canonicalPlanPromptVersion"),this.assignIfPresent(e,"approvalPromptRequiredVersion",n,"approvalPromptRequiredVersion"),this.assignIfPresent(e,"approvalPromptVersion",n,"approvalPromptVersion"),this.assignIfPresent(e,"approvalPromptStatus",n,"approvalPromptStatus"),this.assignIfPresent(e,"approvalPromptTransport",n,"approvalPromptTransport"),this.assignIfPresent(e,"approvalPromptMessageKind",n,"approvalPromptMessageKind"),this.assignIfPresent(e,"approvalPromptLastAttemptAt",n,"approvalPromptLastAttemptAt"),this.assignIfPresent(e,"approvalPromptDeliveredAt",n,"approvalPromptDeliveredAt"),this.assignIfPresent(e,"approvalPromptFailedAt",n,"approvalPromptFailedAt"),this.setControlFieldIfPresent(e,"planModeApproved",n)}applySessionMetadataPatch(e,n){this.assignIfDefined(e,"approvalRationale",n.approvalRationale)}applyWorktreeMetadataPatch(e,n){this.assignIfDefined(e,"worktreePath",n.worktreePath),this.assignIfDefined(e,"worktreeBranch",n.worktreeBranch),this.assignIfDefined(e,"worktreePrUrl",n.worktreePrUrl),this.assignIfDefined(e,"worktreePrNumber",n.worktreePrNumber),this.assignIfDefined(e,"worktreeMerged",n.worktreeMerged),this.assignIfDefined(e,"worktreeMergedAt",n.worktreeMergedAt),this.assignIfDefined(e,"worktreeDisposition",n.worktreeDisposition),this.assignIfDefined(e,"worktreePrTargetRepo",n.worktreePrTargetRepo),this.assignIfDefined(e,"worktreePushRemote",n.worktreePushRemote),this.assignIfDefined(e,"worktreeLifecycle",n.worktreeLifecycle),"autoMergeParentSessionId"in n&&(e.autoMergeParentSessionId=n.autoMergeParentSessionId),"autoMergeConflictResolutionAttemptCount"in n&&(e.autoMergeConflictResolutionAttemptCount=n.autoMergeConflictResolutionAttemptCount),"autoMergeResolverSessionId"in n&&(e.autoMergeResolverSessionId=n.autoMergeResolverSessionId)}assignIfDefined(e,n,r){r!==void 0&&(e[n]=r)}assignIfPresent(e,n,r,o){Object.hasOwn(r,o)&&(e[n]=r[o])}copyControlPatchField(e,n,r){Object.hasOwn(n,r)&&(e[r]=n[r])}setControlFieldIfPresent(e,n,r){Object.hasOwn(r,n)&&e.setControlField?.(n,r[n])}};Z();var og=new Set(["starting","running"]),zr=class{constructor(e,n){this.sessions=e;this.store=n}sessions;store;resolveActive(e){let n=this.sessions.get(e);return n||(this.findPreferredMatch(e,r=>r.name===e)??this.findPreferredMatch(e,r=>$(r)===e)??this.findPreferredMatch(e,r=>r.harnessSessionId===e))}getPersistedSession(e){return this.store.getPersistedSession(e)}resolveBackendConversationId(e){let n=this.resolveActive(e);return this.store.resolveBackendConversationId(e,n?$(n)??n.harnessSessionId:void 0)}findPreferredMatch(e,n){let r,o;for(let i of this.sessions.values())n(i,e)&&((!o||i.startedAt>o.startedAt)&&(o=i),og.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};Z();Z();he();import{existsSync as ig}from"fs";var hd=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),Qr=class{constructor(e){this.deps=e}deps;async plan(e){let n=K(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=hd.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&hd.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),l=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(!l)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 a=le(e);if(a&&!ig(i))return{kind:"no-change",repoDir:s,worktreePath:i,nativeBackendWorktree:a};let d=e.worktreeBaseBranch??Te(s),u=this.deps.getWorktreeCompletionState(s,i,l,d);if(u==="no-change")return{kind:"no-change",repoDir:s,worktreePath:i,nativeBackendWorktree:a};if(u==="merged")return{kind:"merged",repoDir:s,worktreePath:i,branchName:l,nativeBackendWorktree:a};if(u==="base-advanced")return{kind:"notify",label:"worktree-no-commits-ahead",message:`⚠️ [${e.name}] Auto-merge: branch '${l}' has no commits ahead of '${d}', but '${d}' has new commits — commits likely landed outside the worktree branch. Verify that commits were not made directly to '${d}' instead of the worktree branch. Worktree: ${i}`};if(u==="dirty-uncommitted")return{kind:"dirty-uncommitted",worktreePath:i,branchName:l,baseBranch:d};let c=Ee(s,l,d);if(!c)return`${l}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let m=e.repoIntegrationPolicy?void 0:this.deps.resolveRepoPolicy?.(s),p=ml({requestedStrategy:o,policy:e.repoIntegrationPolicy??m?.policy,prAvailable:e.repoIntegrationPolicy?this.deps.isPrAvailable(s):m?.prAvailable??this.deps.isPrAvailable(s)});return p.strategy?{kind:"decision",strategy:p.strategy,policyReason:p.reason,policyBlocked:p.blocked,allowedActions:p.allowedActions,repoDir:s,worktreePath:i,branchName:l,baseBranch:d,diffSummary:c,sessionRef:n??void 0}:{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}}}};fn();function sg(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 ag(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function lg(){return/https?:\/\/\S+/gi}function Jr(t){let e=sg(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function ji(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 dg(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function ug(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function cg(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function Hi(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,l=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?[`${l}. Do NOT repeat the plugin's status line, and do NOT rely on the plugin to summarize the completed work for you.`]:[`${l}. 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.`],`${l+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 pg(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 zi(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=`$${(e.costUsd??0).toFixed(2)}`,s=Re(e.duration),l=dg(),a=d=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...Jr(e),"","Output preview:",r,"",...pg({contract:l,canonicalStatusDelivered:d}),"",...Hi({sessionId:e.id,canonicalStatusDelivered:d,hasOriginRouteBlock:o})].join(`
183
+ `);return{userMessage:`✅ [${e.name}] Completed | ${i} | ${s}${Hn({harness:e.harnessName,model:e.model})}`,wakeMessageOnNotifySuccess:a(!0),wakeMessageOnNotifyFailed:a(!1),followupContract:l}}function Wt(t){let e=ug(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>yd(i).trim()).filter(i=>i.length>0),o=yd(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(`
184
+ `)}function Qi(t){let e=cg(),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(`
185
+ `)}function yd(t){return t.replace(ag(),"PR #$1").replace(lg(),"[link omitted]")}function Ji(t){let{session:e,originThreadLine:n,errorSummary:r,preview:o,worktreeAutoCleaned:i,failedButtons:s}=t,l=o.trim()?["","Output preview:",o]:[],a=i?["","Note: Worktree and branch were auto-removed (zero cost, startup failure)."]:[],d=`$${(e.costUsd??0).toFixed(2)}`,u=Re(e.duration);return{userMessage:[`❌ [${e.name}] Failed | ${d} | ${u}${Hn({harness:e.harnessName,model:e.model})}`,` ⚠️ ${r}`].join(`
186
186
  `),wakeMessage:["Coding agent session failed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,n,...Jr(e),...e.harnessSessionId?[`Backend conversation ID: ${e.harnessSessionId}`]:[],"","Failure summary:",r,...l,...a,"","[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(`
187
- `),buttons:s}}function Ji(t){let{session:e,originThreadLine:n,preview:r}=t,o=`$${(e.costUsd??0).toFixed(2)}`;return{userMessage:`⏸️ [${e.name}] Turn completed | ${o}${Hn({harness:e.harnessName,model:e.model})}`,wakeMessage:["Coding agent session turn ended.",`Name: ${e.name}`,`ID: ${e.id}`,`Status: ${e.status}`,`Lifecycle: ${e.lifecycle}`,"","Last output (~20 lines):",r,...n?["",n]:[]].join(`
188
- `)}}function Yi(t){let{sessionName:e,sessionId:n,branchName:r,baseBranch:o,promptSnippet:i,commitLines:s,moreNote:l,originThreadLine:a,diffSummary:d,allowedActions:u,policyReason:c}=t,m=!!a?.trim();return[`[DELEGATED WORKTREE DECISION] Session "${e}" completed with changes.`,"",`Session ID: ${n}`,`Branch: ${r} → ${o}`,`Commits: ${d.commits} | Files: ${d.filesChanged} | +${d.insertions} / -${d.deletions}`,...m?[a]:[],"",...s,...l?[l]:[],"","Original task prompt (first 500 chars):",i,"",...c?[`Policy constraint: ${c}`,""]:[],"You own the next step for this worktree.",...u?.merge===!1?["- Do not call agent_merge(); repo policy does not allow direct merge for this session."]:[`- Merge immediately with agent_merge(session="${e}", base_branch="${o}") if the changes are clearly in-scope and low-risk.`],...u?.pr===!1?["- Do not call agent_pr(); PR creation is unavailable or forbidden by repo policy."]:[`- If a PR is safer or human choice is needed, call agent_request_worktree_decision(session="${e}", summary="...") so the user gets the canonical Merge/Open PR/Later/Discard buttons.`],`- If scope or risk is unclear, call agent_request_worktree_decision(session="${e}", summary="...") with a concise risk summary instead of sending a plain-text-only question.`,"- Never call agent_pr() autonomously in delegate mode.","- After deciding, notify the user briefly with what you did and why.",...m?["- 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(`
189
- `)}function Zi(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(`
190
- `)}function Xi(t){let{sessionName:e,sessionId:n,cleanupSummary:r,preview:o,originThreadLine:i,requestedPermissionMode:s,currentPermissionMode:l,approvalExecutionState:a,approvalState:d,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:m,approvalPromptDeliveredAt:p}=t,f=o.trim()?["","Output preview:",o]:[],h=!!i?.trim();return["Coding agent session completed with no repository changes.",`Name: ${e} | ID: ${n}`,`Worktree outcome: ${r}`,...h?[i]:[],...Jr({requestedPermissionMode:s,currentPermissionMode:l,approvalExecutionState:a,approvalState:d,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:m,approvalPromptDeliveredAt:p}),...f,"",...ji({sessionId:n,canonicalStatusDetail:"The plugin already sent the canonical completion status to the user, including that no repo changes were kept.",hasOriginRouteBlock:h})].join(`
191
- `)}var kd=3200,es=3e3,ag=2400,lg=120,dg=5,ug=280,hd=1400,yd="- Additional plan details omitted for brevity.";function Sd(t){return t.replace(/^#{1,6}\s+/,"").replace(/^[-*+]\s+/,"").replace(/^\d+[.)]\s+/,"").replace(/^`([^`]+)`$/,"$1").trim()}function cg(t){return t.split(`
192
- `).map(e=>e.trim()).filter(Boolean).map(Sd).map(e=>se(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 pg(t){return t.split(`
193
- `).map(e=>e.trim()).filter(Boolean).map(Sd).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 ts(t){let e=cg(t);return e.length===0?`Review summary:
187
+ `),buttons:s}}function Yi(t){let{session:e,originThreadLine:n,preview:r}=t,o=`$${(e.costUsd??0).toFixed(2)}`;return{userMessage:`⏸️ [${e.name}] Turn completed | ${o}${Hn({harness:e.harnessName,model:e.model})}`,wakeMessage:["Coding agent session turn ended.",`Name: ${e.name}`,`ID: ${e.id}`,`Status: ${e.status}`,`Lifecycle: ${e.lifecycle}`,"","Last output (~20 lines):",r,...n?["",n]:[]].join(`
188
+ `)}}function Zi(t){let{sessionName:e,sessionId:n,branchName:r,baseBranch:o,promptSnippet:i,commitLines:s,moreNote:l,originThreadLine:a,diffSummary:d,allowedActions:u,policyReason:c}=t,m=!!a?.trim();return[`[DELEGATED WORKTREE DECISION] Session "${e}" completed with changes.`,"",`Session ID: ${n}`,`Branch: ${r} → ${o}`,`Commits: ${d.commits} | Files: ${d.filesChanged} | +${d.insertions} / -${d.deletions}`,...m?[a]:[],"",...s,...l?[l]:[],"","Original task prompt (first 500 chars):",i,"",...c?[`Policy constraint: ${c}`,""]:[],"You own the next step for this worktree.",...u?.merge===!1?["- Do not call agent_merge(); repo policy does not allow direct merge for this session."]:[`- Merge immediately with agent_merge(session="${e}", base_branch="${o}") if the changes are clearly in-scope and low-risk.`],...u?.pr===!1?["- Do not call agent_pr(); PR creation is unavailable or forbidden by repo policy."]:[`- If a PR is safer or human choice is needed, call agent_request_worktree_decision(session="${e}", summary="...") so the user gets the canonical Merge/Open PR/Later/Discard buttons.`],`- If scope or risk is unclear, call agent_request_worktree_decision(session="${e}", summary="...") with a concise risk summary instead of sending a plain-text-only question.`,"- Never call agent_pr() autonomously in delegate mode.","- After deciding, notify the user briefly with what you did and why.",...m?["- 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(`
189
+ `)}function Xi(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(`
190
+ `)}function es(t){let{sessionName:e,sessionId:n,cleanupSummary:r,preview:o,originThreadLine:i,requestedPermissionMode:s,currentPermissionMode:l,approvalExecutionState:a,approvalState:d,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:m,approvalPromptDeliveredAt:p}=t,f=o.trim()?["","Output preview:",o]:[],h=!!i?.trim();return["Coding agent session completed with no repository changes.",`Name: ${e} | ID: ${n}`,`Worktree outcome: ${r}`,...h?[i]:[],...Jr({requestedPermissionMode:s,currentPermissionMode:l,approvalExecutionState:a,approvalState:d,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:m,approvalPromptDeliveredAt:p}),...f,"",...Hi({sessionId:n,canonicalStatusDetail:"The plugin already sent the canonical completion status to the user, including that no repo changes were kept.",hasOriginRouteBlock:h})].join(`
191
+ `)}var vd=3200,ts=3e3,mg=2400,fg=120,gg=5,hg=280,kd=1400,Sd="- Additional plan details omitted for brevity.";function Pd(t){return t.replace(/^#{1,6}\s+/,"").replace(/^[-*+]\s+/,"").replace(/^\d+[.)]\s+/,"").replace(/^`([^`]+)`$/,"$1").trim()}function yg(t){return t.split(`
192
+ `).map(e=>e.trim()).filter(Boolean).map(Pd).map(e=>se(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 kg(t){return t.split(`
193
+ `).map(e=>e.trim()).filter(Boolean).map(Pd).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 ns(t){let e=yg(t);return e.length===0?`Review summary:
194
194
  - Plan details are available in the full session output.`:["Review summary:",...e.slice(0,6).map(n=>`- ${n}`)].join(`
195
- `)}function mg(t){let e=[],n=!1;for(let o of t){let i=o.replace(/\s+/g," ").trim();if(!i)continue;let s=se(i,ug);s.length<i.length&&(n=!0);let l=`- ${s}`;if(e.length>=dg||[...e,l].join(`
196
- `).length>hd){n=!0;break}e.push(l)}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,yd].join(`
197
- `).length>hd;)r.pop();return[...r,yd]}function ns(t){return mg(pg(t)).join(`
198
- `)}function fg(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 gg(t,e){let n=t.split(`
199
- `),r=[],o="",i=()=>{o.trim().length>0&&(r.push(o.trimEnd()),o="")};for(let s of n){if(s.length>e){i();for(let a of fg(s,e))r.push(a);continue}let l=o.length>0?`${o}
200
- ${s}`:s;if(l.length>e){i(),o=s;continue}o=l}return i(),r}function vd(t){return se(t.trim(),lg)}function Pd(t,e){return e?t?`
195
+ `)}function Sg(t){let e=[],n=!1;for(let o of t){let i=o.replace(/\s+/g," ").trim();if(!i)continue;let s=se(i,hg);s.length<i.length&&(n=!0);let l=`- ${s}`;if(e.length>=gg||[...e,l].join(`
196
+ `).length>kd){n=!0;break}e.push(l)}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,Sd].join(`
197
+ `).length>kd;)r.pop();return[...r,Sd]}function rs(t){return Sg(kg(t)).join(`
198
+ `)}function vg(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 Pg(t,e){let n=t.split(`
199
+ `),r=[],o="",i=()=>{o.trim().length>0&&(r.push(o.trimEnd()),o="")};for(let s of n){if(s.length>e){i();for(let a of vg(s,e))r.push(a);continue}let l=o.length>0?`${o}
200
+ ${s}`:s;if(l.length>e){i(),o=s;continue}o=l}return i(),r}function wd(t){return se(t.trim(),fg)}function bd(t,e){return e?t?`
201
201
 
202
202
  Choose Approve, Revise, or Reject below.`:`
203
203
 
204
204
  Approval is still pending for this plan version.`:`
205
205
 
206
- Continued in next message.`}function hg(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=`📋 [${e}] Plan v${n??"?"} ready for approval:`,s=`
206
+ Continued in next message.`}function wg(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=`📋 [${e}] Plan v${n??"?"} ready for approval:`,s=`
207
207
 
208
208
  Full plan (truncated):
209
- `,l=Pd(o,!0),a=Math.max(0,es-i.length-s.length-l.length);return`${i}${s}${se(r,a)}${l}`}function yg(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=vd(e),s=ag;for(;s>0;){let l=gg(r,s),a=l.map((c,m)=>{let p=l.length,f=[`📋 [${i}] Plan v${n??"?"} ready for approval (${m+1}/${p}):`,"",m===0?"Full plan:":""].filter(Boolean).join(`
210
- `),h=Pd(o,m===p-1);return`${f}
211
- ${c}${h}`}),d=a.reduce((c,m)=>Math.max(c,m.length),0);if(d<=es)return a;let u=d-es;s-=Math.max(u,50)}return[hg({sessionName:i,actionableVersion:n,fullPlanText:r,hasButtons:o})]}function rs(t){let{preview:e,artifact:n}=t,r=n?.markdown?.trim();return r&&r.length<=kd?`Full plan:
212
- ${r}`:ts(r||e)}function wd(t){let{sessionName:e,actionableVersion:n,preview:r,artifact:o,hasButtons:i}=t,s=o?.markdown?.trim(),l=vd(e);if(s){let d=`📋 [${l}] Plan v${n??"?"} ready for approval:
209
+ `,l=bd(o,!0),a=Math.max(0,ts-i.length-s.length-l.length);return`${i}${s}${se(r,a)}${l}`}function bg(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=wd(e),s=mg;for(;s>0;){let l=Pg(r,s),a=l.map((c,m)=>{let p=l.length,f=[`📋 [${i}] Plan v${n??"?"} ready for approval (${m+1}/${p}):`,"",m===0?"Full plan:":""].filter(Boolean).join(`
210
+ `),h=bd(o,m===p-1);return`${f}
211
+ ${c}${h}`}),d=a.reduce((c,m)=>Math.max(c,m.length),0);if(d<=ts)return a;let u=d-ts;s-=Math.max(u,50)}return[wg({sessionName:i,actionableVersion:n,fullPlanText:r,hasButtons:o})]}function os(t){let{preview:e,artifact:n}=t,r=n?.markdown?.trim();return r&&r.length<=vd?`Full plan:
212
+ ${r}`:ns(r||e)}function Rd(t){let{sessionName:e,actionableVersion:n,preview:r,artifact:o,hasButtons:i}=t,s=o?.markdown?.trim(),l=wd(e);if(s){let d=`📋 [${l}] Plan v${n??"?"} ready for approval:
213
213
 
214
214
  Full plan:
215
215
  ${s}
216
216
 
217
- ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`;return d.length<=kd?{displayMode:"single-full-plan",userMessages:[d],reviewSummary:`Full plan:
218
- ${s}`}:{displayMode:"chunked-full-plan",userMessages:yg({sessionName:e,actionableVersion:n,fullPlanText:s,hasButtons:i}),reviewSummary:ts(s)}}let a=ts(r);return{displayMode:"summary",userMessages:[`📋 [${l}] Plan v${n??"?"} ready for approval:
217
+ ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`;return d.length<=vd?{displayMode:"single-full-plan",userMessages:[d],reviewSummary:`Full plan:
218
+ ${s}`}:{displayMode:"chunked-full-plan",userMessages:bg({sessionName:e,actionableVersion:n,fullPlanText:s,hasButtons:i}),reviewSummary:ns(s)}}let a=ns(r);return{displayMode:"summary",userMessages:[`📋 [${l}] Plan v${n??"?"} ready for approval:
219
219
 
220
220
  ${a}
221
221
 
222
- ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`],reviewSummary:a}}function bd(t){let e=t?.trim();return e||void 0}function kg(t){let e=bd(t.questionText)??"The session is waiting for your reply.",n=bd(t.contextSummary);return n?[`❓ [${t.sessionName}] Question waiting for reply:`,"",e,"",`Why: ${n}`].join(`
222
+ ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`],reviewSummary:a}}function Ad(t){let e=t?.trim();return e||void 0}function Rg(t){let e=Ad(t.questionText)??"The session is waiting for your reply.",n=Ad(t.contextSummary);return n?[`❓ [${t.sessionName}] Question waiting for reply:`,"",e,"",`Why: ${n}`].join(`
223
223
  `):`❓ [${t.sessionName}] Question waiting for reply:
224
224
 
225
- ${e}`}function Sg(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function Pn(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(`
226
- `)}function os(t){let{session:e,preview:n,questionText:r,questionContextSummary:o,planArtifact:i,originThreadLine:s,planApprovalMode:l,planApprovalButtons:a,questionButtons:d}=t,u=e.pendingPlanApproval,c=e.actionablePlanDecisionVersion??e.planDecisionVersion,m=Sg(e,c),p=l??"delegate",f=u&&p==="ask"&&!m?wd({sessionName:e.name,actionableVersion:c,preview:n,artifact:i,hasButtons:!!a}):void 0,h=u?f?.reviewSummary??rs({preview:n,artifact:i}):void 0,k=u?f&&f.userMessages.length===1?f.userMessages[0]:void 0:kg({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!d}),v=u&&f&&f.userMessages.length>1?f.userMessages.map((x,w,A)=>({text:x,buttons:w===A.length-1?a:void 0})):void 0;if(u){let x=p,w="Permission mode: plan → will switch to bypassPermissions on approval";return x==="delegate"?{label:"plan-approval",userMessage:k,userMessages:v,planReviewSummary:h,wakeMessage:["[DELEGATED PLAN APPROVAL] Coding agent session has finished its plan and is requesting approval to implement.",`Name: ${e.name} | ID: ${e.id} | Plan v${c??"?"}`,s,w,"","⚠️ 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(`
225
+ ${e}`}function Ag(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function Pn(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(`
226
+ `)}function is(t){let{session:e,preview:n,questionText:r,questionContextSummary:o,planArtifact:i,originThreadLine:s,planApprovalMode:l,planApprovalButtons:a,questionButtons:d}=t,u=e.pendingPlanApproval,c=e.actionablePlanDecisionVersion??e.planDecisionVersion,m=Ag(e,c),p=l??"delegate",f=u&&p==="ask"&&!m?Rd({sessionName:e.name,actionableVersion:c,preview:n,artifact:i,hasButtons:!!a}):void 0,h=u?f?.reviewSummary??os({preview:n,artifact:i}):void 0,k=u?f&&f.userMessages.length===1?f.userMessages[0]:void 0:Rg({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!d}),v=u&&f&&f.userMessages.length>1?f.userMessages.map((x,w,A)=>({text:x,buttons:w===A.length-1?a:void 0})):void 0;if(u){let x=p,w="Permission mode: plan → will switch to bypassPermissions on approval";return x==="delegate"?{label:"plan-approval",userMessage:k,userMessages:v,planReviewSummary:h,wakeMessage:["[DELEGATED PLAN APPROVAL] Coding agent session has finished its plan and is requesting approval to implement.",`Name: ${e.name} | ID: ${e.id} | Plan v${c??"?"}`,s,w,"","⚠️ YOU MUST COMPLETE THESE STEPS IN ORDER. Do NOT skip any step.","","━━━ STEP 1 (MANDATORY): Read the full plan ━━━",`Call agent_output(session='${e.id}', full=true) to read the FULL plan output.`,"The preview below is truncated — you MUST read the full output before making any decision.","","Preview (truncated):",n,"","━━━ STEP 2 (MANDATORY): Review privately ━━━","You are the delegated decision-maker. Review the plan yourself before involving the user.","If you approve directly, you own the user-facing explanation of what was approved and why.","Keep it short and user-facing: one sentence is usually enough.","","━━━ STEP 3 (ONLY AFTER steps 1 and 2): Decide ━━━","Choose ONE:","","APPROVE the plan directly if ALL of the following are true:","- You have read the FULL plan (not just the preview)","- The plan scope matches the original task request","- The changes are low-risk (no destructive operations, no credential handling, no production deployments)","- The plan is clear and well-scoped (no ambiguous requirements or open design questions)","- No architectural decisions that the user should weigh in on","- The working directory and codebase are correct","","ESCALATE to the user and WAIT if ANY of the following are true:","- The plan involves destructive operations (deleting files, dropping tables, force-pushing)","- The plan involves credentials, secrets, or production environments","- The plan requires architectural decisions not covered by the original task","- The scope has expanded beyond the original request","- The requirements are ambiguous or the plan makes assumptions the user should confirm","- You are unsure — when in doubt, always escalate","",`If approving: call agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true, approval_rationale='<brief reason>').`,"That rationale should say why approval was safe: for example scope match, low risk, or no meaningful ambiguity.","After approving directly, send the user a short plain-text follow-up explaining what was approved and why.","The plugin's thumbs-up line is only the minimal approval acknowledgment, not the explanation.",`If escalating: call agent_request_plan_approval(session='${e.id}', summary='...') exactly once so the plugin posts the single canonical Approve / Revise / Reject prompt.`,"That summary must concisely explain why this was escalated, plus changed files/components, risk level and why, scope match/expansion, and any concerns or assumptions.","After the canonical prompt exists, WAIT for the user's button click or explicit response and do NOT send a second plain-text recap.",`To request changes without user escalation: call agent_respond(session='${e.id}', message='<your feedback>') and do NOT set approve=true. The agent will revise the plan.`].join(`
227
227
  `)}:x==="ask"?{label:"plan-approval",userMessage:k,userMessages:v,planReviewSummary:h,wakeMessage:["[USER APPROVAL REQUESTED] Coding agent session has finished its plan. The user has been notified via Telegram and must approve directly.",`Name: ${e.name} | ID: ${e.id} | Plan v${c??"?"}`,s,w,"","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(`
228
228
  `),buttons:v?void 0:a}:{label:"plan-approval",userMessage:k,planReviewSummary:h,wakeMessage:["[AUTO-APPROVE] Session has a plan ready. Approve it now:",`agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true)`].join(`
229
229
  `)}}let I=e.multiTurn?"Multi-turn session":"Session";return{label:"waiting",userMessage:k,wakeMessage:[`[SYSTEM INSTRUCTION: Follow your auto-respond rules strictly. If this is a permission request or "should I continue?" → auto-respond. For ALL other questions → forward the agent's EXACT question to the user. Do NOT add your own analysis, commentary, or interpretation. Do NOT "nudge" or "poke" the session.]`,"",`${I} 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(`
230
- `),buttons:d}}var Yr=3,is=180,vg=4e3,Rd=32;function Ad(){let t=St(),e=Tg(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=Cg(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 Pg(t,e){let n=Mg(e);if(n.length>0)return n;let r=wg(t);if(r.length>0)return r;let o=[],i=t.changedFiles.slice(0,3).map(l=>`\`${l}\``);if(i.length>0){let l=t.changedFiles.length-i.length;o.push(l>0?`Touches ${i.join(", ")} and ${l} more file${l===1?"":"s"}`:`Touches ${i.join(", ")}`)}let s=[...new Set(t.commitMessages.map(l=>l.message.trim()).filter(Boolean))].slice(0,2);return s.length>0&&o.push(`Recent work: ${s.join("; ")}`),o}function wg(t){let e=new Set,n=t.commitMessages.length===1?t.changedFiles:[];return t.commitMessages.map(r=>bg(r.message,n)).filter(r=>!!r).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Yr)}function bg(t,e){let n=Rg(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 ss(`${n}${r}.`,is)}function Rg(t){let e=Zr(Xr(t)).replace(/^(?:feat|fix|docs|style|refactor|perf|test|tests|build|ci|chore|revert)(?:\([^)]+\))?!?:\s*/i,"").replace(/\.$/,"").trim();if(!e||as(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 Id(t){let e=Ag(t),n=Pg(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=Ig(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 Ag(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:Eg(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=>Zr(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:ss(Xr(t.outputPreview??""),vg)}}function Ig(t){let e=xg(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>Yr)return[];let r=n.map(o=>typeof o=="string"?Zr(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>is)?[]:r.some(as)?[]:r}function xg(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
231
- `).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,Yr)}}}function Tg(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 Cg(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(`
232
- `)}function Mg(t){let e=new Set;return Xr(t??"").replace(/\r\n/g,`
230
+ `),buttons:d}}var Yr=3,ss=180,Ig=4e3,Id=32;function xd(){let t=St(),e=Dg(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=Og(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 xg(t,e){let n=Wg(e);if(n.length>0)return n;let r=Tg(t);if(r.length>0)return r;let o=[],i=t.changedFiles.slice(0,3).map(l=>`\`${l}\``);if(i.length>0){let l=t.changedFiles.length-i.length;o.push(l>0?`Touches ${i.join(", ")} and ${l} more file${l===1?"":"s"}`:`Touches ${i.join(", ")}`)}let s=[...new Set(t.commitMessages.map(l=>l.message.trim()).filter(Boolean))].slice(0,2);return s.length>0&&o.push(`Recent work: ${s.join("; ")}`),o}function Tg(t){let e=new Set,n=t.commitMessages.length===1?t.changedFiles:[];return t.commitMessages.map(r=>Cg(r.message,n)).filter(r=>!!r).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Yr)}function Cg(t,e){let n=Mg(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 as(`${n}${r}.`,ss)}function Mg(t){let e=Zr(Xr(t)).replace(/^(?:feat|fix|docs|style|refactor|perf|test|tests|build|ci|chore|revert)(?:\([^)]+\))?!?:\s*/i,"").replace(/\.$/,"").trim();if(!e||ls(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 Td(t){let e=_g(t),n=xg(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=$g(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 _g(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:Bg(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=>Zr(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:as(Xr(t.outputPreview??""),Ig)}}function $g(t){let e=Eg(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>Yr)return[];let r=n.map(o=>typeof o=="string"?Zr(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>ss)?[]:r.some(ls)?[]:r}function Eg(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
231
+ `).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,Yr)}}}function Dg(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 Og(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(`
232
+ `)}function Wg(t){let e=new Set;return Xr(t??"").replace(/\r\n/g,`
233
233
  `).split(`
234
- `).map(r=>Zr(r)).map(r=>_g(r)).filter($g).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Yr)}function _g(t){return t.replace(/^(?:summary|done|completed|changes|validation|verified)\s*:\s*/i,"").trim()}function $g(t){return t.length<12||t.length>is||as(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 Eg(t){let e=t?.replace(/\r\n/g,`
234
+ `).map(r=>Zr(r)).map(r=>Ng(r)).filter(Lg).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Yr)}function Ng(t){return t.replace(/^(?:summary|done|completed|changes|validation|verified)\s*:\s*/i,"").trim()}function Lg(t){return t.length<12||t.length>ss||ls(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 Bg(t){let e=t?.replace(/\r\n/g,`
235
235
  `).split(`
236
- `).map(o=>o.trim()).filter(Boolean).join(" ");if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=Xr(n).replace(/\s+/g," ").trim();return r?ss(r,180):void 0}function Zr(t){return t.replace(/^[-*•]\s+/,"").replace(/\s+/g," ").trim()}function ss(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function Xr(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_-]{${Rd},}\\b`,"g"),"[redacted token]")}function as(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_-]{${Rd},}\\b`).test(t)}he();var eo=class{constructor(e){this.deps=e;this.actions=new Qr({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(`
236
+ `).map(o=>o.trim()).filter(Boolean).join(" ");if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=Xr(n).replace(/\s+/g," ").trim();return r?as(r,180):void 0}function Zr(t){return t.replace(/^[-*•]\s+/,"").replace(/\s+/g," ").trim()}function as(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function Xr(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_-]{${Id},}\\b`,"g"),"[redacted token]")}function ls(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_-]{${Id},}\\b`).test(t)}he();var eo=class{constructor(e){this.deps=e;this.actions=new Qr({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(`
237
237
  `)}notifyAutoMergeConflictEscalation(e,n,r,o,i=[]){this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-escalated",idempotencyKey:`worktree-merge-conflict-escalated:${e.id}:${n}`,userMessage:[`⚠️ [${e.name}] Auto-merge could not finish after one conflict-resolution attempt.`,`Branch \`${n}\` was preserved for manual follow-up.`,"",r,...i.map(s=>`⚠️ ${s}`)].join(`
238
- `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,o,{},[[this.deps.makeOpenPrButton(e.id)]])})}updatePersistedSessionFor(e,n){for(let r of ue(e))this.deps.updatePersistedSession(r,n)}markPendingDecision(e,n={}){this.updatePersistedSessionFor(e,wr(e,n))}markAutoMergeConflictResolving(e,n,r){this.updatePersistedSessionFor(e,ml(e,n,r,{notes:[`resolver_session:${n}`]}))}markMerged(e){this.updatePersistedSessionFor(e,Ct(e,{clearResolverSessionId:!0}))}markReleased(e,n=[]){let r=new Date().toISOString();this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"released",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{state:"released",updatedAt:r,resolvedAt:r,resolutionSource:"lifecycle_resolver",baseBranch:e.worktreeBaseBranch,targetRepo:e.worktreePrTargetRepo,pushRemote:e.worktreePushRemote,notes:n}})}async handleWorktreeStrategy(e){let n=await this.actions.plan(e);if(n.kind==="skip")return n.result;if(n.kind==="notify")return this.deps.dispatchSessionNotification(e,{label:n.label,idempotencyKey:["worktree-action",e.id,n.label,e.completedAt??"unknown",e.worktreeBranch??"unknown",e.worktreePath??"unknown"].join(":"),userMessage:n.message}),{notificationSent:!0,worktreeRemoved:!1};if(n.kind==="dirty-uncommitted")return this.handleDirtyUncommittedCompletion(e,n.worktreePath,n.branchName,n.baseBranch);if(n.kind==="no-change")return this.handleNoChange(e,n.repoDir,n.worktreePath,n.nativeBackendWorktree);if(n.kind==="merged"){let r=n.nativeBackendWorktree?!0:ce(n.repoDir,n.worktreePath);return Se(n.repoDir,n.branchName),this.markMerged(e),{notificationSent:!1,worktreeRemoved:r}}return n.policyBlocked?(this.markPendingDecision(e,{notes:n.policyReason?[n.policyReason]:void 0}),this.deps.dispatchSessionNotification(e,{label:"worktree-policy-blocked",idempotencyKey:`worktree-policy-blocked:${e.id}:${n.branchName}:${n.baseBranch}`,userMessage:`⚠️ [${e.name}] ${n.policyReason??"Repo policy blocked automatic follow-through."}`,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,n.allowedActions,{allowDelegate:!0})}),{notificationSent:!0,worktreeRemoved:!1}):n.strategy==="ask"?await this.handleAskStrategy(e,n.branchName,n.baseBranch,n.diffSummary,n.allowedActions,n.policyReason):n.strategy==="delegate"?this.handleDelegateStrategy(e,n.branchName,n.baseBranch,n.diffSummary,n.allowedActions,n.policyReason):n.strategy==="auto-merge"?(await this.handleAutoMergeStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.diffSummary,n.sessionRef,n.allowedActions),{notificationSent:!0,worktreeRemoved:!1}):n.strategy==="auto-pr"?this.handleAutoPrStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.allowedActions):{notificationSent:!1,worktreeRemoved:!1}}async handleNoChange(e,n,r,o=le(e)){let i=o?!0:ce(n,r);return i?(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0,worktreeDisposition:"no-change-cleaned",worktreeState:"none",worktreeLifecycle:{state:"no_change",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"strategy_no_change",baseBranch:e.worktreeBaseBranch,targetRepo:e.worktreePrTargetRepo,pushRemote:e.worktreePushRemote}}),this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:o,cleanupSucceeded:!0,worktreePath:r,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)}))):this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:o,cleanupSucceeded:!1,worktreePath:r,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)})),{notificationSent:!0,worktreeRemoved:i}}async handleAskStrategy(e,n,r,o,i,s){let l=await Id({sessionName:e.name,prompt:e.prompt,diffSummary:o,outputPreview:this.deps.getOutputPreview(e,4e3),provider:this.deps.worktreeSummaryProvider});return this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildAskNotification({session:e,branchName:n,baseBranch:r,diffSummary:o,summaryLines:l.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=Xe(n),s=i.slice(0,20).map(a=>`- ${a}`),l=i.length>20?[`- ...and ${i.length-20} more`]:[];return this.deps.dispatchSessionNotification(e,{label:"worktree-dirty-uncommitted",idempotencyKey:`worktree-dirty-uncommitted:${e.id}:${r}:${o}`,userMessage:[`⚠️ [${e.name}] Session completed with uncommitted worktree changes.`,"",`Branch \`${r}\` has no commits ahead of \`${o}\`, so merge/PR follow-through is blocked until the worktree is fixed.`,`Worktree: ${n}`,"",...s.length>0?["Dirty entries:",...s,...l,""]:[],"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(`
238
+ `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,o,{},[[this.deps.makeOpenPrButton(e.id)]])})}updatePersistedSessionFor(e,n){for(let r of ue(e))this.deps.updatePersistedSession(r,n)}markPendingDecision(e,n={}){this.updatePersistedSessionFor(e,wr(e,n))}markAutoMergeConflictResolving(e,n,r){this.updatePersistedSessionFor(e,gl(e,n,r,{notes:[`resolver_session:${n}`]}))}markMerged(e){this.updatePersistedSessionFor(e,Ct(e,{clearResolverSessionId:!0}))}markReleased(e,n=[]){let r=new Date().toISOString();this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"released",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{state:"released",updatedAt:r,resolvedAt:r,resolutionSource:"lifecycle_resolver",baseBranch:e.worktreeBaseBranch,targetRepo:e.worktreePrTargetRepo,pushRemote:e.worktreePushRemote,notes:n}})}async handleWorktreeStrategy(e){let n=await this.actions.plan(e);if(n.kind==="skip")return n.result;if(n.kind==="notify")return this.deps.dispatchSessionNotification(e,{label:n.label,idempotencyKey:["worktree-action",e.id,n.label,e.completedAt??"unknown",e.worktreeBranch??"unknown",e.worktreePath??"unknown"].join(":"),userMessage:n.message}),{notificationSent:!0,worktreeRemoved:!1};if(n.kind==="dirty-uncommitted")return this.handleDirtyUncommittedCompletion(e,n.worktreePath,n.branchName,n.baseBranch);if(n.kind==="no-change")return this.handleNoChange(e,n.repoDir,n.worktreePath,n.nativeBackendWorktree);if(n.kind==="merged"){let r=n.nativeBackendWorktree?!0:ce(n.repoDir,n.worktreePath);return Se(n.repoDir,n.branchName),this.markMerged(e),{notificationSent:!1,worktreeRemoved:r}}return n.policyBlocked?(this.markPendingDecision(e,{notes:n.policyReason?[n.policyReason]:void 0}),this.deps.dispatchSessionNotification(e,{label:"worktree-policy-blocked",idempotencyKey:`worktree-policy-blocked:${e.id}:${n.branchName}:${n.baseBranch}`,userMessage:`⚠️ [${e.name}] ${n.policyReason??"Repo policy blocked automatic follow-through."}`,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,n.allowedActions,{allowDelegate:!0})}),{notificationSent:!0,worktreeRemoved:!1}):n.strategy==="ask"?await this.handleAskStrategy(e,n.branchName,n.baseBranch,n.diffSummary,n.allowedActions,n.policyReason):n.strategy==="delegate"?this.handleDelegateStrategy(e,n.branchName,n.baseBranch,n.diffSummary,n.allowedActions,n.policyReason):n.strategy==="auto-merge"?(await this.handleAutoMergeStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.diffSummary,n.sessionRef,n.allowedActions),{notificationSent:!0,worktreeRemoved:!1}):n.strategy==="auto-pr"?this.handleAutoPrStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.allowedActions):{notificationSent:!1,worktreeRemoved:!1}}async handleNoChange(e,n,r,o=le(e)){let i=o?!0:ce(n,r);return i?(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0,worktreeDisposition:"no-change-cleaned",worktreeState:"none",worktreeLifecycle:{state:"no_change",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"strategy_no_change",baseBranch:e.worktreeBaseBranch,targetRepo:e.worktreePrTargetRepo,pushRemote:e.worktreePushRemote}}),this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:o,cleanupSucceeded:!0,worktreePath:r,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)}))):this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:o,cleanupSucceeded:!1,worktreePath:r,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)})),{notificationSent:!0,worktreeRemoved:i}}async handleAskStrategy(e,n,r,o,i,s){let l=await Td({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:l.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=Xe(n),s=i.slice(0,20).map(a=>`- ${a}`),l=i.length>20?[`- ...and ${i.length-20} more`]:[];return this.deps.dispatchSessionNotification(e,{label:"worktree-dirty-uncommitted",idempotencyKey:`worktree-dirty-uncommitted:${e.id}:${r}:${o}`,userMessage:[`⚠️ [${e.name}] Session completed with uncommitted worktree changes.`,"",`Branch \`${r}\` has no commits ahead of \`${o}\`, so merge/PR follow-through is blocked until the worktree is fixed.`,`Worktree: ${n}`,"",...s.length>0?["Dirty entries:",...s,...l,""]:[],"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(`
239
239
  `)}),{notificationSent:!0,worktreeRemoved:!1}}handleAutoMergeSuccess(e,n,r,o,i,s){Se(n,r),this.markMerged(e);let l=et({kind:"merge",branch:r,base:o,filesChanged:i.filesChanged,insertions:i.insertions,deletions:i.deletions}),a=l;s.stashPopConflict?a+=`
240
240
  ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${s.stashRef??"stash@{0}"}\` in ${n} to review stashed changes.`:s.stashed&&(a+=`
241
241
  (Pre-existing changes on ${o} were auto-stashed and restored.)`),a=Ce(a,s);let d=It(s),u=[s.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",`Auto-merge landed ${r} into ${o}.`,"Local worktree branch cleanup was requested.",...s.stashPopConflict?[`Pre-merge stash pop conflicted; run git stash show ${s.stashRef??"stash@{0}"} in ${n} to review stashed changes.`]:[],...!s.stashPopConflict&&s.stashed?[`Pre-existing changes on ${o} were auto-stashed and restored.`]:[],...d];this.deps.dispatchSessionNotification(e,{label:"worktree-merge-success",idempotencyKey:`worktree-merge-success:${e.id}:${r}:${o}`,userMessage:a,notifyUser:"always",completionSummary:{required:!0,producer:"worktree",outcomeKey:`terminal:${e.id}`},completionWakeSummaryRequired:!0,completionWakeOutcomeKey:`terminal:${e.id}`,deferConditionalWakeUntilNextTick:!0,wakeMessageOnNotifySuccess:Wt({sessionId:e.id,sessionName:e.name,outcomeLine:l,originThreadLine:this.deps.originThreadLine(e),detailLines:u,canonicalStatusDelivered:!0}),wakeMessageOnNotifyFailed:Wt({sessionId:e.id,sessionName:e.name,outcomeLine:l,originThreadLine:this.deps.originThreadLine(e),detailLines:u,canonicalStatusDelivered:!1})})}async handleInitialAutoMergeConflict(e,n,r,o,i,s,l,a){let d=a?It(a):[],u=e.autoMergeConflictResolutionAttemptCount??0;if(u>=1){this.markPendingDecision(e,{notes:["auto_merge_conflict_retry_exhausted"],clearResolverSessionId:!0}),this.notifyAutoMergeConflictEscalation(e,o,s.pr?`The rebased branch still conflicts with \`${i}\`. Open a PR or resolve manually in ${r}.`:`The rebased branch still conflicts with \`${i}\`. Resolve manually in ${r}.`,s,d);return}let c=this.buildConflictResolverPrompt({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,mergeError:l});try{let m=await this.deps.spawnConflictResolver({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,prompt:c});this.markAutoMergeConflictResolving(e,m.id,u+1),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-resolving",idempotencyKey:`worktree-merge-conflict-resolving:${e.id}:${o}:${m.id}`,userMessage:[`⚠️ [${e.name}] Auto-merge hit a rebase conflict. Started resolver session ${m.name} and will retry automatically if it succeeds.`,...d.map(p=>`⚠️ ${p}`)].join(`
242
242
  `)})}catch(m){this.markPendingDecision(e,{notes:["auto_merge_conflict_resolver_spawn_failed"]}),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-spawn-failed",idempotencyKey:`worktree-merge-conflict-spawn-failed:${e.id}:${o}`,userMessage:[`❌ [${e.name}] Auto-merge hit a rebase conflict and failed to start the resolver: ${m instanceof Error?m.message:String(m)}`,...d.map(p=>`⚠️ ${p}`)].join(`
243
243
  `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,s,{},[[this.deps.makeOpenPrButton(e.id)]])})}}handleAutoMergeRetryFailure(e,n,r,o,i){this.markPendingDecision(e,{notes:["auto_merge_conflict_retry_failed"],clearResolverSessionId:!0}),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${n}`,userMessage:[o,"","Auto-merge retry did not complete after conflict resolution.",`Branch \`${n}\` was preserved for manual follow-up in ${r}.`].join(`
244
- `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i,{},[[this.deps.makeOpenPrButton(e.id)]])})}async handleAutoMergeStrategy(e,n,r,o,i,s,l=K(e)??e.harnessSessionId,a={merge:!0,pr:!0}){this.deps.isAlreadyMerged(l)||e.autoMergeResolverSessionId||await this.deps.enqueueMerge(n,async()=>{if(this.deps.isAlreadyMerged(l))return;let d=this.deps.mergeBranch(n,o,i,"merge",r);if(d.success){this.handleAutoMergeSuccess(e,n,o,i,s,d);return}if(d.rebaseConflict){await this.handleInitialAutoMergeConflict(e,n,r,o,i,a,d.error,d);return}let u=Ce(d.dirtyError?`❌ [${e.name}] Merge blocked: ${d.error}`:`❌ [${e.name}] Merge failed: ${d.error??"unknown error"}`,d);if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,o,r,u,a);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${o}`,userMessage:u})},()=>{this.deps.dispatchSessionNotification(e,{label:"worktree-merge-queued",idempotencyKey:`worktree-merge-queued:${e.id}:${o}`,userMessage:`🕐 [${e.name}] Merge queued — another merge for this repo is in progress. Will notify when complete.`})})}async handleAutoPrStrategy(e,n,r,o,i,s={merge:!0,pr:!0}){if(this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_in_progress"}),!(await this.deps.runAutoPr(e,i)).success){let a=Pt(n);if(!!(a&&a!==o&&wt(n,o,a)&&Xe(r).length===0)){let u=le(e)?!0:ce(n,r);return u&&(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0})),Se(n,o),this.markReleased(e,[`released_by_branch:${a}`]),{notificationSent:!1,worktreeRemoved:u}}this.markPendingDecision(e),this.deps.dispatchSessionNotification(e,{label:"worktree-auto-pr-failed",idempotencyKey:`worktree-auto-pr-failed:${e.id}:${i}`,userMessage:`⚠️ [${e.name}] Auto-PR did not complete. The worktree is preserved for an explicit merge or PR decision.`,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,s)})}return{notificationSent:!0,worktreeRemoved:!1}}};import{existsSync as gh,statSync as hh,writeFileSync as yh}from"fs";be();import{randomUUID as Dg}from"crypto";function Og(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var to=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:Dg(),sessionId:e,kind:n,createdAt:Date.now(),...r};return this.tokens.set(o.id,o),this.notifyChanged(),o}getActionToken(e){let n=this.tokens.get(e);if(n){if(n.expiresAt!=null&&n.expiresAt<=Date.now()){this.tokens.delete(e),this.notifyChanged();return}return n}}listActiveActionTokens(e){let n=[];for(let r of[...this.tokens.keys()]){let o=this.getActionToken(r);!o||o.consumedAt!=null||e&&o.kind!==e||n.push(o)}return n}consumeActionToken(e){let n=this.getActionToken(e);if(!(!n||n.consumedAt!=null))return n.consumedAt=Date.now(),this.notifyChanged(),n}deleteActionTokensForSession(e){let n=!1;for(let[r,o]of this.tokens)o.sessionId===e&&(this.tokens.delete(r),n=!0);n&&this.notifyChanged()}deleteActionTokensForSessionByKind(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId===e&&i.kind===n&&(this.tokens.delete(o),r=!0);r&&this.notifyChanged()}deletePlanDecisionTokensForSession(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId!==e||!Og(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?.()}};Z();Z();var no=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 l of this.indexes.persisted.values()){if(l.name!==e){s++;continue}let a=l.createdAt??Number.NEGATIVE_INFINITY,d=l.completedAt??Number.NEGATIVE_INFINITY;(a>r||a===r&&d>o||a===r&&d===o&&s>i)&&(n=l,r=a,o=d,i=s),s++}return n}resolveBackendConversationId(e,n){if(n)return n;let r=this.indexes.idIndex.get(e);if(r){let s=this.indexes.persisted.get(r);return(s?$(s):void 0)??r}let o=this.getLatestPersistedByName(e);if(o)return $(o)??o.harnessSessionId;let i=this.indexes.backendIdIndex.get(e);if(i){let s=this.indexes.persisted.get(i);return(s?$(s):void 0)??i}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?$(s)??e:e}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e))return e}resolveHarnessSessionId(e,n){return this.resolveBackendConversationId(e,n)}getPersistedSession(e){let n=this.indexes.idIndex.get(e);if(n)return this.indexes.persisted.get(n);let r=this.getLatestPersistedByName(e);if(r)return r;let o=this.indexes.backendIdIndex.get(e);return o?this.indexes.persisted.get(o):this.indexes.persisted.get(e)}listPersistedSessions(){return[...this.indexes.persisted.values()].sort((e,n)=>(n.completedAt??0)-(e.completedAt??0))}};import{existsSync as Wd,mkdirSync as ah,readFileSync as lh,readdirSync as dh,renameSync as Nd,statSync as Ld,unlinkSync as Bd,writeFileSync as Fd}from"fs";import{tmpdir as uh}from"os";import{dirname as ch,join as qd}from"path";import{homedir as Wg}from"node:os";import{join as Ng}from"node:path";function xd(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||Wg();return Ng(n,".openclaw")}be();var ro=7,Lg=new Set(["running","completed","failed","killed"]);function Ge(t){return!!t&&typeof t=="object"}function Nt(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 Td(t){return typeof t=="string"&&il.has(t)?t:void 0}function ls(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function Bg(t){return t==="never"||t==="on-request"?"never":void 0}function Cd(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function Fg(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function Md(t){return typeof t=="string"&&vr.has(t)?t:void 0}function ds(t){return typeof t=="string"&&ol.has(t)?t:void 0}function _d(t){return t==="github"||t==="unsupported"?t:void 0}function qg(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function Kg(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function Ug(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 Vg(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function Gg(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 jg(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 Hg(t){return t==="live"||t==="stopped"?t:void 0}function zg(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function Qg(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function Jg(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function Yg(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function Zg(t){return t==="in_flight"||t==="delivered"?t:void 0}function Xg(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ge(n))return;let r=P(n.key),o=Zg(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 eh(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ge(n))return;let r=P(n.key),o=P(n.recordedAt);if(!(!r||!o||!Number.isFinite(Date.parse(o))))return{key:r,recordedAt:o,label:P(n.label),skipReason:P(n.skipReason)}}).filter(n=>!!n);return e.length>0?e.slice(-1024):void 0}function th(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 nh(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 $d(t){if(!Ge(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 rh(t,e,n){if(Ge(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 oh(t){if(!Ge(t))return;let e=jg(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 ih(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 sh(t){if(typeof t=="string"&&Lg.has(t))return t==="running"?"killed":t}function Ed(t){if(!Ge(t))return;let e=Nt(t.harnessSessionId);if(!e)return;let n=sh(t.status);if(!n)return;let r=t.status==="running",o=P(t.worktreePath),i=P(t.worktreeBranch),s=P(t.originChannel),l=typeof t.originThreadId=="string"||typeof t.originThreadId=="number"?t.originThreadId:void 0,a=P(t.originSessionKey),d=$d(t.route);if(!d)return;let u=He({route:d,originChannel:s,originThreadId:l,originSessionKey:a});if(!u||o&&!i)return;let c=P(t.harness),m=rh(t.backendRef,c,e),p=oh(t.worktreeLifecycle)??ih(t),f=P(t.completionWakeSucceededAt),h=P(t.completionWakeSkippedAt),k=t.completionWakeSummaryRequired===!0&&!h?!0:void 0;return{sessionId:P(t.sessionId),harnessSessionId:e,backendRef:m,name:Nt(t.name,e),prompt:Nt(t.prompt),workdir:Nt(t.workdir,"(unknown)"),model:P(t.model),reasoningEffort:Td(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:pe(t.createdAt),completedAt:pe(t.completedAt),status:n,lifecycle:r?"suspended":Ug(t.lifecycle),approvalState:Vg(t.approvalState),worktreeState:Gg(t.worktreeState),runtimeState:r?"stopped":Hg(t.runtimeState),deliveryState:Yg(t.deliveryState),notificationDedupe:Xg(t.notificationDedupe),completionSummaryDedupe:eh(t.completionSummaryDedupe),completionWakeIssuedAt:P(t.completionWakeIssuedAt),completionWakeSucceededAt:f,completionWakeFailedAt:P(t.completionWakeFailedAt),completionWakeSkippedAt:h,completionWakeSkipReason:P(t.completionWakeSkipReason),completionWakeSummaryRequired:k,killReason:Kg(t.killReason),costUsd:typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)?t.costUsd:0,originAgentId:P(t.originAgentId),originChannel:s,originThreadId:l,originSessionKey:a,route:u,outputPath:P(t.outputPath),harness:c,goalTaskId:P(t.goalTaskId),requestedPermissionMode:ls(t.requestedPermissionMode),currentPermissionMode:ls(t.currentPermissionMode),approvalExecutionState:th(t.approvalExecutionState),approvalRationale:P(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:Fg(t.planApprovalContext),planDecisionVersion:pe(t.planDecisionVersion),actionablePlanDecisionVersion:pe(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:pe(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:pe(t.approvalPromptRequiredVersion),approvalPromptVersion:pe(t.approvalPromptVersion),approvalPromptStatus:zg(t.approvalPromptStatus),approvalPromptTransport:Qg(t.approvalPromptTransport),approvalPromptMessageKind:Jg(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:P(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:P(t.approvalPromptDeliveredAt),approvalPromptFailedAt:P(t.approvalPromptFailedAt),planApproval:Cd(t.planApproval),codexApprovalPolicy:Bg(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:Md(t.worktreeStrategy),repoIntegrationPolicy:ds(t.repoIntegrationPolicy),repoIntegrationPolicySource:qg(t.repoIntegrationPolicySource),repoProvider:_d(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),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,worktreeDismissedAt:P(t.worktreeDismissedAt),worktreeLifecycle:p,resumable:r?!0:t.resumable===!0}}function Dd(t){if(!Ge(t))return;let e=P(t.key),n=P(t.repoRoot),r=ds(t.policy),o=_d(t.provider)??"unsupported",i=P(t.createdAt),s=P(t.updatedAt),l=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:l}}function Od(t){if(!Ge(t))return;let e=nh(t.kind),n=Nt(t.id),r=Nt(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:$d(t.route),launchName:P(t.launchName),launchPrompt:P(t.launchPrompt),launchWorkdir:P(t.launchWorkdir),launchModel:P(t.launchModel),launchReasoningEffort:Td(t.launchReasoningEffort),launchFastMode:t.launchFastMode===!0?!0:void 0,launchSystemPrompt:P(t.launchSystemPrompt),launchAllowedTools:Array.isArray(t.launchAllowedTools)?t.launchAllowedTools.filter(i=>typeof i=="string"):void 0,launchResumeSessionId:P(t.launchResumeSessionId),launchResumeWorktreeFrom:P(t.launchResumeWorktreeFrom),launchSessionIdOverride:P(t.launchSessionIdOverride),launchClearedPersistedCodexResume:t.launchClearedPersistedCodexResume===!0?!0:void 0,launchForkSession:typeof t.launchForkSession=="boolean"?t.launchForkSession:void 0,launchForceNewSession:typeof t.launchForceNewSession=="boolean"?t.launchForceNewSession:void 0,launchPermissionMode:ls(t.launchPermissionMode),launchPlanApproval:Cd(t.launchPlanApproval),launchHarness:P(t.launchHarness),launchWorktreeStrategy:Md(t.launchWorktreeStrategy),launchWorktreeBaseBranch:P(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:P(t.launchWorktreePrTargetRepo),launchOriginAgentId:P(t.launchOriginAgentId),repoPolicy:ds(t.repoPolicy),repoPolicyWorkdir:P(t.repoPolicyWorkdir)}}function oo(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 us(t){return!!t&&typeof t=="object"}function cs(t){return t instanceof Error?t.message:String(t)}function Kd(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(!Wd(s))return s}}function ps(){let t=uh();return dh(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>qd(t,e))}function Ud(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||qd(xd(t),"code-agent-sessions.json")}function Vd(t,e,n,r=[]){try{ah(ch(t),{recursive:!0});let o=t+".tmp";Fd(o,JSON.stringify({schemaVersion:ro,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),Nd(o,t)}catch(o){`${cs(o)}`}}function ph(t,e){try{if(!Wd(t))return!1;let n=Kd(t,"legacy");return n?(Nd(t,n),`${e}${n}`,!0):!1}catch(n){return`${cs(n)}`,!1}}var mh={archiveLegacySessionIndex:ph};function fh(t,e){try{if(e.length===0)return;let n=Kd(t,"codex-sdk-legacy");if(!n)return;Fd(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${cs(n)}`}}function Gd(t,e,n=[]){try{let r=new Set(n);for(let o of ps())if(!r.has(o))try{let i=Ld(o).mtimeMs;t-i>e&&Bd(o)}catch{}}catch{}}function jd(t,e,n=[]){try{let r=new Set(n),o;for(let i of ps())if(!r.has(i))try{let s=Ld(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function Hd(t){try{let e=new Set(t);for(let n of ps())if(!e.has(n))try{Bd(n)}catch{}}catch{}}function zd(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:l}=t,a=d=>mh.archiveLegacySessionIndex(e,d)?(n(),!0):!1;try{let d=lh(e,"utf-8"),u=JSON.parse(d);if(Array.isArray(u)){if(!a("legacy array store"))return;l();return}if(!us(u)||u.schemaVersion!==ro&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!a(`schema mismatch (expected v${ro})`))return;l();return}let c=(w,A)=>{if(!Object.prototype.hasOwnProperty.call(u,w))return[];let y=u[w];if(Array.isArray(y))return y;a(A)&&l()},m=c("sessions","invalid sessions collection");if(m===void 0)return;let p=[],f=[];for(let w of m){if(us(w)&&w.harness==="codex"){let y=us(w.backendRef)?w.backendRef:void 0;if((typeof y?.kind=="string"?y.kind:void 0)!=="codex-app-server"){p.push(w);continue}}let A=Ed(w);if(!A){if(!a("invalid v4 session entry"))return;l();return}f.push(A)}p.length>0&&fh(e,p);let h=c("actionTokens","invalid action token collection");if(h===void 0)return;let k=[];for(let w of h){let A=Od(w);if(!A){if(!a("invalid v4 action token"))return;l();return}k.push(A)}let v=c("repoPolicies","invalid repo policy collection");if(v===void 0)return;let I=[],x=!1;for(let w of v){let A=Dd(w);if(!A){x=!0;continue}I.push(A)}for(let w of f)r(w);for(let w of k)o(w);for(let w of I)i(w);p.length>0&&l(),x&&l(),s()}catch(d){if(d.code==="ENOENT"||!a("corrupt or unreadable"))return;l()}}var kh=new Set(["completed","failed","killed"]),ms=1440*60*1e3;function Sh(t){return t instanceof Error?t.message:String(t)}var vh={statSync:hh};function Ph(t){try{return vh.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var io=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??Ud(n),this.actionTokenStore=new to(()=>this.saveIndex(),ms),this.actionTokens=this.actionTokenStore.tokens,this.queries=new no({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){zd({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(){Vd(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){oo(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=si(e),r=n==="codex"?"codex-app-server":n==="opencode"?"opencode-server":"claude-code";return e.backendRef??{kind:e.backendKind??r,conversationId:e.harnessSessionId}}getSessionApprovalSnapshot(e){if(typeof e.approvalSnapshot=="function")return e.approvalSnapshot();let n=typeof e.controlStateSnapshot=="function"?e.controlStateSnapshot():{planModeApproved:!1};return{requestedPermissionMode:e.requestedPermissionMode,currentPermissionMode:e.currentPermissionMode,approvalExecutionState:e.approvalExecutionState,approvalRationale:e.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy}}getSessionRoutingSnapshot(e){return typeof e.routingSnapshot=="function"?e.routingSnapshot():{route:e.route,originAgentId:e.originAgentId,originChannel:e.originChannel,originThreadId:e.originThreadId,originSessionKey:e.originSessionKey}}getSessionWorktreeSnapshot(e){return typeof e.worktreeSnapshot=="function"?e.worktreeSnapshot():{worktreePath:e.worktreePath,worktreeBranch:e.worktreeBranch,worktreeStrategy:e.worktreeStrategy,repoIntegrationPolicy:e.repoIntegrationPolicy,repoIntegrationPolicySource:e.repoIntegrationPolicySource,repoProvider:e.repoProvider,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,autoMergeParentSessionId:e.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:e.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:e.autoMergeResolverSessionId,worktreeLifecycle:e.worktreeLifecycle}}indexPersistedEntry(e){let n=this.getEntryStorageKey(e);this.persisted.set(n,e),e.sessionId&&this.idIndex.set(e.sessionId,n),e.name&&this.nameIndex.set(e.name,n);let r=$(e);r&&this.backendIdIndex.set(r,n)}removePersistedIndexes(e){let n=this.getEntryStorageKey(e);this.persisted.delete(n);for(let[r,o]of this.idIndex)o===n&&this.idIndex.delete(r);for(let[r,o]of this.nameIndex)o===n&&this.nameIndex.delete(r);for(let[r,o]of this.backendIdIndex)o===n&&this.backendIdIndex.delete(r)}markRunning(e){if(!e.harnessSessionId)return;let n=this.getSessionApprovalSnapshot(e),r=this.getSessionRoutingSnapshot(e),o=this.getSessionWorktreeSnapshot(e),i=He({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,status:"running",lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),costUsd:0,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:Ze(e.id),harness:e.harnessName,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalRationale:n.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planApproval:n.planApproval,codexApprovalPolicy:n.codexApprovalPolicy,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,repoIntegrationPolicy:o.repoIntegrationPolicy,repoIntegrationPolicySource:o.repoIntegrationPolicySource,repoProvider:o.repoProvider,worktreeBaseBranch:o.worktreeBaseBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};oo(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=He({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let a=Ze(e.id);if(gh(a))s=a;else{let d=e.getOutput().join(`
245
- `);d.length>0&&(yh(a,d,"utf-8"),s=a)}}catch(a){`${e.id}${Sh(a)}`}let l={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,completedAt:e.completedAt,status:e.status,lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),killReason:e.killReason,costUsd:e.costUsd,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:s,harness:e.harnessName,goalTaskId:e.goalTaskId,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalRationale:n.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planApproval:n.planApproval,codexApprovalPolicy:n.codexApprovalPolicy,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,worktreeBaseBranch:o.worktreeBaseBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};oo(l),this.indexPersistedEntry(l),this.saveIndex()}getExistingNotificationDedupe(e){return this.getPersistedSession(e.id)?.notificationDedupe??(e.harnessSessionId?this.getPersistedSession(e.harnessSessionId)?.notificationDedupe:void 0)??($(e)?this.getPersistedSession($(e))?.notificationDedupe:void 0)}getLatestPersistedByName(e){return this.queries.getLatestPersistedByName(e)}resolveBackendConversationId(e,n){return this.queries.resolveBackendConversationId(e,n)}resolveHarnessSessionId(e,n){return this.queries.resolveHarnessSessionId(e,n)}getPersistedSession(e){return this.queries.getPersistedSession(e)}listPersistedSessions(){return this.queries.listPersistedSessions()}getRepoPolicy(e){return this.repoPolicies.get(e)}listRepoPolicies(){return[...this.repoPolicies.values()].sort((e,n)=>e.repoRoot.localeCompare(n.repoRoot)||e.key.localeCompare(n.key))}setRepoPolicy(e){let n=this.repoPolicies.get(e.key),r={...e,createdAt:n?.createdAt??e.createdAt,updatedAt:new Date().toISOString(),source:"stored"};return this.repoPolicies.set(r.key,r),this.saveIndex(),r}updateRepoPolicy(e,n){let r=this.repoPolicies.get(e);if(r)return this.setRepoPolicy({...r,policy:n})}resetRepoPolicy(e){let n=this.repoPolicies.delete(e);return n&&this.saveIndex(),n}removeRepoPolicies(e){let n=[];for(let r of e){let o=this.repoPolicies.get(r);o&&(this.repoPolicies.delete(r),n.push(o))}return n.length>0&&this.saveIndex(),n.sort((r,o)=>r.repoRoot.localeCompare(o.repoRoot)||r.key.localeCompare(o.key))}cleanupRepoPolicies(){let e=[];for(let[n,r]of this.repoPolicies)Ph(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),Gd(e,ms,this.getReferencedOutputPaths())}getNextTmpOutputCleanupAt(e){return jd(e,ms,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||!kh.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(){Hd(this.getReferencedOutputPaths())}};var wh=new Set(["completed","failed","killed"]),so=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),wh.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:se(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 Yd from"child_process";var Qd=5e3,Zd=64,bh={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},Rh={execFile:Yd.execFile},je=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},lo=class{constructor(e=Rh.execFile){this.execFile=e}execFile;async send(e,n,r){B("direct_send_started",{...we(e),messageTextLength:n.length,...z(r)});try{await this.sendViaRuntime(e,n,r),B("direct_send_succeeded",{...we(e),deliveryPath:"runtime",...z(r)});return}catch(o){if(!(o instanceof je))throw B("direct_send_failed",{...we(e),deliveryPath:"runtime",...z(r),error:fs(o)}),o;B("direct_send_runtime_capability_missing",{...we(e),deliveryPath:"runtime",...z(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),B("direct_send_succeeded",{...we(e),deliveryPath:"cli-fallback",...z(r)})}}async sendViaRuntime(e,n,r){let o=St(),i=ga(),s=o?.channel?.outbound?.loadAdapter;if(!o)throw new je("OpenClaw plugin runtime is unavailable for direct notification delivery");if(i==null)throw new je("OpenClaw runtime config snapshot is unavailable for direct notification delivery");if(!o.channel)throw new je(`OpenClaw plugin runtime channel surface is unavailable for direct notification delivery (runtimeVersion=${gs(o)})`);if(!o.channel.outbound)throw new je(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${gs(o)})`);if(!s)throw new je(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${gs(o)})`);let l=await s(e.channel);if(!l)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let a=co(r);if(B("runtime_adapter_loaded",{...we(e),adapterHasRenderPresentation:typeof l.renderPresentation=="function",adapterHasSendPayload:typeof l.sendPayload=="function",adapterHasSendText:typeof l.sendText=="function",...z(r),...a?Fi(a):{}}),a){await this.sendPresentation(l,i,e,n,a);return}if(!l.sendText)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" cannot send text`);await l.sendText({cfg:i,to:e.target,text:n,accountId:e.accountId,threadId:e.threadId})}async sendPresentation(e,n,r,o,i){let s=Ih(i),l={text:o,presentation:i,interactive:s};B("presentation_render_started",{...we(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Fi(i)});let a={cfg:n,to:r.target,text:o,payload:l,accountId:r.accountId,threadId:r.threadId},d=e.renderPresentation?await e.renderPresentation({payload:l,presentation:i,ctx:a}):l,u=Th(d,s,r.channel);if(B("presentation_render_completed",{...we(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...qi(u)}),!u||typeof u!="object"||!e.sendPayload)throw new Error(`OpenClaw outbound adapter for channel "${r.channel}" cannot preserve interactive presentation`);let c=await e.sendPayload({...a,payload:u});B("presentation_send_payload_completed",{...we(r),...qi(u),...$l(c)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let l=Ah(e,n,r);B("direct_send_cli_fallback_started",{...we(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...z(r)}),this.execFile("openclaw",l,{timeout:Qd,killSignal:"SIGKILL"},(a,d,u)=>{if(!a){B("direct_send_cli_fallback_completed",{...we(e),deliveryPath:"cli-fallback",...z(r)}),i();return}let c=u?.trim()?` | stderr: ${u.trim()}`:"";B("direct_send_cli_fallback_failed",{...we(e),deliveryPath:"cli-fallback",...z(r),error:fs(a),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${Qd}ms timeout: ${fs(a)}${c}`))})})}};function we(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function Ah(t,e,n){let r=co(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 fs(t){return t instanceof Error?t.message:String(t)}function gs(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function co(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:Dh(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function Ih(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 xh(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 Th(t,e,n){if(!e)return t;let r=xh(t)?t:Ch(t,e);return n!=="telegram"?r:Mh(r,e)}function Ch(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function Mh(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Lt(n.channelData),o=Lt(r?.telegram),i=$h(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=_h(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function _h(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")<=Zd).map(r=>({text:r.label,callback_data:r.value,...Xd(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function $h(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")>Zd))&&Eh(i))return{...i,...Xd(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function Eh(t){return uo(t.callback_data)||uo(t.url)||ao(t.web_app)||ao(t.webApp)||ao(t.login_url)||ao(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||Lt(t.switch_inline_query_chosen_chat)!==void 0||Lt(t.callback_game)!==void 0||t.pay===!0||Jd(t.copy_text)||Jd(t.copyText)}function uo(t){return typeof t=="string"&&t.trim().length>0}function ao(t){let e=Lt(t);return uo(e?.url)}function Jd(t){let e=Lt(t);return uo(e?.text)}function Xd(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=bh[e];return n?{style:n}:{}}function Lt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Dh(t){return t.startsWith(`${ye}:`)?t:`${ye}:${t}`}import*as eu from"child_process";var Bt=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()),l=s.catch(()=>{});return this.tails.set(e,l),l.finally(()=>{this.tails.get(e)===l&&this.tails.delete(e)}),s}clear(){this.tails.clear()}};var hs=3e4,Oh=2e3,Wh=2e4,me=4;function wn(t){return t instanceof Error?t.message:String(t)}function Nh(){return new Error(`Dispatch timed out after ${hs}ms`)}function Lh(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var Bh={execFile:eu.execFile},po=class{pendingRetryTimers=new Map;orderedDispatches=new Bt;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:me}),Bh.execFile("openclaw",e,{timeout:hs,killSignal:"SIGKILL"},(s,l,a)=>{if(this.disposed){r?.();return}let d=Date.now()-i;if(!s){let f=n.successValidator?.(l??"");if(f?.outcome==="failure"){this.log("error","dispatch_success_validation_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:me,elapsedMs:d,error:f.reason,terminal:!0}),n.onFinalFailure?.(),r?.();return}if(f?.outcome==="skipped"){this.log("info","dispatch_skipped",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:me,elapsedMs:d,reason:f.reason}),n.shouldContinue?.()!==!1&&n.onSkipped?.(f.reason),r?.();return}this.log("info","dispatch_succeeded",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:me,elapsedMs:d}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.();return}let u=a?.trim()?` | stderr: ${a.trim()}`:"";if(n.shouldContinue?.()===!1){r?.();return}if(n.target==="message.send"&&Lh(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:me,elapsedMs:d,error:`${wn(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(o>=me||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:me,elapsedMs:d,error:`${wn(s)}${u}`,terminal:!0}),n.onFinalFailure?.(),r?.();return}let m=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:me,elapsedMs:d,retryDelayMs:m,error:`${wn(s)}${u}`});let p={timer:setTimeout(()=>{let f=this.pendingRetryTimers.get(n.sessionId);if(f&&(f.delete(p),f.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executeNow(e,n,r,o+1)},m),onCleared:r};p.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(p)})}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:me}),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:me,elapsedMs:s}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.()}).catch(s=>{if(this.disposed){r?.();return}let l=Date.now()-i;if(n.shouldContinue?.()===!1){r?.();return}if(o>=me||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:me,elapsedMs:l,error:wn(s),terminal:!0,...n.terminalOnFailure===!0&&o<me?{terminalReason:"non_retryable"}:{}}),n.onFinalFailure?.(),r?.();return}let a=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:me,elapsedMs:l,retryDelayMs:a,error:wn(s)});let d={timer:setTimeout(()=>{let u=this.pendingRetryTimers.get(n.sessionId);if(u&&(u.delete(d),u.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executePromiseNow(e,n,r,o+1)},a),onCleared:r};d.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(d)})}executePromiseWithTimeout(e){return new Promise((n,r)=>{let o=!1,i=setTimeout(()=>{o||(o=!0,r(Nh()))},hs);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=Oh*2**n;return Math.min(r,Wh)}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}}};be();var mo=class{resolve(e){let n=Me(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 Fh}from"crypto";var fo=class{constructor(e={}){}buildChatSendArgs(e,n,r,o=Fh()){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=co(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 qh(t){let e=Kh(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 Kh(t){let e=t.trim();if(!e)return"";try{return ys(JSON.parse(e)).trim()}catch{return e}}function ys(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>ys(r)).filter(Boolean).join(`
246
- `);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=ys(e[r]);if(o.trim())return o}return""}var go=class{routes=new mo;transport;directNotifications;executor=new po;constructor(e={}){this.transport=e.transport??new fo(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new lo: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,l,a,d,u){let c=this.routes.resolve(e),m=l;if(m?.()===!1)return;let p=c?.sessionKey?.trim();if(!p){this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-system`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:d,onFinalFailure:i,successValidator:a,shouldContinue:m});return}this.executor.execute(this.transport.buildChatSendArgs(p,n,!0,u),{label:r,sessionId:e.id,target:"chat.send",phase:o,routeSummary:`session:${p}`,messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:`session:${p}`,route:c,text:n}),onSuccess:s,onSkipped:d,successValidator:a,shouldContinue:m,onFinalFailure:()=>{m?.()!==!1&&this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-fallback`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:d,onFinalFailure:i,successValidator:a,shouldContinue:m})}})}sendUserNotification(e,n,r,o,i,s,l=!1,a){if(a?.()===!1)return;let d=!!o?.some(f=>Array.isArray(f)&&f.length>0),u=this.routes.resolve(e);B("wake_notify_selected",{sessionId:e.id,sessionName:e.name,label:r,messageTextLength:n.length,requireDirectDelivery:l,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,...z(o)});let c=u?`notify:${u.channel}|${u.accountId??""}|${u.target}|${u.threadId??""}`:`notify:system:${e.id}`;if(!u){if(B("wake_notify_no_direct_route",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:l,hasInteractiveButtons:d,...z(o)}),l){`${r}${e.id}`,i?.();return}if(d){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-system`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n,buttons:o}),orderingKey:c,onSuccess:s,onFinalFailure:i,shouldContinue:a});return}let m=()=>{if(B("wake_notify_direct_failed",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:l,hasInteractiveButtons:d,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...z(o)}),l){`${r}${e.id}`,i?.();return}if(d){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-fallback`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),orderingKey:c,onSuccess:s,onFinalFailure:i,shouldContinue:a})},p={label:`${r}-notify`,sessionId:e.id,target:"message.send",phase:"notify",routeSummary:this.routes.summary(u),messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:this.routes.summary(u),route:u,text:n,buttons:o}),orderingKey:c,onSuccess:s,onAmbiguousResult:m,onFinalFailure:m,terminalOnFailure:this.directNotifications?!0:void 0,shouldContinue:a};if(this.directNotifications){B("wake_notify_dispatching_direct_runtime",{sessionId:e.id,sessionName:e.name,label:r,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...z(o)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,o),p);return}B("wake_notify_dispatching_cli_message_send",{sessionId:e.id,sessionName:e.name,label:r,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...z(o)}),this.executor.execute(this.transport.buildDirectNotificationArgs(u,n,o),p)}sendUserNotificationSequence(e,n,r,o,i,s=!1,l){let a=n.map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0);if(a.length===0){o?.();return}B("wake_notify_sequence_started",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:a.length,buttonChunkIndexes:a.map((u,c)=>u.buttons?.some(m=>Array.isArray(m)&&m.length>0)?c+1:void 0).filter(u=>typeof u=="number"),requireDirectDelivery:s});let d=u=>{if(l?.()===!1)return;let c=a[u];if(!c){B("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:a.length}),i?.();return}let m=u===0?o:i;B("wake_notify_sequence_chunk_selected",{sessionId:e.id,sessionName:e.name,label:r,chunkIndex:u+1,chunkCount:a.length,messageTextLength:c.text.length,failureHandler:u===0?"all-failed":"sequence-success",...z(c.buttons)}),this.sendUserNotification(e,c.text,`${r}-part-${u+1}`,c.buttons,m,()=>d(u+1),s,l)};d(0)}dispatchSessionNotification(e,n){let r=n.hooks,o=n.wakeMessageOnNotifySuccess!=null||n.wakeMessageOnNotifyFailed!=null,i=n.notifyUser??(n.wakeMessage?"on-wake-fallback":"always"),s=(n.userMessages?.length?n.userMessages:n.userMessage?.trim()?[{text:n.userMessage.trim(),buttons:n.buttons}]:[]).map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0),l=n.wakeMessage?.trim(),a=n.shouldDispatch,d=n.completionWakeSummaryRequired===!0?qh:void 0;if(o){let u=n.wakeMessageOnNotifySuccess?.trim(),c=n.wakeMessageOnNotifyFailed?.trim(),m=k=>{k&&a?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,k,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,a,d,r?.onWakeSkipped,n.idempotencyKey))},p=k=>{if(k){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let v=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>m(k),v).unref?.();return}m(k)}},f=()=>{a?.()!==!1&&(r?.onNotifySucceeded?.(),u&&p(u))},h=c?()=>{a?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),p(c))}:()=>{a?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(a?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,h,f,n.requireDirectUserNotification===!0,a)}else h();return}if(i==="always"&&s.length>0){if(a?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{a?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{a?.()!==!1&&r?.onNotifySucceeded?.()},n.requireDirectUserNotification===!0,a)}if(l&&a?.()!==!1){if(r?.onWakeStarted?.(),i==="on-wake-fallback"&&s.length>0&&!this.routes.resolve(e)?.sessionKey){if(a?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{a?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{a?.()!==!1&&r?.onNotifySucceeded?.()},!1,a)}this.sendWake(e,l,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,a,d,r?.onWakeSkipped,n.idempotencyKey)}}};var tu=36,nu=2,ru="...";function Uh(t){let e=Array.from(t);return e.length<=tu?t:`${e.slice(0,tu-ru.length).join("")}${ru}`}var ho=class{constructor(e,n){this.actionTokens=e;this.isGitHubCliAvailable=n}actionTokens;isGitHubCliAvailable;createActionToken(e,n,r={}){return this.actionTokens.createActionToken(e,n,{expiresAt:Date.now()+10080*60*1e3,...r})}consumeActionToken(e){return this.actionTokens.consumeActionToken(e)}getActionToken(e){return this.actionTokens.getActionToken(e)}listActiveActionTokens(e){return this.actionTokens.listActiveActionTokens(e)}clearRepoPolicyChoiceTokens(e){this.actionTokens.deleteActionTokensForSessionByKind(e,"repo-policy-set")}clearPlanDecisionTokens(e,n){this.actionTokens.deletePlanDecisionTokensForSession(e,n)}makeActionButton(e,n,r,o={}){let i=this.createActionToken(e,n,{label:r,...o});return{label:r,callbackData:i.id,style:this.resolveButtonStyle(n)}}resolveButtonStyle(e){switch(e){case"plan-approve":case"worktree-create-pr":case"worktree-update-pr":case"plan-offer-start":case"repo-policy-set":return"primary";case"worktree-merge":case"session-resume":case"session-restart":return"success";case"plan-reject":case"worktree-dismiss":return"danger";default:return"secondary"}}getWorktreeDecisionButtons(e,n,r={merge:!0,pr:!0}){if(!n)return[];let o=[],i=[];if(r.merge&&i.push(this.makeActionButton(e,"worktree-merge","Merge")),r.pr&&this.isGitHubCliAvailable())n.worktreePrUrl?(i.push(this.makeActionButton(e,"worktree-view-pr","View PR",{targetUrl:n.worktreePrUrl})),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-update-pr","Sync PR"),this.makeActionButton(e,"worktree-decide-later","Later")])):(i.push(this.makeActionButton(e,"worktree-create-pr","Open PR")),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-decide-later","Later"),this.makeActionButton(e,"worktree-dismiss","Discard")]));else return o.push([...i,this.makeActionButton(e,"worktree-decide-later","Later")]),o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o;return n.worktreePrUrl&&o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o}getPlanApprovalButtons(e,n){let r=n?.actionablePlanDecisionVersion??n?.planDecisionVersion;this.clearPlanDecisionTokens(e,r);let o=[[this.makeActionButton(e,"plan-approve","Approve",{planDecisionVersion:r}),this.makeActionButton(e,"plan-request-changes","Revise",{planDecisionVersion:r}),this.makeActionButton(e,"plan-reject","Reject",{planDecisionVersion:r})]];return B("plan_approval_buttons_created",{sessionId:e,planDecisionVersion:r,...z(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,l)=>{let a=this.createActionToken(e,"question-answer",{label:s.label,optionIndex:l,pendingInputRequestId:r.requestId,pendingInputQuestionId:r.questionId});return{label:Uh(s.label),callbackData:a.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=nu)i.push(o.slice(s,s+nu));return i}getPlanOfferButtons(e){let{offerId:n,route:r,planName:o,planPrompt:i,planWorkdir:s,planWorktreeStrategy:l}=e,a=[[this.makeActionButton(n,"plan-offer-start","Start Plan",{route:r,launchName:o,launchPrompt:i,launchWorkdir:s,launchWorktreeStrategy:l}),this.makeActionButton(n,"plan-offer-dismiss","Dismiss",{route:r})]];return B("plan_offer_buttons_created",{offerId:n,planName:o,channel:r.provider,target:r.target,accountId:r.accountId,threadId:r.threadId,sessionKey:r.sessionKey,planPromptLength:i.length,planWorkdirLength:s.length,planWorktreeStrategy:l,...z(a)}),a}getRepoPolicyChoiceButtons(e){let n=cn(e.prAvailable??!0),r=Array.from({length:Math.ceil(n.length/2)},(o,i)=>n.slice(i*2,i*2+2)).map(o=>o.map(i=>this.makeActionButton(e.choiceId,"repo-policy-set",i.label,{route:e.route,repoPolicy:i.policy,repoPolicyWorkdir:e.repoRoot,launchName:e.launchName,launchPrompt:e.launchPrompt,launchWorkdir:e.launchWorkdir,launchModel:e.launchModel,launchReasoningEffort:e.launchReasoningEffort,launchFastMode:e.launchFastMode,launchSystemPrompt:e.launchSystemPrompt,launchAllowedTools:e.launchAllowedTools,launchResumeSessionId:e.launchResumeSessionId,launchResumeWorktreeFrom:e.launchResumeWorktreeFrom,launchSessionIdOverride:e.launchSessionIdOverride,launchClearedPersistedCodexResume:e.launchClearedPersistedCodexResume,launchForkSession:e.launchForkSession,launchForceNewSession:e.launchForceNewSession,launchPermissionMode:e.launchPermissionMode,launchPlanApproval:e.launchPlanApproval,launchHarness:e.launchHarness,launchWorktreeStrategy:e.launchWorktreeStrategy,launchWorktreeBaseBranch:e.launchWorktreeBaseBranch,launchWorktreePrTargetRepo:e.launchWorktreePrTargetRepo,launchOriginAgentId:e.launchOriginAgentId})));return B("repo_policy_choice_buttons_created",{choiceId:e.choiceId,repoRoot:e.repoRoot,channel:e.route.provider,target:e.route.target,accountId:e.route.accountId,threadId:e.route.threadId,sessionKey:e.route.sessionKey,labels:n.map(o=>o.label),...z(r)}),r}};Z();be();import{createHash as Hh}from"crypto";var Vh="duplicate notification already delivered or in flight",yo=class{maxRecords;inFlightTtlMs;now;inFlight=new Set;delivered=new Set;constructor(e={}){this.maxRecords=Math.max(1,Math.floor(e.maxRecords??64)),this.inFlightTtlMs=Math.max(1,Math.floor(e.inFlightTtlMs??6e5)),this.now=e.now??(()=>new Date)}claim(e,n,r){if(!e)return{allowed:!0};let o=this.now(),i=this.prune(n??[],o),s=i.find(l=>l.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:Vh}:(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))}};be();Z();be();import{createHash as Gh}from"crypto";var jh=1024,bn="duplicate completion follow-up wake already handled",ko="prior human-visible summary already delivered",So=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??jh))}decide(e,n,r){if(n?.required!==!0)return{required:!1,allowed:!1,explicit:!1};let o=this.buildKeySet(e,n);if(!o)return{required:!0,allowed:!0,explicit:!1};let i=this.normalizeRecords(r),s=new Map(i.map(u=>[u.key,u])),l=o.decisionKeys.find(u=>this.inFlight.has(u)||this.completed.has(u)||s.has(u)),a=l?this.completed.get(l):void 0,d=l?s.get(l):void 0;return l?{required:!0,allowed:!1,explicit:o.explicit,dedupeKey:o.primary,skipReason:a?.skipReason??d?.skipReason??bn}:(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),l=new Map(s.map(m=>[m.key,m])),a=i.decisionKeys.find(m=>this.completed.has(m)||l.has(m)),d=a?this.completed.get(a):void 0,u=a?l.get(a):void 0;if(d||u)return{required:!0,allowed:!1,explicit:i.explicit,dedupeKey:i.primary,skipReason:d?.skipReason??u?.skipReason};this.finishKeys(i.primary,i.claimKeys,!0,ko);let c=this.deliveredRecords(i.claimKeys,s,o,ko);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:c}}finish(e,n,r=bn){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=bn){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=bn){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===ko&&o!==ko||(this.completed.delete(i),this.completed.set(i,{skipReason:o}));for(;this.completed.size>this.maxCompletedKeys;){let i=this.completed.keys().next().value;if(i===void 0)break;this.completed.delete(i)}}}buildKeySet(e,n){let r=this.getDeliveryRef(e);if(!r)return;let o=this.normalizeOutcomeKey(e,n.outcomeKey?.trim());if(o){let l=`${this.buildVisibleScope(r,e)}:outcome:${this.digest(o)}`,a=this.isGoalLike(e,n,o),d=this.buildSessionAliasKeys(r,e,"visible-summary"),u=this.buildSessionAliasKeys(r,e,"goal-summary"),c=this.isTerminalLike(n,o);return{primary:l,explicit:!0,claimKeys:[l,...d,...a?u:[]],decisionKeys:[l,...a||c?d:[],...u]}}let i=n.fallbackFingerprint?.trim();if(!i)return;let s=`${r}:${n.producer}:${this.digest(i)}`;return{primary:s,explicit:!1,claimKeys:[s],decisionKeys:[s]}}isGoalLike(e,n,r){return!!e.goalTaskId?.trim()||n.producer==="goal"||/^goal:/i.test(r)}isTerminalLike(e,n){return e.producer==="terminal"||/^terminal:/i.test(n)}normalizeOutcomeKey(e,n){let r=e.goalTaskId?.trim();if(r)return`goal:${r}`;let o=this.normalizeWorktreePrOutcomeKey(n);return o||n}normalizeWorktreePrOutcomeKey(e){if(!e)return;let n=e.split(":");if(n[0]!=="worktree-pr"||n.length<5)return;let r=n[1]?.trim().toLowerCase();if(!r||!/^(?:draft-)?(?:opened|updated)$/.test(r))return;let o=n[2]?.trim()||"default-repo",i=n[3]?.trim();if(!i)return;let s=this.normalizePrIdentity(i),l=n[4]?.trim();if(!(!s||!l))return["worktree-pr",o.toLowerCase(),s,l].join(":")}normalizePrIdentity(e){let n=e.match(/#?(\d+)$/);if(n?.[1])return`#${n[1]}`;let r=e.match(/\/pull\/(\d+)(?:\b|\/|$)/);if(r?.[1])return`#${r[1]}`;let o=e.trim();return o||void 0}buildVisibleScope(e,n){let r=Me(n);return r?`route:${this.digest(JSON.stringify({provider:r.provider,accountId:r.accountId,target:r.target,threadId:r.threadId}))}`:e}buildSessionAliasKeys(e,n,r){let o=this.buildVisibleScope(e,n),i=["id"in n?n.id:void 0,"sessionId"in n?n.sessionId:void 0,n.name,$(n),n.harnessSessionId,e].map(s=>s?.trim()).filter(s=>!!s);return[...new Set(i)].map(s=>`${o}:session:${this.digest(s)}:${r}`)}getDeliveryRef(e){return K(e)??$(e)??""}digest(e){return Gh("sha256").update(e).digest("hex").slice(0,16)}normalizeRecords(e){return e?.length?e.filter(n=>n.key.trim()&&Number.isFinite(Date.parse(n.recordedAt))).slice(-this.maxCompletedKeys):[]}deliveredRecords(e,n,r,o=bn){let i=new Date().toISOString(),a=[...this.normalizeRecords(n).filter(d=>!e.includes(d.key)),...e.map(d=>({key:d,recordedAt:i,label:r,skipReason:o}))];return a.slice(Math.max(0,a.length-this.maxCompletedKeys))}};var zh=2e3,Qh=new Set(["1","true","yes","on"]);function Jh(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&Qh.has(t))||Bi()}function Yh(t){Jh()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
247
- `)}var vo=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new So({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new yo({maxRecords:r.maxNotificationDedupeRecords}),this.getPersistedSession=r.getPersistedSession}wakeDispatcher;applyPersistedPatch;completionSummaries;notificationDedupe;getPersistedSession;dispatch(e,n){let r=this.getDeliveryRef(e),o=this.getPersistedSession?.(r),i=this.buildNotificationDedupeKey(e,n),s=this.notificationDedupe.claim(i,o?.notificationDedupe,n.label);if(s.records&&this.applyNotificationDedupePatch(r,s.records),!s.allowed){this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:i,decision:"skip",reason:s.reason??"duplicate notification skipped",deliveryPath:"notify"}),n.hooks?.onDuplicateSkipped?.(s.reason??"duplicate notification skipped");return}let l=this.buildCompletionSummaryFact(n),a=n.completionSummaryOwner==="foreground"&&l?.required===!0,d=a?this.completionSummaries.recordVisibleDelivery(e,l,o?.completionSummaryDedupe,n.label):this.completionSummaries.decide(e,l,o?.completionSummaryDedupe);d.records&&this.applyCompletionSummaryDedupePatch(r,d.records);let u=a?this.withoutCompletionWake(n):n;if(d.required&&!d.allowed)if(this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:d.dedupeKey??d.key,outcomeKey:l?.outcomeKey,decision:a?"skip":d.explicit?"send_without_followup":"skip",reason:d.skipReason??"completion follow-up wake suppressed",deliveryPath:a?"foreground-summary":"wake",followupKind:l?.producer}),n.hooks?.onWakeSkipped?.(d.skipReason??"completion follow-up wake suppressed"),a){this.releaseNotificationDedupe(r,i);return}else if(d.explicit)u=this.withoutCompletionWake(n);else{this.releaseNotificationDedupe(r,i);return}l?.required===!0&&this.logNotificationDecision({session:e,request:u,deliveryRef:r,dedupeKey:d.dedupeKey??d.key,outcomeKey:l.outcomeKey,decision:a?"record_visible":u.completionWakeSummaryRequired===!0?"send_with_followup":"send_without_followup",reason:a?"foreground summary owns completion follow-up":void 0,deliveryPath:a?"foreground-summary":"wake",followupKind:l.producer});let c=this.buildCompletionWakePatch(u),m=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifySuccess?.trim()),p=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifyFailed?.trim()),f=!1,h=!1,k=()=>{h||(h=!0,f||(this.releaseNotificationDedupe(r,i),f=!0),this.completionSummaries.finish(d.key,!1))},v=u.shouldDispatch?()=>{let x=u.shouldDispatch?.()!==!1;return x||k(),x}:void 0,I={onNotifyStarted:()=>{this.applyDeliveryState(r,"notifying"),u.hooks?.onNotifyStarted?.()},onNotifySucceeded:()=>{f=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.applyNotifyDeliveryState(r,m?"wake_pending":"idle",m?c:void 0),m||this.completionSummaries.finish(d.key,!1),u.hooks?.onNotifySucceeded?.()},onNotifyFailed:()=>{this.applyNotifyDeliveryState(r,p?"wake_pending":"failed",p?c:void 0),p||(this.completionSummaries.finish(d.key,!1),this.releaseNotificationDedupe(r,i),f=!0),u.hooks?.onNotifyFailed?.()},onWakeStarted:()=>{this.applyPersistedPatchWithCompletionWake(r,"wake_pending",c,{completionWakeIssuedAt:new Date().toISOString(),completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),u.hooks?.onWakeStarted?.()},onWakeSucceeded:()=>{f=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,d.key,u.label),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(c),{completionWakeSucceededAt:new Date().toISOString(),completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),this.completionSummaries.finish(d.key,!0),u.hooks?.onWakeSucceeded?.()},onWakeSkipped:x=>{if(h){u.hooks?.onWakeSkipped?.(x);return}f=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,d.key,u.label,x),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(c),{completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:new Date().toISOString(),completionWakeSkipReason:x}),this.completionSummaries.finish(d.key,!0),u.hooks?.onWakeSkipped?.(x)},onWakeFailed:()=>{this.applyPersistedPatchWithCompletionWake(r,"failed",c,{completionWakeFailedAt:new Date().toISOString()}),this.completionSummaries.finish(d.key,!1),this.releaseNotificationDedupe(r,i),f=!0,u.hooks?.onWakeFailed?.()}};this.wakeDispatcher.dispatchSessionNotification(e,{...u,idempotencyKey:i??u.idempotencyKey,shouldDispatch:v,hooks:I})}notifyWorktreeOutcome(e,n,r={}){let o=this.getDeliveryRef(e),i=d=>Wt({sessionId:o,sessionName:e.name,outcomeLine:n,originThreadLine:Gt(e),detailLines:r.detailLines,canonicalStatusDelivered:d}),s=r.summaryWakeRequired??!0,l={required:s,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},a=r.completionSummaryOwner!=="foreground";if(s&&!a){let d=this.getDeliveryRef(e),u=this.completionSummaries.recordVisibleDelivery(e,l,d?this.getPersistedSession?.(d)?.completionSummaryDedupe:void 0,"worktree-outcome");u.records&&this.applyCompletionSummaryDedupePatch(d,u.records)}this.dispatch(e,{label:"worktree-outcome",userMessage:n,notifyUser:"always",requireDirectUserNotification:!0,completionSummary:{...l,required:s&&a},completionWakeSummaryRequired:s&&a,completionWakeOutcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`,idempotencyKey:`worktree-outcome:${r.completionWakeOutcomeKey??n}`,deferConditionalWakeUntilNextTick:!0,deferConditionalWakeMs:zh,wakeMessageOnNotifySuccess:s&&a?i(!0):void 0,wakeMessageOnNotifyFailed:s&&a?i(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return K(e)??$(e)??""}applyDeliveryState(e,n){!e||!n||this.applyPersistedPatch(e,{deliveryState:n})}applyNotifyDeliveryState(e,n,r){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r}:{deliveryState:n})}applyPersistedPatchWithCompletionWake(e,n,r,o){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r,...o}:{deliveryState:n})}buildCompletionWakePatch(e){if(e.completionWakeSummaryRequired===!0)return{completionWakeSummaryRequired:!0}}buildCompletionWakeSucceededPatch(e){if(e)return{completionWakeSummaryRequired:void 0}}withoutCompletionWake(e){return{...e,completionSummary:e.completionSummary?{...e.completionSummary,required:!1}:void 0,wakeMessage:void 0,wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:void 0,completionWakeSummaryRequired:!1}}buildCompletionSummaryFact(e){if(e.completionSummary)return e.completionSummary;if(e.completionWakeSummaryRequired!==!0)return;let n=[e.wakeMessage,e.wakeMessageOnNotifySuccess,e.wakeMessageOnNotifyFailed].map(r=>r?.trim()).filter(r=>!!r);return{required:!0,producer:"legacy",outcomeKey:e.completionWakeOutcomeKey,fallbackFingerprint:n.length>0?`${e.label}
244
+ `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i,{},[[this.deps.makeOpenPrButton(e.id)]])})}async handleAutoMergeStrategy(e,n,r,o,i,s,l=K(e)??e.harnessSessionId,a={merge:!0,pr:!0}){this.deps.isAlreadyMerged(l)||e.autoMergeResolverSessionId||await this.deps.enqueueMerge(n,async()=>{if(this.deps.isAlreadyMerged(l))return;let d=this.deps.mergeBranch(n,o,i,"merge",r);if(d.success){this.handleAutoMergeSuccess(e,n,o,i,s,d);return}if(d.rebaseConflict){await this.handleInitialAutoMergeConflict(e,n,r,o,i,a,d.error,d);return}let u=Ce(d.dirtyError?`❌ [${e.name}] Merge blocked: ${d.error}`:`❌ [${e.name}] Merge failed: ${d.error??"unknown error"}`,d);if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,o,r,u,a);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${o}`,userMessage:u})},()=>{this.deps.dispatchSessionNotification(e,{label:"worktree-merge-queued",idempotencyKey:`worktree-merge-queued:${e.id}:${o}`,userMessage:`🕐 [${e.name}] Merge queued — another merge for this repo is in progress. Will notify when complete.`})})}async handleAutoPrStrategy(e,n,r,o,i,s={merge:!0,pr:!0}){if(this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_in_progress"}),!(await this.deps.runAutoPr(e,i)).success){let a=Pt(n);if(!!(a&&a!==o&&wt(n,o,a)&&Xe(r).length===0)){let u=le(e)?!0:ce(n,r);return u&&(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0})),Se(n,o),this.markReleased(e,[`released_by_branch:${a}`]),{notificationSent:!1,worktreeRemoved:u}}this.markPendingDecision(e),this.deps.dispatchSessionNotification(e,{label:"worktree-auto-pr-failed",idempotencyKey:`worktree-auto-pr-failed:${e.id}:${i}`,userMessage:`⚠️ [${e.name}] Auto-PR did not complete. The worktree is preserved for an explicit merge or PR decision.`,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,s)})}return{notificationSent:!0,worktreeRemoved:!1}}};import{existsSync as Ph,statSync as wh,writeFileSync as bh}from"fs";be();import{randomUUID as Fg}from"crypto";function qg(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var to=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:Fg(),sessionId:e,kind:n,createdAt:Date.now(),...r};return this.tokens.set(o.id,o),this.notifyChanged(),o}getActionToken(e){let n=this.tokens.get(e);if(n){if(n.expiresAt!=null&&n.expiresAt<=Date.now()){this.tokens.delete(e),this.notifyChanged();return}return n}}listActiveActionTokens(e){let n=[];for(let r of[...this.tokens.keys()]){let o=this.getActionToken(r);!o||o.consumedAt!=null||e&&o.kind!==e||n.push(o)}return n}consumeActionToken(e){let n=this.getActionToken(e);if(!(!n||n.consumedAt!=null))return n.consumedAt=Date.now(),this.notifyChanged(),n}deleteActionTokensForSession(e){let n=!1;for(let[r,o]of this.tokens)o.sessionId===e&&(this.tokens.delete(r),n=!0);n&&this.notifyChanged()}deleteActionTokensForSessionByKind(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId===e&&i.kind===n&&(this.tokens.delete(o),r=!0);r&&this.notifyChanged()}deletePlanDecisionTokensForSession(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId!==e||!qg(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?.()}};Z();Z();var no=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 l of this.indexes.persisted.values()){if(l.name!==e){s++;continue}let a=l.createdAt??Number.NEGATIVE_INFINITY,d=l.completedAt??Number.NEGATIVE_INFINITY;(a>r||a===r&&d>o||a===r&&d===o&&s>i)&&(n=l,r=a,o=d,i=s),s++}return n}resolveBackendConversationId(e,n){if(n)return n;let r=this.indexes.idIndex.get(e);if(r){let s=this.indexes.persisted.get(r);return(s?$(s):void 0)??r}let o=this.getLatestPersistedByName(e);if(o)return $(o)??o.harnessSessionId;let i=this.indexes.backendIdIndex.get(e);if(i){let s=this.indexes.persisted.get(i);return(s?$(s):void 0)??i}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?$(s)??e:e}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e))return e}resolveHarnessSessionId(e,n){return this.resolveBackendConversationId(e,n)}getPersistedSession(e){let n=this.indexes.idIndex.get(e);if(n)return this.indexes.persisted.get(n);let r=this.getLatestPersistedByName(e);if(r)return r;let o=this.indexes.backendIdIndex.get(e);return o?this.indexes.persisted.get(o):this.indexes.persisted.get(e)}listPersistedSessions(){return[...this.indexes.persisted.values()].sort((e,n)=>(n.completedAt??0)-(e.completedAt??0))}};import{existsSync as Ld,mkdirSync as mh,readFileSync as fh,readdirSync as gh,renameSync as Bd,statSync as Fd,unlinkSync as qd,writeFileSync as Kd}from"fs";import{tmpdir as hh}from"os";import{dirname as yh,join as Ud}from"path";import{homedir as Kg}from"node:os";import{join as Ug}from"node:path";function Cd(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||Kg();return Ug(n,".openclaw")}be();var ro=7,Vg=new Set(["running","completed","failed","killed"]);function Ge(t){return!!t&&typeof t=="object"}function Nt(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 Md(t){return typeof t=="string"&&al.has(t)?t:void 0}function ds(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function Gg(t){return t==="never"||t==="on-request"?"never":void 0}function _d(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function jg(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function $d(t){return typeof t=="string"&&vr.has(t)?t:void 0}function us(t){return typeof t=="string"&&sl.has(t)?t:void 0}function Ed(t){return t==="github"||t==="unsupported"?t:void 0}function Hg(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function zg(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function Qg(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 Jg(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function Yg(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 Zg(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 Xg(t){return t==="live"||t==="stopped"?t:void 0}function eh(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function th(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function nh(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function rh(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function oh(t){return t==="in_flight"||t==="delivered"?t:void 0}function ih(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ge(n))return;let r=P(n.key),o=oh(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 sh(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ge(n))return;let r=P(n.key),o=P(n.recordedAt);if(!(!r||!o||!Number.isFinite(Date.parse(o))))return{key:r,recordedAt:o,label:P(n.label),skipReason:P(n.skipReason)}}).filter(n=>!!n);return e.length>0?e.slice(-1024):void 0}function ah(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 lh(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 Dd(t){if(!Ge(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 dh(t,e,n){if(Ge(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 uh(t){if(!Ge(t))return;let e=Zg(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 ch(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 ph(t){if(typeof t=="string"&&Vg.has(t))return t==="running"?"killed":t}function Od(t){if(!Ge(t))return;let e=Nt(t.harnessSessionId);if(!e)return;let n=ph(t.status);if(!n)return;let r=t.status==="running",o=P(t.worktreePath),i=P(t.worktreeBranch),s=P(t.originChannel),l=typeof t.originThreadId=="string"||typeof t.originThreadId=="number"?t.originThreadId:void 0,a=P(t.originSessionKey),d=Dd(t.route);if(!d)return;let u=He({route:d,originChannel:s,originThreadId:l,originSessionKey:a});if(!u||o&&!i)return;let c=P(t.harness),m=dh(t.backendRef,c,e),p=uh(t.worktreeLifecycle)??ch(t),f=P(t.completionWakeSucceededAt),h=P(t.completionWakeSkippedAt),k=t.completionWakeSummaryRequired===!0&&!h?!0:void 0;return{sessionId:P(t.sessionId),harnessSessionId:e,backendRef:m,name:Nt(t.name,e),prompt:Nt(t.prompt),workdir:Nt(t.workdir,"(unknown)"),model:P(t.model),reasoningEffort:Md(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:pe(t.createdAt),completedAt:pe(t.completedAt),status:n,lifecycle:r?"suspended":Qg(t.lifecycle),approvalState:Jg(t.approvalState),worktreeState:Yg(t.worktreeState),runtimeState:r?"stopped":Xg(t.runtimeState),deliveryState:rh(t.deliveryState),notificationDedupe:ih(t.notificationDedupe),completionSummaryDedupe:sh(t.completionSummaryDedupe),completionWakeIssuedAt:P(t.completionWakeIssuedAt),completionWakeSucceededAt:f,completionWakeFailedAt:P(t.completionWakeFailedAt),completionWakeSkippedAt:h,completionWakeSkipReason:P(t.completionWakeSkipReason),completionWakeSummaryRequired:k,killReason:zg(t.killReason),costUsd:typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)?t.costUsd:0,originAgentId:P(t.originAgentId),originChannel:s,originThreadId:l,originSessionKey:a,route:u,outputPath:P(t.outputPath),harness:c,goalTaskId:P(t.goalTaskId),requestedPermissionMode:ds(t.requestedPermissionMode),currentPermissionMode:ds(t.currentPermissionMode),approvalExecutionState:ah(t.approvalExecutionState),approvalRationale:P(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:jg(t.planApprovalContext),planDecisionVersion:pe(t.planDecisionVersion),actionablePlanDecisionVersion:pe(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:pe(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:pe(t.approvalPromptRequiredVersion),approvalPromptVersion:pe(t.approvalPromptVersion),approvalPromptStatus:eh(t.approvalPromptStatus),approvalPromptTransport:th(t.approvalPromptTransport),approvalPromptMessageKind:nh(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:P(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:P(t.approvalPromptDeliveredAt),approvalPromptFailedAt:P(t.approvalPromptFailedAt),planApproval:_d(t.planApproval),codexApprovalPolicy:Gg(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:$d(t.worktreeStrategy),repoIntegrationPolicy:us(t.repoIntegrationPolicy),repoIntegrationPolicySource:Hg(t.repoIntegrationPolicySource),repoProvider:Ed(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),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,worktreeDismissedAt:P(t.worktreeDismissedAt),worktreeLifecycle:p,resumable:r?!0:t.resumable===!0}}function Wd(t){if(!Ge(t))return;let e=P(t.key),n=P(t.repoRoot),r=us(t.policy),o=Ed(t.provider)??"unsupported",i=P(t.createdAt),s=P(t.updatedAt),l=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:l}}function Nd(t){if(!Ge(t))return;let e=lh(t.kind),n=Nt(t.id),r=Nt(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:Dd(t.route),launchName:P(t.launchName),launchPrompt:P(t.launchPrompt),launchWorkdir:P(t.launchWorkdir),launchModel:P(t.launchModel),launchReasoningEffort:Md(t.launchReasoningEffort),launchFastMode:t.launchFastMode===!0?!0:void 0,launchSystemPrompt:P(t.launchSystemPrompt),launchAllowedTools:Array.isArray(t.launchAllowedTools)?t.launchAllowedTools.filter(i=>typeof i=="string"):void 0,launchResumeSessionId:P(t.launchResumeSessionId),launchResumeWorktreeFrom:P(t.launchResumeWorktreeFrom),launchSessionIdOverride:P(t.launchSessionIdOverride),launchClearedPersistedCodexResume:t.launchClearedPersistedCodexResume===!0?!0:void 0,launchForkSession:typeof t.launchForkSession=="boolean"?t.launchForkSession:void 0,launchForceNewSession:typeof t.launchForceNewSession=="boolean"?t.launchForceNewSession:void 0,launchPermissionMode:ds(t.launchPermissionMode),launchPlanApproval:_d(t.launchPlanApproval),launchHarness:P(t.launchHarness),launchWorktreeStrategy:$d(t.launchWorktreeStrategy),launchWorktreeBaseBranch:P(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:P(t.launchWorktreePrTargetRepo),launchOriginAgentId:P(t.launchOriginAgentId),repoPolicy:us(t.repoPolicy),repoPolicyWorkdir:P(t.repoPolicyWorkdir)}}function oo(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 cs(t){return!!t&&typeof t=="object"}function ps(t){return t instanceof Error?t.message:String(t)}function Vd(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(!Ld(s))return s}}function ms(){let t=hh();return gh(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>Ud(t,e))}function Gd(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||Ud(Cd(t),"code-agent-sessions.json")}function jd(t,e,n,r=[]){try{mh(yh(t),{recursive:!0});let o=t+".tmp";Kd(o,JSON.stringify({schemaVersion:ro,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),Bd(o,t)}catch(o){`${ps(o)}`}}function kh(t,e){try{if(!Ld(t))return!1;let n=Vd(t,"legacy");return n?(Bd(t,n),`${e}${n}`,!0):!1}catch(n){return`${ps(n)}`,!1}}var Sh={archiveLegacySessionIndex:kh};function vh(t,e){try{if(e.length===0)return;let n=Vd(t,"codex-sdk-legacy");if(!n)return;Kd(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${ps(n)}`}}function Hd(t,e,n=[]){try{let r=new Set(n);for(let o of ms())if(!r.has(o))try{let i=Fd(o).mtimeMs;t-i>e&&qd(o)}catch{}}catch{}}function zd(t,e,n=[]){try{let r=new Set(n),o;for(let i of ms())if(!r.has(i))try{let s=Fd(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function Qd(t){try{let e=new Set(t);for(let n of ms())if(!e.has(n))try{qd(n)}catch{}}catch{}}function Jd(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:l}=t,a=d=>Sh.archiveLegacySessionIndex(e,d)?(n(),!0):!1;try{let d=fh(e,"utf-8"),u=JSON.parse(d);if(Array.isArray(u)){if(!a("legacy array store"))return;l();return}if(!cs(u)||u.schemaVersion!==ro&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!a(`schema mismatch (expected v${ro})`))return;l();return}let c=(w,A)=>{if(!Object.prototype.hasOwnProperty.call(u,w))return[];let y=u[w];if(Array.isArray(y))return y;a(A)&&l()},m=c("sessions","invalid sessions collection");if(m===void 0)return;let p=[],f=[];for(let w of m){if(cs(w)&&w.harness==="codex"){let y=cs(w.backendRef)?w.backendRef:void 0;if((typeof y?.kind=="string"?y.kind:void 0)!=="codex-app-server"){p.push(w);continue}}let A=Od(w);if(!A){if(!a("invalid v4 session entry"))return;l();return}f.push(A)}p.length>0&&vh(e,p);let h=c("actionTokens","invalid action token collection");if(h===void 0)return;let k=[];for(let w of h){let A=Nd(w);if(!A){if(!a("invalid v4 action token"))return;l();return}k.push(A)}let v=c("repoPolicies","invalid repo policy collection");if(v===void 0)return;let I=[],x=!1;for(let w of v){let A=Wd(w);if(!A){x=!0;continue}I.push(A)}for(let w of f)r(w);for(let w of k)o(w);for(let w of I)i(w);p.length>0&&l(),x&&l(),s()}catch(d){if(d.code==="ENOENT"||!a("corrupt or unreadable"))return;l()}}var Rh=new Set(["completed","failed","killed"]),fs=1440*60*1e3;function Ah(t){return t instanceof Error?t.message:String(t)}var Ih={statSync:wh};function xh(t){try{return Ih.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var io=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??Gd(n),this.actionTokenStore=new to(()=>this.saveIndex(),fs),this.actionTokens=this.actionTokenStore.tokens,this.queries=new no({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Jd({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(){jd(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){oo(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=si(e),r=n==="codex"?"codex-app-server":n==="opencode"?"opencode-server":"claude-code";return e.backendRef??{kind:e.backendKind??r,conversationId:e.harnessSessionId}}getSessionApprovalSnapshot(e){if(typeof e.approvalSnapshot=="function")return e.approvalSnapshot();let n=typeof e.controlStateSnapshot=="function"?e.controlStateSnapshot():{planModeApproved:!1};return{requestedPermissionMode:e.requestedPermissionMode,currentPermissionMode:e.currentPermissionMode,approvalExecutionState:e.approvalExecutionState,approvalRationale:e.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy}}getSessionRoutingSnapshot(e){return typeof e.routingSnapshot=="function"?e.routingSnapshot():{route:e.route,originAgentId:e.originAgentId,originChannel:e.originChannel,originThreadId:e.originThreadId,originSessionKey:e.originSessionKey}}getSessionWorktreeSnapshot(e){return typeof e.worktreeSnapshot=="function"?e.worktreeSnapshot():{worktreePath:e.worktreePath,worktreeBranch:e.worktreeBranch,worktreeStrategy:e.worktreeStrategy,repoIntegrationPolicy:e.repoIntegrationPolicy,repoIntegrationPolicySource:e.repoIntegrationPolicySource,repoProvider:e.repoProvider,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,autoMergeParentSessionId:e.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:e.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:e.autoMergeResolverSessionId,worktreeLifecycle:e.worktreeLifecycle}}indexPersistedEntry(e){let n=this.getEntryStorageKey(e);this.persisted.set(n,e),e.sessionId&&this.idIndex.set(e.sessionId,n),e.name&&this.nameIndex.set(e.name,n);let r=$(e);r&&this.backendIdIndex.set(r,n)}removePersistedIndexes(e){let n=this.getEntryStorageKey(e);this.persisted.delete(n);for(let[r,o]of this.idIndex)o===n&&this.idIndex.delete(r);for(let[r,o]of this.nameIndex)o===n&&this.nameIndex.delete(r);for(let[r,o]of this.backendIdIndex)o===n&&this.backendIdIndex.delete(r)}markRunning(e){if(!e.harnessSessionId)return;let n=this.getSessionApprovalSnapshot(e),r=this.getSessionRoutingSnapshot(e),o=this.getSessionWorktreeSnapshot(e),i=He({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,status:"running",lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),costUsd:0,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:Ze(e.id),harness:e.harnessName,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalRationale:n.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planApproval:n.planApproval,codexApprovalPolicy:n.codexApprovalPolicy,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,repoIntegrationPolicy:o.repoIntegrationPolicy,repoIntegrationPolicySource:o.repoIntegrationPolicySource,repoProvider:o.repoProvider,worktreeBaseBranch:o.worktreeBaseBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};oo(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=He({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let a=Ze(e.id);if(Ph(a))s=a;else{let d=e.getOutput().join(`
245
+ `);d.length>0&&(bh(a,d,"utf-8"),s=a)}}catch(a){`${e.id}${Ah(a)}`}let l={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,completedAt:e.completedAt,status:e.status,lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),killReason:e.killReason,costUsd:e.costUsd,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:s,harness:e.harnessName,goalTaskId:e.goalTaskId,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalRationale:n.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planApproval:n.planApproval,codexApprovalPolicy:n.codexApprovalPolicy,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,worktreeBaseBranch:o.worktreeBaseBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};oo(l),this.indexPersistedEntry(l),this.saveIndex()}getExistingNotificationDedupe(e){return this.getPersistedSession(e.id)?.notificationDedupe??(e.harnessSessionId?this.getPersistedSession(e.harnessSessionId)?.notificationDedupe:void 0)??($(e)?this.getPersistedSession($(e))?.notificationDedupe:void 0)}getLatestPersistedByName(e){return this.queries.getLatestPersistedByName(e)}resolveBackendConversationId(e,n){return this.queries.resolveBackendConversationId(e,n)}resolveHarnessSessionId(e,n){return this.queries.resolveHarnessSessionId(e,n)}getPersistedSession(e){return this.queries.getPersistedSession(e)}listPersistedSessions(){return this.queries.listPersistedSessions()}getRepoPolicy(e){return this.repoPolicies.get(e)}listRepoPolicies(){return[...this.repoPolicies.values()].sort((e,n)=>e.repoRoot.localeCompare(n.repoRoot)||e.key.localeCompare(n.key))}setRepoPolicy(e){let n=this.repoPolicies.get(e.key),r={...e,createdAt:n?.createdAt??e.createdAt,updatedAt:new Date().toISOString(),source:"stored"};return this.repoPolicies.set(r.key,r),this.saveIndex(),r}updateRepoPolicy(e,n){let r=this.repoPolicies.get(e);if(r)return this.setRepoPolicy({...r,policy:n})}resetRepoPolicy(e){let n=this.repoPolicies.delete(e);return n&&this.saveIndex(),n}removeRepoPolicies(e){let n=[];for(let r of e){let o=this.repoPolicies.get(r);o&&(this.repoPolicies.delete(r),n.push(o))}return n.length>0&&this.saveIndex(),n.sort((r,o)=>r.repoRoot.localeCompare(o.repoRoot)||r.key.localeCompare(o.key))}cleanupRepoPolicies(){let e=[];for(let[n,r]of this.repoPolicies)xh(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),Hd(e,fs,this.getReferencedOutputPaths())}getNextTmpOutputCleanupAt(e){return zd(e,fs,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||!Rh.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(){Qd(this.getReferencedOutputPaths())}};var Th=new Set(["completed","failed","killed"]),so=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),Th.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:se(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 Xd from"child_process";var Yd=5e3,eu=64,Ch={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},Mh={execFile:Xd.execFile},je=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},lo=class{constructor(e=Mh.execFile){this.execFile=e}execFile;async send(e,n,r){B("direct_send_started",{...we(e),messageTextLength:n.length,...z(r)});try{await this.sendViaRuntime(e,n,r),B("direct_send_succeeded",{...we(e),deliveryPath:"runtime",...z(r)});return}catch(o){if(!(o instanceof je))throw B("direct_send_failed",{...we(e),deliveryPath:"runtime",...z(r),error:gs(o)}),o;B("direct_send_runtime_capability_missing",{...we(e),deliveryPath:"runtime",...z(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),B("direct_send_succeeded",{...we(e),deliveryPath:"cli-fallback",...z(r)})}}async sendViaRuntime(e,n,r){let o=St(),i=ya(),s=o?.channel?.outbound?.loadAdapter;if(!o)throw new je("OpenClaw plugin runtime is unavailable for direct notification delivery");if(i==null)throw new je("OpenClaw runtime config snapshot is unavailable for direct notification delivery");if(!o.channel)throw new je(`OpenClaw plugin runtime channel surface is unavailable for direct notification delivery (runtimeVersion=${hs(o)})`);if(!o.channel.outbound)throw new je(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${hs(o)})`);if(!s)throw new je(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${hs(o)})`);let l=await s(e.channel);if(!l)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let a=co(r);if(B("runtime_adapter_loaded",{...we(e),adapterHasRenderPresentation:typeof l.renderPresentation=="function",adapterHasSendPayload:typeof l.sendPayload=="function",adapterHasSendText:typeof l.sendText=="function",...z(r),...a?qi(a):{}}),a){await this.sendPresentation(l,i,e,n,a);return}if(!l.sendText)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" cannot send text`);await l.sendText({cfg:i,to:e.target,text:n,accountId:e.accountId,threadId:e.threadId})}async sendPresentation(e,n,r,o,i){let s=$h(i),l={text:o,presentation:i,interactive:s};B("presentation_render_started",{...we(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...qi(i)});let a={cfg:n,to:r.target,text:o,payload:l,accountId:r.accountId,threadId:r.threadId},d=e.renderPresentation?await e.renderPresentation({payload:l,presentation:i,ctx:a}):l,u=Dh(d,s,r.channel);if(B("presentation_render_completed",{...we(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Ki(u)}),!u||typeof u!="object"||!e.sendPayload)throw new Error(`OpenClaw outbound adapter for channel "${r.channel}" cannot preserve interactive presentation`);let c=await e.sendPayload({...a,payload:u});B("presentation_send_payload_completed",{...we(r),...Ki(u),...Dl(c)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let l=_h(e,n,r);B("direct_send_cli_fallback_started",{...we(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...z(r)}),this.execFile("openclaw",l,{timeout:Yd,killSignal:"SIGKILL"},(a,d,u)=>{if(!a){B("direct_send_cli_fallback_completed",{...we(e),deliveryPath:"cli-fallback",...z(r)}),i();return}let c=u?.trim()?` | stderr: ${u.trim()}`:"";B("direct_send_cli_fallback_failed",{...we(e),deliveryPath:"cli-fallback",...z(r),error:gs(a),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${Yd}ms timeout: ${gs(a)}${c}`))})})}};function we(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function _h(t,e,n){let r=co(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 gs(t){return t instanceof Error?t.message:String(t)}function hs(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function co(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:Fh(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function $h(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 Eh(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 Dh(t,e,n){if(!e)return t;let r=Eh(t)?t:Oh(t,e);return n!=="telegram"?r:Wh(r,e)}function Oh(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function Wh(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Lt(n.channelData),o=Lt(r?.telegram),i=Lh(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=Nh(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function Nh(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")<=eu).map(r=>({text:r.label,callback_data:r.value,...tu(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function Lh(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")>eu))&&Bh(i))return{...i,...tu(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function Bh(t){return uo(t.callback_data)||uo(t.url)||ao(t.web_app)||ao(t.webApp)||ao(t.login_url)||ao(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||Lt(t.switch_inline_query_chosen_chat)!==void 0||Lt(t.callback_game)!==void 0||t.pay===!0||Zd(t.copy_text)||Zd(t.copyText)}function uo(t){return typeof t=="string"&&t.trim().length>0}function ao(t){let e=Lt(t);return uo(e?.url)}function Zd(t){let e=Lt(t);return uo(e?.text)}function tu(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=Ch[e];return n?{style:n}:{}}function Lt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Fh(t){return t.startsWith(`${ye}:`)?t:`${ye}:${t}`}import*as nu from"child_process";var Bt=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()),l=s.catch(()=>{});return this.tails.set(e,l),l.finally(()=>{this.tails.get(e)===l&&this.tails.delete(e)}),s}clear(){this.tails.clear()}};var ys=3e4,qh=2e3,Kh=2e4,me=4;function wn(t){return t instanceof Error?t.message:String(t)}function Uh(){return new Error(`Dispatch timed out after ${ys}ms`)}function Vh(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var Gh={execFile:nu.execFile},po=class{pendingRetryTimers=new Map;orderedDispatches=new Bt;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:me}),Gh.execFile("openclaw",e,{timeout:ys,killSignal:"SIGKILL"},(s,l,a)=>{if(this.disposed){r?.();return}let d=Date.now()-i;if(!s){let f=n.successValidator?.(l??"");if(f?.outcome==="failure"){this.log("error","dispatch_success_validation_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:me,elapsedMs:d,error:f.reason,terminal:!0}),n.onFinalFailure?.(),r?.();return}if(f?.outcome==="skipped"){this.log("info","dispatch_skipped",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:me,elapsedMs:d,reason:f.reason}),n.shouldContinue?.()!==!1&&n.onSkipped?.(f.reason),r?.();return}this.log("info","dispatch_succeeded",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:me,elapsedMs:d}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.();return}let u=a?.trim()?` | stderr: ${a.trim()}`:"";if(n.shouldContinue?.()===!1){r?.();return}if(n.target==="message.send"&&Vh(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:me,elapsedMs:d,error:`${wn(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(o>=me||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:me,elapsedMs:d,error:`${wn(s)}${u}`,terminal:!0}),n.onFinalFailure?.(),r?.();return}let m=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:me,elapsedMs:d,retryDelayMs:m,error:`${wn(s)}${u}`});let p={timer:setTimeout(()=>{let f=this.pendingRetryTimers.get(n.sessionId);if(f&&(f.delete(p),f.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executeNow(e,n,r,o+1)},m),onCleared:r};p.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(p)})}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:me}),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:me,elapsedMs:s}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.()}).catch(s=>{if(this.disposed){r?.();return}let l=Date.now()-i;if(n.shouldContinue?.()===!1){r?.();return}if(o>=me||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:me,elapsedMs:l,error:wn(s),terminal:!0,...n.terminalOnFailure===!0&&o<me?{terminalReason:"non_retryable"}:{}}),n.onFinalFailure?.(),r?.();return}let a=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:me,elapsedMs:l,retryDelayMs:a,error:wn(s)});let d={timer:setTimeout(()=>{let u=this.pendingRetryTimers.get(n.sessionId);if(u&&(u.delete(d),u.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executePromiseNow(e,n,r,o+1)},a),onCleared:r};d.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(d)})}executePromiseWithTimeout(e){return new Promise((n,r)=>{let o=!1,i=setTimeout(()=>{o||(o=!0,r(Uh()))},ys);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=qh*2**n;return Math.min(r,Kh)}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}}};be();var mo=class{resolve(e){let n=Me(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 jh}from"crypto";var fo=class{constructor(e={}){}buildChatSendArgs(e,n,r,o=jh()){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=co(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 Hh(t){let e=zh(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 zh(t){let e=t.trim();if(!e)return"";try{return ks(JSON.parse(e)).trim()}catch{return e}}function ks(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>ks(r)).filter(Boolean).join(`
246
+ `);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=ks(e[r]);if(o.trim())return o}return""}var go=class{routes=new mo;transport;directNotifications;executor=new po;constructor(e={}){this.transport=e.transport??new fo(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new lo: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,l,a,d,u){let c=this.routes.resolve(e),m=l;if(m?.()===!1)return;let p=c?.sessionKey?.trim();if(!p){this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-system`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:d,onFinalFailure:i,successValidator:a,shouldContinue:m});return}this.executor.execute(this.transport.buildChatSendArgs(p,n,!0,u),{label:r,sessionId:e.id,target:"chat.send",phase:o,routeSummary:`session:${p}`,messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:`session:${p}`,route:c,text:n}),onSuccess:s,onSkipped:d,successValidator:a,shouldContinue:m,onFinalFailure:()=>{m?.()!==!1&&this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-fallback`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:d,onFinalFailure:i,successValidator:a,shouldContinue:m})}})}sendUserNotification(e,n,r,o,i,s,l=!1,a){if(a?.()===!1)return;let d=!!o?.some(f=>Array.isArray(f)&&f.length>0),u=this.routes.resolve(e);B("wake_notify_selected",{sessionId:e.id,sessionName:e.name,label:r,messageTextLength:n.length,requireDirectDelivery:l,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,...z(o)});let c=u?`notify:${u.channel}|${u.accountId??""}|${u.target}|${u.threadId??""}`:`notify:system:${e.id}`;if(!u){if(B("wake_notify_no_direct_route",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:l,hasInteractiveButtons:d,...z(o)}),l){`${r}${e.id}`,i?.();return}if(d){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-system`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n,buttons:o}),orderingKey:c,onSuccess:s,onFinalFailure:i,shouldContinue:a});return}let m=()=>{if(B("wake_notify_direct_failed",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:l,hasInteractiveButtons:d,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...z(o)}),l){`${r}${e.id}`,i?.();return}if(d){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-fallback`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),orderingKey:c,onSuccess:s,onFinalFailure:i,shouldContinue:a})},p={label:`${r}-notify`,sessionId:e.id,target:"message.send",phase:"notify",routeSummary:this.routes.summary(u),messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:this.routes.summary(u),route:u,text:n,buttons:o}),orderingKey:c,onSuccess:s,onAmbiguousResult:m,onFinalFailure:m,terminalOnFailure:this.directNotifications?!0:void 0,shouldContinue:a};if(this.directNotifications){B("wake_notify_dispatching_direct_runtime",{sessionId:e.id,sessionName:e.name,label:r,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...z(o)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,o),p);return}B("wake_notify_dispatching_cli_message_send",{sessionId:e.id,sessionName:e.name,label:r,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...z(o)}),this.executor.execute(this.transport.buildDirectNotificationArgs(u,n,o),p)}sendUserNotificationSequence(e,n,r,o,i,s=!1,l){let a=n.map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0);if(a.length===0){o?.();return}B("wake_notify_sequence_started",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:a.length,buttonChunkIndexes:a.map((u,c)=>u.buttons?.some(m=>Array.isArray(m)&&m.length>0)?c+1:void 0).filter(u=>typeof u=="number"),requireDirectDelivery:s});let d=u=>{if(l?.()===!1)return;let c=a[u];if(!c){B("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:a.length}),i?.();return}let m=u===0?o:i;B("wake_notify_sequence_chunk_selected",{sessionId:e.id,sessionName:e.name,label:r,chunkIndex:u+1,chunkCount:a.length,messageTextLength:c.text.length,failureHandler:u===0?"all-failed":"sequence-success",...z(c.buttons)}),this.sendUserNotification(e,c.text,`${r}-part-${u+1}`,c.buttons,m,()=>d(u+1),s,l)};d(0)}dispatchSessionNotification(e,n){let r=n.hooks,o=n.wakeMessageOnNotifySuccess!=null||n.wakeMessageOnNotifyFailed!=null,i=n.notifyUser??(n.wakeMessage?"on-wake-fallback":"always"),s=(n.userMessages?.length?n.userMessages:n.userMessage?.trim()?[{text:n.userMessage.trim(),buttons:n.buttons}]:[]).map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0),l=n.wakeMessage?.trim(),a=n.shouldDispatch,d=n.completionWakeSummaryRequired===!0?Hh:void 0;if(o){let u=n.wakeMessageOnNotifySuccess?.trim(),c=n.wakeMessageOnNotifyFailed?.trim(),m=k=>{k&&a?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,k,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,a,d,r?.onWakeSkipped,n.idempotencyKey))},p=k=>{if(k){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let v=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>m(k),v).unref?.();return}m(k)}},f=()=>{a?.()!==!1&&(r?.onNotifySucceeded?.(),u&&p(u))},h=c?()=>{a?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),p(c))}:()=>{a?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(a?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,h,f,n.requireDirectUserNotification===!0,a)}else h();return}if(i==="always"&&s.length>0){if(a?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{a?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{a?.()!==!1&&r?.onNotifySucceeded?.()},n.requireDirectUserNotification===!0,a)}if(l&&a?.()!==!1){if(r?.onWakeStarted?.(),i==="on-wake-fallback"&&s.length>0&&!this.routes.resolve(e)?.sessionKey){if(a?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{a?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{a?.()!==!1&&r?.onNotifySucceeded?.()},!1,a)}this.sendWake(e,l,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,a,d,r?.onWakeSkipped,n.idempotencyKey)}}};var ru=36,ou=2,iu="...";function Qh(t){let e=Array.from(t);return e.length<=ru?t:`${e.slice(0,ru-iu.length).join("")}${iu}`}var ho=class{constructor(e,n){this.actionTokens=e;this.isGitHubCliAvailable=n}actionTokens;isGitHubCliAvailable;createActionToken(e,n,r={}){return this.actionTokens.createActionToken(e,n,{expiresAt:Date.now()+10080*60*1e3,...r})}consumeActionToken(e){return this.actionTokens.consumeActionToken(e)}getActionToken(e){return this.actionTokens.getActionToken(e)}listActiveActionTokens(e){return this.actionTokens.listActiveActionTokens(e)}clearRepoPolicyChoiceTokens(e){this.actionTokens.deleteActionTokensForSessionByKind(e,"repo-policy-set")}clearPlanDecisionTokens(e,n){this.actionTokens.deletePlanDecisionTokensForSession(e,n)}makeActionButton(e,n,r,o={}){let i=this.createActionToken(e,n,{label:r,...o});return{label:r,callbackData:i.id,style:this.resolveButtonStyle(n)}}resolveButtonStyle(e){switch(e){case"plan-approve":case"worktree-create-pr":case"worktree-update-pr":case"plan-offer-start":case"repo-policy-set":return"primary";case"worktree-merge":case"session-resume":case"session-restart":return"success";case"plan-reject":case"worktree-dismiss":return"danger";default:return"secondary"}}getWorktreeDecisionButtons(e,n,r={merge:!0,pr:!0}){if(!n)return[];let o=[],i=[];if(r.merge&&i.push(this.makeActionButton(e,"worktree-merge","Merge")),r.pr&&this.isGitHubCliAvailable())n.worktreePrUrl?(i.push(this.makeActionButton(e,"worktree-view-pr","View PR",{targetUrl:n.worktreePrUrl})),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-update-pr","Sync PR"),this.makeActionButton(e,"worktree-decide-later","Later")])):(i.push(this.makeActionButton(e,"worktree-create-pr","Open PR")),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-decide-later","Later"),this.makeActionButton(e,"worktree-dismiss","Discard")]));else return o.push([...i,this.makeActionButton(e,"worktree-decide-later","Later")]),o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o;return n.worktreePrUrl&&o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o}getPlanApprovalButtons(e,n){let r=n?.actionablePlanDecisionVersion??n?.planDecisionVersion;this.clearPlanDecisionTokens(e,r);let o=[[this.makeActionButton(e,"plan-approve","Approve",{planDecisionVersion:r}),this.makeActionButton(e,"plan-request-changes","Revise",{planDecisionVersion:r}),this.makeActionButton(e,"plan-reject","Reject",{planDecisionVersion:r})]];return B("plan_approval_buttons_created",{sessionId:e,planDecisionVersion:r,...z(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,l)=>{let a=this.createActionToken(e,"question-answer",{label:s.label,optionIndex:l,pendingInputRequestId:r.requestId,pendingInputQuestionId:r.questionId});return{label:Qh(s.label),callbackData:a.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=ou)i.push(o.slice(s,s+ou));return i}getPlanOfferButtons(e){let{offerId:n,route:r,planName:o,planPrompt:i,planWorkdir:s,planWorktreeStrategy:l}=e,a=[[this.makeActionButton(n,"plan-offer-start","Start Plan",{route:r,launchName:o,launchPrompt:i,launchWorkdir:s,launchWorktreeStrategy:l}),this.makeActionButton(n,"plan-offer-dismiss","Dismiss",{route:r})]];return B("plan_offer_buttons_created",{offerId:n,planName:o,channel:r.provider,target:r.target,accountId:r.accountId,threadId:r.threadId,sessionKey:r.sessionKey,planPromptLength:i.length,planWorkdirLength:s.length,planWorktreeStrategy:l,...z(a)}),a}getRepoPolicyChoiceButtons(e){let n=cn(e.prAvailable??!0),r=Array.from({length:Math.ceil(n.length/2)},(o,i)=>n.slice(i*2,i*2+2)).map(o=>o.map(i=>this.makeActionButton(e.choiceId,"repo-policy-set",i.label,{route:e.route,repoPolicy:i.policy,repoPolicyWorkdir:e.repoRoot,launchName:e.launchName,launchPrompt:e.launchPrompt,launchWorkdir:e.launchWorkdir,launchModel:e.launchModel,launchReasoningEffort:e.launchReasoningEffort,launchFastMode:e.launchFastMode,launchSystemPrompt:e.launchSystemPrompt,launchAllowedTools:e.launchAllowedTools,launchResumeSessionId:e.launchResumeSessionId,launchResumeWorktreeFrom:e.launchResumeWorktreeFrom,launchSessionIdOverride:e.launchSessionIdOverride,launchClearedPersistedCodexResume:e.launchClearedPersistedCodexResume,launchForkSession:e.launchForkSession,launchForceNewSession:e.launchForceNewSession,launchPermissionMode:e.launchPermissionMode,launchPlanApproval:e.launchPlanApproval,launchHarness:e.launchHarness,launchWorktreeStrategy:e.launchWorktreeStrategy,launchWorktreeBaseBranch:e.launchWorktreeBaseBranch,launchWorktreePrTargetRepo:e.launchWorktreePrTargetRepo,launchOriginAgentId:e.launchOriginAgentId})));return B("repo_policy_choice_buttons_created",{choiceId:e.choiceId,repoRoot:e.repoRoot,channel:e.route.provider,target:e.route.target,accountId:e.route.accountId,threadId:e.route.threadId,sessionKey:e.route.sessionKey,labels:n.map(o=>o.label),...z(r)}),r}};Z();be();import{createHash as Xh}from"crypto";var Jh="duplicate notification already delivered or in flight",yo=class{maxRecords;inFlightTtlMs;now;inFlight=new Set;delivered=new Set;constructor(e={}){this.maxRecords=Math.max(1,Math.floor(e.maxRecords??64)),this.inFlightTtlMs=Math.max(1,Math.floor(e.inFlightTtlMs??6e5)),this.now=e.now??(()=>new Date)}claim(e,n,r){if(!e)return{allowed:!0};let o=this.now(),i=this.prune(n??[],o),s=i.find(l=>l.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:Jh}:(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))}};be();Z();be();import{createHash as Yh}from"crypto";var Zh=1024,bn="duplicate completion follow-up wake already handled",ko="prior human-visible summary already delivered",So=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??Zh))}decide(e,n,r){if(n?.required!==!0)return{required:!1,allowed:!1,explicit:!1};let o=this.buildKeySet(e,n);if(!o)return{required:!0,allowed:!0,explicit:!1};let i=this.normalizeRecords(r),s=new Map(i.map(u=>[u.key,u])),l=o.decisionKeys.find(u=>this.inFlight.has(u)||this.completed.has(u)||s.has(u)),a=l?this.completed.get(l):void 0,d=l?s.get(l):void 0;return l?{required:!0,allowed:!1,explicit:o.explicit,dedupeKey:o.primary,skipReason:a?.skipReason??d?.skipReason??bn}:(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),l=new Map(s.map(m=>[m.key,m])),a=i.decisionKeys.find(m=>this.completed.has(m)||l.has(m)),d=a?this.completed.get(a):void 0,u=a?l.get(a):void 0;if(d||u)return{required:!0,allowed:!1,explicit:i.explicit,dedupeKey:i.primary,skipReason:d?.skipReason??u?.skipReason};this.finishKeys(i.primary,i.claimKeys,!0,ko);let c=this.deliveredRecords(i.claimKeys,s,o,ko);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:c}}finish(e,n,r=bn){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=bn){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=bn){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===ko&&o!==ko||(this.completed.delete(i),this.completed.set(i,{skipReason:o}));for(;this.completed.size>this.maxCompletedKeys;){let i=this.completed.keys().next().value;if(i===void 0)break;this.completed.delete(i)}}}buildKeySet(e,n){let r=this.getDeliveryRef(e);if(!r)return;let o=this.normalizeOutcomeKey(e,n.outcomeKey?.trim());if(o){let l=`${this.buildVisibleScope(r,e)}:outcome:${this.digest(o)}`,a=this.isGoalLike(e,n,o),d=this.buildSessionAliasKeys(r,e,"visible-summary"),u=this.buildSessionAliasKeys(r,e,"goal-summary"),c=this.isTerminalLike(n,o);return{primary:l,explicit:!0,claimKeys:[l,...d,...a?u:[]],decisionKeys:[l,...a||c?d:[],...u]}}let i=n.fallbackFingerprint?.trim();if(!i)return;let s=`${r}:${n.producer}:${this.digest(i)}`;return{primary:s,explicit:!1,claimKeys:[s],decisionKeys:[s]}}isGoalLike(e,n,r){return!!e.goalTaskId?.trim()||n.producer==="goal"||/^goal:/i.test(r)}isTerminalLike(e,n){return e.producer==="terminal"||/^terminal:/i.test(n)}normalizeOutcomeKey(e,n){let r=e.goalTaskId?.trim();if(r)return`goal:${r}`;let o=this.normalizeWorktreePrOutcomeKey(n);return o||n}normalizeWorktreePrOutcomeKey(e){if(!e)return;let n=e.split(":");if(n[0]!=="worktree-pr"||n.length<5)return;let r=n[1]?.trim().toLowerCase();if(!r||!/^(?:draft-)?(?:opened|updated)$/.test(r))return;let o=n[2]?.trim()||"default-repo",i=n[3]?.trim();if(!i)return;let s=this.normalizePrIdentity(i),l=n[4]?.trim();if(!(!s||!l))return["worktree-pr",o.toLowerCase(),s,l].join(":")}normalizePrIdentity(e){let n=e.match(/#?(\d+)$/);if(n?.[1])return`#${n[1]}`;let r=e.match(/\/pull\/(\d+)(?:\b|\/|$)/);if(r?.[1])return`#${r[1]}`;let o=e.trim();return o||void 0}buildVisibleScope(e,n){let r=Me(n);return r?`route:${this.digest(JSON.stringify({provider:r.provider,accountId:r.accountId,target:r.target,threadId:r.threadId}))}`:e}buildSessionAliasKeys(e,n,r){let o=this.buildVisibleScope(e,n),i=["id"in n?n.id:void 0,"sessionId"in n?n.sessionId:void 0,n.name,$(n),n.harnessSessionId,e].map(s=>s?.trim()).filter(s=>!!s);return[...new Set(i)].map(s=>`${o}:session:${this.digest(s)}:${r}`)}getDeliveryRef(e){return K(e)??$(e)??""}digest(e){return Yh("sha256").update(e).digest("hex").slice(0,16)}normalizeRecords(e){return e?.length?e.filter(n=>n.key.trim()&&Number.isFinite(Date.parse(n.recordedAt))).slice(-this.maxCompletedKeys):[]}deliveredRecords(e,n,r,o=bn){let i=new Date().toISOString(),a=[...this.normalizeRecords(n).filter(d=>!e.includes(d.key)),...e.map(d=>({key:d,recordedAt:i,label:r,skipReason:o}))];return a.slice(Math.max(0,a.length-this.maxCompletedKeys))}};var ey=2e3,ty=new Set(["1","true","yes","on"]);function ny(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&ty.has(t))||Fi()}function ry(t){ny()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
247
+ `)}var vo=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new So({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new yo({maxRecords:r.maxNotificationDedupeRecords}),this.getPersistedSession=r.getPersistedSession}wakeDispatcher;applyPersistedPatch;completionSummaries;notificationDedupe;getPersistedSession;dispatch(e,n){let r=this.getDeliveryRef(e),o=this.getPersistedSession?.(r),i=this.buildNotificationDedupeKey(e,n),s=this.notificationDedupe.claim(i,o?.notificationDedupe,n.label);if(s.records&&this.applyNotificationDedupePatch(r,s.records),!s.allowed){this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:i,decision:"skip",reason:s.reason??"duplicate notification skipped",deliveryPath:"notify"}),n.hooks?.onDuplicateSkipped?.(s.reason??"duplicate notification skipped");return}let l=this.buildCompletionSummaryFact(n),a=n.completionSummaryOwner==="foreground"&&l?.required===!0,d=a?this.completionSummaries.recordVisibleDelivery(e,l,o?.completionSummaryDedupe,n.label):this.completionSummaries.decide(e,l,o?.completionSummaryDedupe);d.records&&this.applyCompletionSummaryDedupePatch(r,d.records);let u=a?this.withoutCompletionWake(n):n;if(d.required&&!d.allowed)if(this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:d.dedupeKey??d.key,outcomeKey:l?.outcomeKey,decision:a?"skip":d.explicit?"send_without_followup":"skip",reason:d.skipReason??"completion follow-up wake suppressed",deliveryPath:a?"foreground-summary":"wake",followupKind:l?.producer}),n.hooks?.onWakeSkipped?.(d.skipReason??"completion follow-up wake suppressed"),a){this.releaseNotificationDedupe(r,i);return}else if(d.explicit)u=this.withoutCompletionWake(n);else{this.releaseNotificationDedupe(r,i);return}l?.required===!0&&this.logNotificationDecision({session:e,request:u,deliveryRef:r,dedupeKey:d.dedupeKey??d.key,outcomeKey:l.outcomeKey,decision:a?"record_visible":u.completionWakeSummaryRequired===!0?"send_with_followup":"send_without_followup",reason:a?"foreground summary owns completion follow-up":void 0,deliveryPath:a?"foreground-summary":"wake",followupKind:l.producer});let c=this.buildCompletionWakePatch(u),m=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifySuccess?.trim()),p=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifyFailed?.trim()),f=!1,h=!1,k=()=>{h||(h=!0,f||(this.releaseNotificationDedupe(r,i),f=!0),this.completionSummaries.finish(d.key,!1))},v=u.shouldDispatch?()=>{let x=u.shouldDispatch?.()!==!1;return x||k(),x}:void 0,I={onNotifyStarted:()=>{this.applyDeliveryState(r,"notifying"),u.hooks?.onNotifyStarted?.()},onNotifySucceeded:()=>{f=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.applyNotifyDeliveryState(r,m?"wake_pending":"idle",m?c:void 0),m||this.completionSummaries.finish(d.key,!1),u.hooks?.onNotifySucceeded?.()},onNotifyFailed:()=>{this.applyNotifyDeliveryState(r,p?"wake_pending":"failed",p?c:void 0),p||(this.completionSummaries.finish(d.key,!1),this.releaseNotificationDedupe(r,i),f=!0),u.hooks?.onNotifyFailed?.()},onWakeStarted:()=>{this.applyPersistedPatchWithCompletionWake(r,"wake_pending",c,{completionWakeIssuedAt:new Date().toISOString(),completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),u.hooks?.onWakeStarted?.()},onWakeSucceeded:()=>{f=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,d.key,u.label),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(c),{completionWakeSucceededAt:new Date().toISOString(),completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),this.completionSummaries.finish(d.key,!0),u.hooks?.onWakeSucceeded?.()},onWakeSkipped:x=>{if(h){u.hooks?.onWakeSkipped?.(x);return}f=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,d.key,u.label,x),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(c),{completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:new Date().toISOString(),completionWakeSkipReason:x}),this.completionSummaries.finish(d.key,!0),u.hooks?.onWakeSkipped?.(x)},onWakeFailed:()=>{this.applyPersistedPatchWithCompletionWake(r,"failed",c,{completionWakeFailedAt:new Date().toISOString()}),this.completionSummaries.finish(d.key,!1),this.releaseNotificationDedupe(r,i),f=!0,u.hooks?.onWakeFailed?.()}};this.wakeDispatcher.dispatchSessionNotification(e,{...u,idempotencyKey:i??u.idempotencyKey,shouldDispatch:v,hooks:I})}notifyWorktreeOutcome(e,n,r={}){let o=this.getDeliveryRef(e),i=d=>Wt({sessionId:o,sessionName:e.name,outcomeLine:n,originThreadLine:Gt(e),detailLines:r.detailLines,canonicalStatusDelivered:d}),s=r.summaryWakeRequired??!0,l={required:s,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},a=r.completionSummaryOwner!=="foreground";if(s&&!a){let d=this.getDeliveryRef(e),u=this.completionSummaries.recordVisibleDelivery(e,l,d?this.getPersistedSession?.(d)?.completionSummaryDedupe:void 0,"worktree-outcome");u.records&&this.applyCompletionSummaryDedupePatch(d,u.records)}this.dispatch(e,{label:"worktree-outcome",userMessage:n,notifyUser:"always",requireDirectUserNotification:!0,completionSummary:{...l,required:s&&a},completionWakeSummaryRequired:s&&a,completionWakeOutcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`,idempotencyKey:`worktree-outcome:${r.completionWakeOutcomeKey??n}`,deferConditionalWakeUntilNextTick:!0,deferConditionalWakeMs:ey,wakeMessageOnNotifySuccess:s&&a?i(!0):void 0,wakeMessageOnNotifyFailed:s&&a?i(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return K(e)??$(e)??""}applyDeliveryState(e,n){!e||!n||this.applyPersistedPatch(e,{deliveryState:n})}applyNotifyDeliveryState(e,n,r){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r}:{deliveryState:n})}applyPersistedPatchWithCompletionWake(e,n,r,o){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r,...o}:{deliveryState:n})}buildCompletionWakePatch(e){if(e.completionWakeSummaryRequired===!0)return{completionWakeSummaryRequired:!0}}buildCompletionWakeSucceededPatch(e){if(e)return{completionWakeSummaryRequired:void 0}}withoutCompletionWake(e){return{...e,completionSummary:e.completionSummary?{...e.completionSummary,required:!1}:void 0,wakeMessage:void 0,wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:void 0,completionWakeSummaryRequired:!1}}buildCompletionSummaryFact(e){if(e.completionSummary)return e.completionSummary;if(e.completionWakeSummaryRequired!==!0)return;let n=[e.wakeMessage,e.wakeMessageOnNotifySuccess,e.wakeMessageOnNotifyFailed].map(r=>r?.trim()).filter(r=>!!r);return{required:!0,producer:"legacy",outcomeKey:e.completionWakeOutcomeKey,fallbackFingerprint:n.length>0?`${e.label}
248
248
  ${n.join(`
249
249
  ---completion-wake---
250
- `)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=Me(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=Me(e.session);Yh({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 Hh("sha256").update(e).digest("hex").slice(0,16)}};he();import{existsSync as Zh}from"fs";var Po=class{getCompletionState(e,n,r,o){let i=an(e,r,o);if(i===void 0)return"has-commits";if(i===0){let s=an(e,o,r);return s===void 0?"has-commits":s>0?wt(e,r,o)?"merged":"base-advanced":At(n)?"dirty-uncommitted":"no-change"}return"has-commits"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!Zh(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 Xh}from"node:crypto";function ey(t){let e=t.pendingInputState,n=e?.activeQuestionIndex??0;return e?.questions?.[n]?.id??(e?.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:void 0)}var wo=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],l=s.options??[],a=`❓ [${e.name}] ${s.question}`,d=ey(e),u=e.pendingInputState?.requestId??`legacy:${Xh()}`,c=this.getQuestionButtons(e.id,l,{requestId:u,questionId:d}),m=[`[ASK USER QUESTION] Session "${e.name}" has a question requiring user input.`,"",`Question: ${s.question}`,...l.length>0?["Options:",...l.map((p,f)=>` ${f+1}. ${p.label}`)]:[],"",`Send the question to the user and call agent_respond(session="${e.id}", message="<answer>") with their answer.`].join(`
250
+ `)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=Me(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=Me(e.session);ry({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 Xh("sha256").update(e).digest("hex").slice(0,16)}};he();import{existsSync as oy}from"fs";var Po=class{getCompletionState(e,n,r,o){let i=an(e,r,o);if(i===void 0)return"has-commits";if(i===0){let s=an(e,o,r);return s===void 0?"has-commits":s>0?wt(e,r,o)?"merged":"base-advanced":At(n)?"dirty-uncommitted":"no-change"}return"has-commits"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!oy(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 iy}from"node:crypto";function sy(t){let e=t.pendingInputState,n=e?.activeQuestionIndex??0;return e?.questions?.[n]?.id??(e?.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:void 0)}var wo=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],l=s.options??[],a=`❓ [${e.name}] ${s.question}`,d=sy(e),u=e.pendingInputState?.requestId??`legacy:${iy()}`,c=this.getQuestionButtons(e.id,l,{requestId:u,questionId:d}),m=[`[ASK USER QUESTION] Session "${e.name}" has a question requiring user input.`,"",`Question: ${s.question}`,...l.length>0?["Options:",...l.map((p,f)=>` ${f+1}. ${p.label}`)]:[],"",`Send the question to the user and call agent_respond(session="${e.id}", message="<answer>") with their answer.`].join(`
251
251
  `);return new Promise((p,f)=>{let h=this.pendingQuestions.get(e.id);h&&(clearTimeout(h.timeoutHandle),h.reject(new Error(`AskUserQuestion superseded by a newer question for session "${e.name}".`)));let k=setTimeout(()=>{this.pendingQuestions.delete(e.id),f(new Error(`AskUserQuestion timed out after ${6e5/1e3}s for session "${e.name}"`))},6e5);k.unref?.(),this.pendingQuestions.set(e.id,{resolve:p,reject:f,questions:i,timeoutHandle:k,requestId:u,questionId:d}),this.dispatchSessionNotification(e,{label:"ask-user-question",idempotencyKey:`ask-user-question:${e.id}:${u}`,userMessage:a,notifyUser:"always",buttons:c,wakeMessageOnNotifySuccess:["AskUserQuestion delivered to the user.",`Session: ${e.name} | ID: ${e.id}`,`Question: ${s.question}`,"Await their selection — do NOT answer this question yourself."].join(`
252
- `),wakeMessageOnNotifyFailed:m})})}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??[],l=s[n];return l?(clearTimeout(o.timeoutHandle),this.pendingQuestions.delete(e),this.clearWaitingTimestamp(e),o.resolve({behavior:"allow",updatedInput:{questions:o.questions,answers:{[i.question]:l.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()}};Z();dn();var ty=new Set(["merged","released","dismissed","none","cleanup_failed"]),ny=new Set(["merged","released","dismissed","no_change","none","cleanup_failed"]),bo=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 ue(e))this.updatePersistedSession(s,{lastWorktreeReminderAt:new Date(n).toISOString()});return!0}sendReminderNotification(e,n){let r=this.buildRoutingProxy({id:e.sessionId??e.name??$(e)??e.harnessSessionId,sessionId:e.sessionId,harnessSessionId:e.harnessSessionId,backendRef:e.backendRef,route:e.route});if(e.worktreeStrategy==="delegate"){this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,wakeMessage:Zi(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(`
253
- `);this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,userMessage:o,notifyUser:"always",buttons:this.getWorktreeDecisionButtons(K(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 ue(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=Ke(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(s.derivedState)?"resolved":"pending"}isResolvedWorktreeDecision(e){if(this.hasResolvedWorktreeDecisionMarker(e))return!0;let n=Ke(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(n.derivedState)}hasResolvedWorktreeDecisionMarker(e){return!!(e.worktreeMerged||e.worktreePrUrl||e.lifecycle==="terminal"||e.worktreeState&&ty.has(e.worktreeState)||e.worktreeLifecycle?.state&&ny.has(e.worktreeLifecycle.state))}isResolvedDerivedWorktreeState(e){return e==="merged"||e==="released"||e==="cleanup_failed"}};he();Z();be();function Rn(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&ry(t.approvalPromptStatus)}function ry(t){return t==="delivered"||t==="fallback_delivered"}function An(t,e){return!t||e==null?!1:!!(t.pendingPlanApproval&&t.approvalState==="pending"&&t.lifecycle==="awaiting_plan_decision"&&(t.actionablePlanDecisionVersion??t.planDecisionVersion)===e)}function Ft(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(`
252
+ `),wakeMessageOnNotifyFailed:m})})}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??[],l=s[n];return l?(clearTimeout(o.timeoutHandle),this.pendingQuestions.delete(e),this.clearWaitingTimestamp(e),o.resolve({behavior:"allow",updatedInput:{questions:o.questions,answers:{[i.question]:l.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()}};Z();dn();var ay=new Set(["merged","released","dismissed","none","cleanup_failed"]),ly=new Set(["merged","released","dismissed","no_change","none","cleanup_failed"]),bo=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 ue(e))this.updatePersistedSession(s,{lastWorktreeReminderAt:new Date(n).toISOString()});return!0}sendReminderNotification(e,n){let r=this.buildRoutingProxy({id:e.sessionId??e.name??$(e)??e.harnessSessionId,sessionId:e.sessionId,harnessSessionId:e.harnessSessionId,backendRef:e.backendRef,route:e.route});if(e.worktreeStrategy==="delegate"){this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,wakeMessage:Xi(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(`
253
+ `);this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,userMessage:o,notifyUser:"always",buttons:this.getWorktreeDecisionButtons(K(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 ue(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=Ke(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(s.derivedState)?"resolved":"pending"}isResolvedWorktreeDecision(e){if(this.hasResolvedWorktreeDecisionMarker(e))return!0;let n=Ke(e,{activeSession:!1,includePrSync:!1});return this.isResolvedDerivedWorktreeState(n.derivedState)}hasResolvedWorktreeDecisionMarker(e){return!!(e.worktreeMerged||e.worktreePrUrl||e.lifecycle==="terminal"||e.worktreeState&&ay.has(e.worktreeState)||e.worktreeLifecycle?.state&&ly.has(e.worktreeLifecycle.state))}isResolvedDerivedWorktreeState(e){return e==="merged"||e==="released"||e==="cleanup_failed"}};he();Z();be();function Rn(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&dy(t.approvalPromptStatus)}function dy(t){return t==="delivered"||t==="fallback_delivered"}function An(t,e){return!t||e==null?!1:!!(t.pendingPlanApproval&&t.approvalState==="pending"&&t.lifecycle==="awaiting_plan_decision"&&(t.actionablePlanDecisionVersion??t.planDecisionVersion)===e)}function Ft(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(`
254
254
  `)}function Ro(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(`
255
- `)}import{existsSync as my,readFileSync as fy}from"fs";var oy=4e3,ou=180,iy=300;function iu(){let t=St(),e=ly(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=dy(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 su(t){let e=Ao(t.question??""),n=Ao(uy(e,t.context??""));if(!t.provider||!e||!n)return;let r={sessionName:t.sessionName,question:e,context:cy(n,oy)};try{let o=await py(t.provider.generateQuestionContextSummary(r),t.timeoutMs??iy);return sy(o)}catch(o){let i=o instanceof Error?o.message:String(o);i!=="question-context-summary timed out"&&`${i}`;return}}function sy(t){let e=ay(t),n=typeof e=="string"?e:e&&typeof e=="object"&&typeof e.summary=="string"?e.summary:void 0,r=Ao(n??"").replace(/^[-*•]\s+/,"").trim();if(!(!r||r.length>ou)&&!(r.split(/[.!?]+/).filter(o=>o.trim()).length>1))return r}function ay(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return e}}function ly(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 dy(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 ${ou} characters.`,"Do not answer the question. Do not invent choices. Do not alter option labels or semantics.","","Evidence:",JSON.stringify(t,null,2)].join(`
256
- `)}function uy(t,e){return t?e.split(/\r?\n/).filter(n=>Ao(n)!==t).join(`
257
- `):e}function Ao(t){return t.replace(/\s+/g," ").trim()}function cy(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function py(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 gy=280;function hy(t,e){if(t.latestPlanArtifactVersion===e&&t.latestPlanArtifact)return t.latestPlanArtifact;let n=t.planFilePath?.trim();if(!(!n||!my(n)))try{let r=fy(n,"utf-8").trim();return r?{markdown:r,steps:[]}:void 0}catch{return}}function yy(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(`
258
- `)}function ky(t){return t.options.map(e=>({label:e.label,description:e.description?.trim()??""})).filter(e=>e.description&&e.description.length<=gy)}function au(t){let e=t?.activeQuestionIndex??0;return t?.questions?.[e]?.id??(t?.activeQuestionIndex!=null?`q${t.activeQuestionIndex}`:void 0)}function Sy(t,e,n){let r=t.pendingInputState;return!!(r&&r.requestId===e&&au(r)===n)}var Io=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:Pn({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>An(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:Ft(e,n,!0),wakeMessageOnNotifyFailed:Ro({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:!!Me(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 l=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath),a=e.worktreeBranch,d=le(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(l&&!d&&(u=ce(l,e.worktreePath)),l&&a&&!d&&u&&Se(l,a),u){for(let c of ue(e))this.deps.updatePersistedSession(c,{worktreePath:void 0,worktreeBranch:void 0});r=!0}}let o=e.worktreeStrategy&&e.worktreeStrategy!=="off"&&e.worktreeStrategy!=="manual";if(!r&&e.worktreePath&&e.originalWorkdir){let l=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath),a=le(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:l&&!a&&ce(l,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 l=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,se(l,200),r);return}let i=`$${(e.costUsd??0).toFixed(2)}`,s=e.duration;if(e.killReason==="idle-timeout"){let l=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0;if(e.pendingPlanApproval){let a=e.actionablePlanDecisionVersion??e.planDecisionVersion,d=Rn(e,a);if(l==="delegate"){this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${a??"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(`
255
+ `)}import{existsSync as Sy,readFileSync as vy}from"fs";var uy=4e3,su=180,cy=300;function au(){let t=St(),e=fy(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=gy(n);if(typeof e.generateObject=="function")return await e.generateObject({task:"openclaw-code-agent.question-context-summary",prompt:r,input:n});if(typeof e.generateText=="function")return await e.generateText({task:"openclaw-code-agent.question-context-summary",prompt:r});if(typeof e.complete=="function")return await e.complete({prompt:r})}}}async function lu(t){let e=Ao(t.question??""),n=Ao(hy(e,t.context??""));if(!t.provider||!e||!n)return;let r={sessionName:t.sessionName,question:e,context:yy(n,uy)};try{let o=await ky(t.provider.generateQuestionContextSummary(r),t.timeoutMs??cy);return py(o)}catch(o){let i=o instanceof Error?o.message:String(o);i!=="question-context-summary timed out"&&`${i}`;return}}function py(t){let e=my(t),n=typeof e=="string"?e:e&&typeof e=="object"&&typeof e.summary=="string"?e.summary:void 0,r=Ao(n??"").replace(/^[-*•]\s+/,"").trim();if(!(!r||r.length>su)&&!(r.split(/[.!?]+/).filter(o=>o.trim()).length>1))return r}function my(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return e}}function fy(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 gy(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 ${su} characters.`,"Do not answer the question. Do not invent choices. Do not alter option labels or semantics.","","Evidence:",JSON.stringify(t,null,2)].join(`
256
+ `)}function hy(t,e){return t?e.split(/\r?\n/).filter(n=>Ao(n)!==t).join(`
257
+ `):e}function Ao(t){return t.replace(/\s+/g," ").trim()}function yy(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function ky(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 Py=280;function wy(t,e){if(t.latestPlanArtifactVersion===e&&t.latestPlanArtifact)return t.latestPlanArtifact;let n=t.planFilePath?.trim();if(!(!n||!Sy(n)))try{let r=vy(n,"utf-8").trim();return r?{markdown:r,steps:[]}:void 0}catch{return}}function by(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(`
258
+ `)}function Ry(t){return t.options.map(e=>({label:e.label,description:e.description?.trim()??""})).filter(e=>e.description&&e.description.length<=Py)}function du(t){let e=t?.activeQuestionIndex??0;return t?.questions?.[e]?.id??(t?.activeQuestionIndex!=null?`q${t.activeQuestionIndex}`:void 0)}function Ay(t,e,n){let r=t.pendingInputState;return!!(r&&r.requestId===e&&du(r)===n)}var Io=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:Pn({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>An(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:Ft(e,n,!0),wakeMessageOnNotifyFailed:Ro({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:!!Me(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 l=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath),a=e.worktreeBranch,d=le(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(l&&!d&&(u=ce(l,e.worktreePath)),l&&a&&!d&&u&&Se(l,a),u){for(let c of ue(e))this.deps.updatePersistedSession(c,{worktreePath:void 0,worktreeBranch:void 0});r=!0}}let o=e.worktreeStrategy&&e.worktreeStrategy!=="off"&&e.worktreeStrategy!=="manual";if(!r&&e.worktreePath&&e.originalWorkdir){let l=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath),a=le(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:l&&!a&&ce(l,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 l=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,se(l,200),r);return}let i=`$${(e.costUsd??0).toFixed(2)}`,s=e.duration;if(e.killReason==="idle-timeout"){let l=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0;if(e.pendingPlanApproval){let a=e.actionablePlanDecisionVersion??e.planDecisionVersion,d=Rn(e,a);if(l==="delegate"){this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${a??"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(`
259
259
  `),notifyUser:"never"}),this.deps.clearRetryTimersForSession(e.id);return}if(l==="ask"&&d){this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${a??"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${a??"?"}`,this.deps.originThreadLine(e),"Do NOT post another approval summary unless canonical delivery is known to be missing."].join(`
260
260
  `)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${a??"unknown"}:user-prompt`,userMessage:[`📋 [${e.name}] Plan v${a??"?"} still awaiting approval after idle timeout | ${i} | ${Re(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(`
261
- `),notifyUser:"always",buttons:l==="ask"&&!d?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:a}):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} | ${Re(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${Gi(e.killReason)} | ${i} | ${Re(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=au(e.pendingInputState),s=o?[o,i].filter(Boolean).join(":"):void 0,l=s?`pending-input:${s}`:void 0;if(!this.deps.debounceWaitingEvent(e.id,l))return;let a=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0,d=e.actionablePlanDecisionVersion??e.planDecisionVersion,u=e.pendingPlanApproval&&a==="ask"&&Rn(e,d),c=e.pendingInputState?.promptText?.trim()||void 0,m=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),p=!e.pendingPlanApproval&&c?c:!e.pendingPlanApproval&&m!==void 0?m:this.deps.getOutputPreview(e,e.pendingPlanApproval&&a!=="delegate"?Number.POSITIVE_INFINITY:void 0),f=e.pendingInputState?.options.map(b=>({label:b}))??[],h=!n||n.length===0?f:r&&r.options.length>0&&r.options.length<=6&&!r.options.some(b=>b.isOther)&&!r.multiSelect?r.options:n.length===1&&r&&r.options.length===0?f:[],k=e.pendingPlanApproval&&a==="ask"&&!u?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:d}):!e.pendingPlanApproval&&h.length?this.deps.getQuestionButtons(e.id,h,{requestId:e.pendingInputState?.requestId,questionId:r?.id}):void 0,v=hy(e,d),I=r?ky(r):[],x=r?yy({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:I}):c,w=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await su({sessionName:e.name,question:x??p,context:m,provider:this.deps.questionContextSummaryProvider}):void 0,A=os({session:e,preview:p,questionText:e.pendingPlanApproval?void 0:x,questionContextPreview:m,questionContextSummary:w,planArtifact:v,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:a,planApprovalButtons:k,questionButtons:e.pendingPlanApproval?void 0:k}),y=A.planReviewSummary??p;if(A.label==="plan-approval"&&a==="ask"&&u){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${d??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"never",buttons:A.buttons,wakeMessage:A.wakeMessage});return}if(A.label==="plan-approval"&&a==="ask"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${d??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"always",buttons:A.buttons,hooks:{onNotifyStarted:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.deps.updatePersistedSession(e.id,{canonicalPlanPromptVersion:d,approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>An(e,d),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,d,y),wakeMessageOnNotifySuccess:Ft(e,d)});return}if(A.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${d??"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?()=>Sy(e,o,i):void 0,wakeMessageOnNotifyFailed:A.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=Ji({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${e.result?.num_turns??0}`,userMessage:n.userMessage,wakeMessage:n.wakeMessage,notifyUser:"always",onUserNotifyFailed:()=>{`${e.id}`,this.deps.shouldEmitTerminalWake(e)&&this.emitCompleted(e)}})}emitCompleted(e){let n=this.deps.getOutputPreview(e),r=this.shouldRequestCompletionFollowup(e),o=Hi({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i;this.deps.dispatchSessionNotification(e,{label:"completed",idempotencyKey:`terminal-completed:${e.id}`,userMessage:o.userMessage,notifyUser:"always",completionSummary:{required:r,producer:"terminal",outcomeKey:`terminal:${e.id}`},completionWakeSummaryRequired:r,completionWakeOutcomeKey:`terminal:${e.id}`,requireDirectUserNotification:!0,wakeMessageOnNotifySuccess:r?o.wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:r?o.wakeMessageOnNotifyFailed:void 0,hooks:{onNotifySucceeded:()=>{i=!0,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_succeeded",canonicalStatusDelivered:i,followupSummaryRequired:r})},onNotifyFailed:()=>{i=!1,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_failed",canonicalStatusDelivered:i,followupSummaryRequired:r})},onWakeSucceeded:()=>{this.logCompletionWakeDiagnostic({session:e,event:"completion_wake_succeeded",canonicalStatusDelivered:i,followupSummaryRequired:r})}}})}emitFailed(e,n,r){let o=Qi({session:e,originThreadLine:this.deps.originThreadLine(e),errorSummary:n,preview:this.deps.getOutputPreview(e),worktreeAutoCleaned:r,failedButtons:this.deps.getResumeButtons(e.id,e)});this.deps.dispatchSessionNotification(e,{label:"failed",idempotencyKey:`terminal-failed:${e.id}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};Z();he();import{existsSync as vy}from"fs";var xo=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),l=r?.worktreeBranch??n?.worktreeBranch,a=r?.name??n?.name??e;if(!s)return`Error: No workdir found for session "${e}".`;let d=le(o);!d&&i&&vy(i)&&ce(s,i,{destructive:!0}),l&&Se(s,l);for(let c of ue(r??n))this.deps.updatePersistedSession(c,{worktreeDisposition:"dismissed",worktreeDismissedAt:new Date().toISOString(),pendingWorktreeDecisionSince:void 0,worktreeState:"dismissed",lifecycle:"terminal",worktreePath:void 0,worktreeBranch:void 0,worktreeLifecycle:{state:"dismissed",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"dismiss",baseBranch:n?.worktreeLifecycle?.baseBranch,targetRepo:n?.worktreePrTargetRepo,pushRemote:n?.worktreePushRemote}});let u=d?`🗑️ [${a}] Branch \`${l??"unknown"}\` dismissed. Native backend worktree released for backend cleanup.`:`🗑️ [${a}] Branch \`${l??"unknown"}\` dismissed and permanently deleted.`;return this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:K(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:${K(r??n??{id:e})??e}:${l??"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 a of ue(r))this.deps.updatePersistedSession(a,{worktreeDecisionSnoozedUntil:i,lastWorktreeReminderAt:new Date(o).toISOString()});let l=`⏭️ Reminder snoozed 24h for \`${r.worktreeBranch??"unknown"}\` (session: ${r.name})`;return n.notifyUser!==!1&&this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:K(r)??$(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${K(r)??$(r)??r.harnessSessionId}:${i}`,userMessage:l,notifyUser:"always"}),l}};var lu=new Set(["starting","running"]),To=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>lu.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>lu.has(o.status)).map(o=>o.name));if(!n.has(e))return e;let r=2;for(;n.has(`${e}-${r}`);)r+=1;return`${e}-${r}`}add(e){this.sessions.set(e.id,e)}remove(e){this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var Co=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(l=>{console.error(`[SessionRuntimeBootstrap] handleTerminal threw for session ${e.id}:`,l)}))}),e.on("lifecycleChange",(i,s)=>{r.taskLifecycle?.progress(e)}),e.on("turnEnd",(i,s)=>{this.deps.handleTurnEnd(e,s).catch(l=>{console.error(`[SessionRuntimeBootstrap] handleTurnEnd threw for session ${e.id}:`,l)})}),e.start(),o.notifyLaunch!==!1){let i=this.deps.formatLaunchWorkdirLabel(e),s=`🚀 [${e.name}] Launched | ${i} | ${rn({harness:e.harnessName,model:e.model})??"default"}`;this.deps.notifySession(e,s,"launch")}return e}};var Mo=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,preview:s,originThreadLine:l}=e,a=o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`;return{label:o?"worktree-no-changes":"worktree-no-changes-cleanup-failed",idempotencyKey:`worktree-no-change:${n.id}:${o?"cleaned":"cleanup-failed"}`,userMessage:o?r?`ℹ️ [${n.name}] Session completed with no changes — native backend worktree released for backend cleanup`:`ℹ️ [${n.name}] Session completed with no changes — worktree cleaned up`:`⚠️ [${n.name}] Session completed with no changes, but worktree cleanup failed. Worktree still exists at ${i}`,wakeMessage:Xi({sessionName:n.name,sessionId:n.id,cleanupSummary:a,preview:s,originThreadLine:l,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalState:n.approvalState,planApproval:n.planApproval,approvalPromptStatus:n.approvalPromptStatus,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt}),notifyUser:"always"}}buildAskNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,buttons:s,summaryLines:l=[],policyReason:a}=e,d=i.commitMessages.slice(0,5).map(m=>`• ${m.hash} ${m.message} (${m.author})`),u=i.commits>5?`...and ${i.commits-5} more`:"",c=n.worktreePrTargetRepo?`Branch: \`${r}\` → \`${o}\` | PR target: ${n.worktreePrTargetRepo}`:`Branch: \`${r}\` → \`${o}\``;return{label:"worktree-merge-ask",idempotencyKey:["worktree-decision",n.id,r,o,i.commits,i.commitMessages.map(m=>m.hash).join(",")].join(":"),userMessage:[`🔀 Worktree decision required for session \`${n.name}\``,"",c,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`,"",...l.length>0?["Summary:",...l.map(m=>`- ${m}`),""]:[],...a?[`Policy: ${a}`,""]:[],"Recent commits:",...d,...u?[u]:[],"",`⚠️ Discard will permanently delete branch \`${r}\` and all local changes. This cannot be undone.`].join(`
261
+ `),notifyUser:"always",buttons:l==="ask"&&!d?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:a}):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} | ${Re(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${ji(e.killReason)} | ${i} | ${Re(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=du(e.pendingInputState),s=o?[o,i].filter(Boolean).join(":"):void 0,l=s?`pending-input:${s}`:void 0;if(!this.deps.debounceWaitingEvent(e.id,l))return;let a=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0,d=e.actionablePlanDecisionVersion??e.planDecisionVersion,u=e.pendingPlanApproval&&a==="ask"&&Rn(e,d),c=e.pendingInputState?.promptText?.trim()||void 0,m=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),p=!e.pendingPlanApproval&&c?c:!e.pendingPlanApproval&&m!==void 0?m:this.deps.getOutputPreview(e,e.pendingPlanApproval&&a!=="delegate"?Number.POSITIVE_INFINITY:void 0),f=e.pendingInputState?.options.map(b=>({label:b}))??[],h=!n||n.length===0?f:r&&r.options.length>0&&r.options.length<=6&&!r.options.some(b=>b.isOther)&&!r.multiSelect?r.options:n.length===1&&r&&r.options.length===0?f:[],k=e.pendingPlanApproval&&a==="ask"&&!u?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:d}):!e.pendingPlanApproval&&h.length?this.deps.getQuestionButtons(e.id,h,{requestId:e.pendingInputState?.requestId,questionId:r?.id}):void 0,v=wy(e,d),I=r?Ry(r):[],x=r?by({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:I}):c,w=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await lu({sessionName:e.name,question:x??p,context:m,provider:this.deps.questionContextSummaryProvider}):void 0,A=is({session:e,preview:p,questionText:e.pendingPlanApproval?void 0:x,questionContextPreview:m,questionContextSummary:w,planArtifact:v,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:a,planApprovalButtons:k,questionButtons:e.pendingPlanApproval?void 0:k}),y=A.planReviewSummary??p;if(A.label==="plan-approval"&&a==="ask"&&u){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${d??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"never",buttons:A.buttons,wakeMessage:A.wakeMessage});return}if(A.label==="plan-approval"&&a==="ask"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${d??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"always",buttons:A.buttons,hooks:{onNotifyStarted:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.deps.updatePersistedSession(e.id,{canonicalPlanPromptVersion:d,approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>An(e,d),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,d,y),wakeMessageOnNotifySuccess:Ft(e,d)});return}if(A.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${d??"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?()=>Ay(e,o,i):void 0,wakeMessageOnNotifyFailed:A.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=Yi({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${e.result?.num_turns??0}`,userMessage:n.userMessage,wakeMessage:n.wakeMessage,notifyUser:"always",onUserNotifyFailed:()=>{`${e.id}`,this.deps.shouldEmitTerminalWake(e)&&this.emitCompleted(e)}})}emitCompleted(e){let n=this.deps.getOutputPreview(e),r=this.shouldRequestCompletionFollowup(e),o=zi({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i;this.deps.dispatchSessionNotification(e,{label:"completed",idempotencyKey:`terminal-completed:${e.id}`,userMessage:o.userMessage,notifyUser:"always",completionSummary:{required:r,producer:"terminal",outcomeKey:`terminal:${e.id}`},completionWakeSummaryRequired:r,completionWakeOutcomeKey:`terminal:${e.id}`,requireDirectUserNotification:!0,wakeMessageOnNotifySuccess:r?o.wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:r?o.wakeMessageOnNotifyFailed:void 0,hooks:{onNotifySucceeded:()=>{i=!0,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_succeeded",canonicalStatusDelivered:i,followupSummaryRequired:r})},onNotifyFailed:()=>{i=!1,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_failed",canonicalStatusDelivered:i,followupSummaryRequired:r})},onWakeSucceeded:()=>{this.logCompletionWakeDiagnostic({session:e,event:"completion_wake_succeeded",canonicalStatusDelivered:i,followupSummaryRequired:r})}}})}emitFailed(e,n,r){let o=Ji({session:e,originThreadLine:this.deps.originThreadLine(e),errorSummary:n,preview:this.deps.getOutputPreview(e),worktreeAutoCleaned:r,failedButtons:this.deps.getResumeButtons(e.id,e)});this.deps.dispatchSessionNotification(e,{label:"failed",idempotencyKey:`terminal-failed:${e.id}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};Z();he();import{existsSync as Iy}from"fs";var xo=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),l=r?.worktreeBranch??n?.worktreeBranch,a=r?.name??n?.name??e;if(!s)return`Error: No workdir found for session "${e}".`;let d=le(o);!d&&i&&Iy(i)&&ce(s,i,{destructive:!0}),l&&Se(s,l);for(let c of ue(r??n))this.deps.updatePersistedSession(c,{worktreeDisposition:"dismissed",worktreeDismissedAt:new Date().toISOString(),pendingWorktreeDecisionSince:void 0,worktreeState:"dismissed",lifecycle:"terminal",worktreePath:void 0,worktreeBranch:void 0,worktreeLifecycle:{state:"dismissed",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"dismiss",baseBranch:n?.worktreeLifecycle?.baseBranch,targetRepo:n?.worktreePrTargetRepo,pushRemote:n?.worktreePushRemote}});let u=d?`🗑️ [${a}] Branch \`${l??"unknown"}\` dismissed. Native backend worktree released for backend cleanup.`:`🗑️ [${a}] Branch \`${l??"unknown"}\` dismissed and permanently deleted.`;return this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:K(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:${K(r??n??{id:e})??e}:${l??"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 a of ue(r))this.deps.updatePersistedSession(a,{worktreeDecisionSnoozedUntil:i,lastWorktreeReminderAt:new Date(o).toISOString()});let l=`⏭️ Reminder snoozed 24h for \`${r.worktreeBranch??"unknown"}\` (session: ${r.name})`;return n.notifyUser!==!1&&this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:K(r)??$(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${K(r)??$(r)??r.harnessSessionId}:${i}`,userMessage:l,notifyUser:"always"}),l}};var uu=new Set(["starting","running"]),To=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>uu.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>uu.has(o.status)).map(o=>o.name));if(!n.has(e))return e;let r=2;for(;n.has(`${e}-${r}`);)r+=1;return`${e}-${r}`}add(e){this.sessions.set(e.id,e)}remove(e){this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var Co=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(l=>{console.error(`[SessionRuntimeBootstrap] handleTerminal threw for session ${e.id}:`,l)}))}),e.on("lifecycleChange",(i,s)=>{r.taskLifecycle?.progress(e)}),e.on("turnEnd",(i,s)=>{this.deps.handleTurnEnd(e,s).catch(l=>{console.error(`[SessionRuntimeBootstrap] handleTurnEnd threw for session ${e.id}:`,l)})}),e.start(),o.notifyLaunch!==!1){let i=this.deps.formatLaunchWorkdirLabel(e),s=`🚀 [${e.name}] Launched | ${i} | ${rn({harness:e.harnessName,model:e.model})??"default"}`;this.deps.notifySession(e,s,"launch")}return e}};var Mo=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,preview:s,originThreadLine:l}=e,a=o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`;return{label:o?"worktree-no-changes":"worktree-no-changes-cleanup-failed",idempotencyKey:`worktree-no-change:${n.id}:${o?"cleaned":"cleanup-failed"}`,userMessage:o?r?`ℹ️ [${n.name}] Session completed with no changes — native backend worktree released for backend cleanup`:`ℹ️ [${n.name}] Session completed with no changes — worktree cleaned up`:`⚠️ [${n.name}] Session completed with no changes, but worktree cleanup failed. Worktree still exists at ${i}`,wakeMessage:es({sessionName:n.name,sessionId:n.id,cleanupSummary:a,preview:s,originThreadLine:l,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalState:n.approvalState,planApproval:n.planApproval,approvalPromptStatus:n.approvalPromptStatus,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt}),notifyUser:"always"}}buildAskNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,buttons:s,summaryLines:l=[],policyReason:a}=e,d=i.commitMessages.slice(0,5).map(m=>`• ${m.hash} ${m.message} (${m.author})`),u=i.commits>5?`...and ${i.commits-5} more`:"",c=n.worktreePrTargetRepo?`Branch: \`${r}\` → \`${o}\` | PR target: ${n.worktreePrTargetRepo}`:`Branch: \`${r}\` → \`${o}\``;return{label:"worktree-merge-ask",idempotencyKey:["worktree-decision",n.id,r,o,i.commits,i.commitMessages.map(m=>m.hash).join(",")].join(":"),userMessage:[`🔀 Worktree decision required for session \`${n.name}\``,"",c,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`,"",...l.length>0?["Summary:",...l.map(m=>`- ${m}`),""]:[],...a?[`Policy: ${a}`,""]:[],"Recent commits:",...d,...u?[u]:[],"",`⚠️ Discard will permanently delete branch \`${r}\` and all local changes. This cannot be undone.`].join(`
262
262
  `),notifyUser:"always",buttons:s,wakeMessageOnNotifySuccess:["Worktree decision buttons delivered to the user.",`Session: ${n.name} | ID: ${n.id}`,c,"Wait for their button callback — do NOT act on this worktree yourself."].join(`
263
263
  `),wakeMessageOnNotifyFailed:[`🔀 Worktree decision required for session \`${n.name}\``,"",c,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`].join(`
264
- `)}}buildDelegateNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,policyReason:s,allowedActions:l,originThreadLine:a}=e,d=i.commitMessages.slice(0,5).map(m=>`• ${m.hash} ${m.message} (${m.author})`),u=i.commits>5?`...and ${i.commits-5} more`:void 0,c=n.prompt?n.prompt.slice(0,500):"(no prompt)";return{label:"worktree-delegate",idempotencyKey:["worktree-delegate",n.id,r,o,i.commits,i.commitMessages.map(m=>m.hash).join(",")].join(":"),wakeMessage:Yi({sessionName:n.name,sessionId:n.id,branchName:r,baseBranch:o,promptSnippet:c,commitLines:d,moreNote:u,originThreadLine:a,diffSummary:i,allowedActions:l,policyReason:s}),notifyUser:"never"}}};function du(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
265
- `):Py(t);return n?o:o.length>e?uu(t)?ca(o,e):pa(o,e):o}function Py(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
266
- `).trim();return n?uu(t)?wy(n)??n:e.slice(-20).join(`
267
- `):""}function uu(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 wy(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(`
268
- `)?n:void 0}be();he();ie();import{unlinkSync as by}from"fs";var _o=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()}};Z();dn();he();var cu=10080*60*1e3,Ry=300*1e3,pu="tmp-output:cleanup",Ay=60*1e3;function Iy(t){return t instanceof Error?t.message:String(t)}var $o=class{constructor(e){this.deps=e}deps;scheduler=new _o;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),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=Ke(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 l=new Date(i).getTime();Number.isFinite(l)&&this.schedule(this.persistedMaintenanceKey(n,"worktree-retention"),l+cu,()=>{let a=this.deps.store.getPersistedSession(n);a&&this.reconcileResolvedWorktreeRetention(a,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=Ke(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<cu))try{if(!e.worktreePath&&!le(e))return;let l=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!l)return;let a=le(e)?!1:ce(l,e.worktreePath);if(!le(e)&&!a)return;for(let d of ue(e))this.deps.updatePersistedSession(d,{worktreePath:void 0,worktreeBranch:void 0,worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{...e.worktreeLifecycle??r.lifecycle,state:r.cleanupSafe?r.derivedState:s??r.derivedState,updatedAt:new Date(n).toISOString(),resolvedAt:e.worktreeLifecycle?.resolvedAt??o,resolutionSource:e.worktreeLifecycle?.resolutionSource??"maintenance",notes:r.reasons}})}catch(l){`${e.worktreePath}${Iy(l)}`}}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(pu);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(pu,this.getTmpOutputCleanupScheduleAt(n,e),()=>{let r=Date.now();this.runTmpOutputCleanup(r),this.syncTmpOutputCleanupDeadline(r)})}enforcePersistedRetention(){let e=this.deps.store.evictOldestPersisted(this.deps.getMaxPersistedSessions());for(let n of e)this.cancelPersistedMaintenance(n),n.sessionId&&this.cancelRuntimeGc(n.sessionId),this.cleanupOutputPathIfUnreferenced(n.outputPath)}dispose(){this.scheduler.dispose()}persistedMaintenanceRef(e){return e.sessionId??$(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(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+Ay;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()+Ry))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{by(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"}};fn();var mu=new Set(["completed","failed","killed"]),xy=new Set(["starting","running"]),Ty=5e3;function Cy(t,e){return fu("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.prompt,workdir:t.workdir,name:t.name,model:t.model,reasoningEffort:t.reasoningEffort,fastMode:t.fastMode,systemPrompt:t.systemPrompt,allowedTools:t.allowedTools?[...t.allowedTools].sort():t.allowedTools,resumeSessionId:t.resumeSessionId,resumeWorktreeFrom:t.resumeWorktreeFrom,sessionIdOverride:t.sessionIdOverride,clearedPersistedCodexResume:t.clearedPersistedCodexResume,forkSession:t.forkSession,forceNewSession:t.forceNewSession,permissionMode:t.permissionMode,planApproval:t.planApproval,harness:t.harness,worktreeStrategy:t.worktreeStrategy,effectiveWorktreeStrategy:e,worktreeBaseBranch:t.worktreeBaseBranch,worktreePrTargetRepo:t.worktreePrTargetRepo,originAgentId:t.originAgentId})).digest("hex").slice(0,16)}function My(t){return fu("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.launchPrompt,workdir:t.launchWorkdir,name:t.launchName,model:t.launchModel,reasoningEffort:t.launchReasoningEffort,fastMode:t.launchFastMode,systemPrompt:t.launchSystemPrompt,allowedTools:t.launchAllowedTools?[...t.launchAllowedTools].sort():t.launchAllowedTools,resumeSessionId:t.launchResumeSessionId,resumeWorktreeFrom:t.launchResumeWorktreeFrom,sessionIdOverride:t.launchSessionIdOverride,clearedPersistedCodexResume:t.launchClearedPersistedCodexResume,forkSession:t.launchForkSession,forceNewSession:t.launchForceNewSession,permissionMode:t.launchPermissionMode,planApproval:t.launchPlanApproval,harness:t.launchHarness,worktreeStrategy:t.launchWorktreeStrategy,worktreeBaseBranch:t.launchWorktreeBaseBranch,worktreePrTargetRepo:t.launchWorktreePrTargetRepo,originAgentId:t.launchOriginAgentId})).digest("hex").slice(0,16)}var Eo=class t{registry;sessions;maxSessions;maxPersistedSessions;lastWaitingEventTimestamps=new Map;lastTurnCompleteMarkers=new Map;lastTerminalWakeMarkers=new Map;mergeQueue=new Bt;pendingAskUserQuestions=new Map;store;metrics;wakeDispatcher;interactions;notifications;worktrees;questions;lifecycle;restore;stateSync;references;worktreeStrategy;worktreeDecisions;runtimeBootstrap;worktreeMessages;maintenance;constructor(e=20,n=50,r={}){this.maxSessions=e,this.maxPersistedSessions=n;let o=t.createServiceBundle(this,r);this.registry=o.registry,this.sessions=o.sessions,this.store=o.store,this.metrics=o.metrics,this.wakeDispatcher=o.wakeDispatcher,this.interactions=o.interactions,this.notifications=o.notifications,this.worktrees=o.worktrees,this.questions=o.questions,this.lifecycle=o.lifecycle,this.restore=o.restore,this.stateSync=o.stateSync,this.references=o.references,this.worktreeStrategy=o.worktreeStrategy,this.worktreeDecisions=o.worktreeDecisions,this.runtimeBootstrap=o.runtimeBootstrap,this.worktreeMessages=o.worktreeMessages,this.maintenance=o.maintenance}static createServiceBundle(e,n){let r=new To,o=r.sessions,i=new io(n.store),s=new so,l=new go,a=new ho(i.actionTokenStore,Ae),d=new zr(o,i),u=new Hr({store:i,sessions:o,resolveSession:y=>d.resolveActive(y)}),c=new vo(l,(y,b)=>u.applySessionPatch(y,b),{getPersistedSession:y=>i.getPersistedSession(y)}),m=new Po,p=new jr(y=>i.getPersistedSession(y)),f=new Mo,h=new eo({shouldRunWorktreeStrategy:y=>e.shouldRunWorktreeStrategy(y),isAlreadyMerged:y=>e.isAlreadyMerged(y),resolveWorktreeRepoDir:(y,b)=>e.resolveWorktreeRepoDir(y,b),getWorktreeCompletionState:(y,b,V,E)=>e.getWorktreeCompletionState(y,b,V,E),updatePersistedSession:(y,b)=>e.updatePersistedSession(y,b),dispatchSessionNotification:(y,b)=>e.dispatchSessionNotification(y,b),getOutputPreview:(y,b)=>e.getOutputPreview(y,b),originThreadLine:y=>e.originThreadLine(y),getWorktreeDecisionButtons:y=>e.getWorktreeDecisionButtons(y),getPolicyAwareWorktreeDecisionButtons:(y,b,V)=>e.getWorktreeDecisionButtons(y,b,V),makeOpenPrButton:y=>e.makeActionButton(y,"worktree-create-pr","Open PR"),isPrAvailable:y=>e.resolveRepoPolicy(y).prAvailable,resolveRepoPolicy:y=>e.resolveRepoPolicy(y),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:f,enqueueMerge:(y,b,V)=>e.enqueueMerge(y,b,V),mergeBranch:cr,spawnConflictResolver:async({session:y,worktreePath:b,prompt:V})=>e.spawn({prompt:V,workdir:b,name:`${y.name}-conflict-resolver`,harness:y.harnessName||ae(),model:y.model,reasoningEffort:y.reasoningEffort,fastMode:y.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:y.id,route:y.route,originChannel:y.originChannel,originThreadId:y.originThreadId,originAgentId:y.originAgentId,originSessionKey:y.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(y,b)=>{let{makeAgentPrTool:V}=await Promise.resolve().then(()=>(Er(),vl));return{success:(await V().execute("auto-pr",{session:y.id,base_branch:b}))?.meta?.success===!0}}}),k=new wo(e.pendingAskUserQuestions,(y,b)=>e.dispatchSessionNotification(y,b),y=>{e.clearWaitingTimestampsForSession(y)},(y,b,V)=>a.getQuestionButtons(y,b,V)),v=new bo(y=>e.buildRoutingProxy(y),(y,b)=>c.dispatch(y,b),(y,b)=>e.updatePersistedSession(y,b),(y,b)=>e.getPolicyAwareWorktreeDecisionButtons(y,{},void 0,b)),I=new $o({store:i,sessions:o,reminders:v,removeRuntimeSession:y=>r.remove(y),persistSession:(y,b)=>e.persistSession(y,b),clearRuntimeSessionState:y=>{e.clearWaitingTimestampsForSession(y),e.lastTurnCompleteMarkers.delete(y),e.lastTerminalWakeMarkers.delete(y)},resolveWorktreeRepoDir:(y,b)=>e.resolveWorktreeRepoDir(y,b),updatePersistedSession:(y,b)=>e.updatePersistedSession(y,b),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let x=new Io({persistSession:y=>e.persistSession(y),clearWaitingTimestamp:y=>{e.clearWaitingTimestampsForSession(y)},handleWorktreeStrategy:y=>e.handleWorktreeStrategy(y),resolveWorktreeRepoDir:(y,b)=>e.resolveWorktreeRepoDir(y,b),updatePersistedSession:(y,b)=>e.updatePersistedSession(y,b),dispatchSessionNotification:(y,b)=>e.dispatchSessionNotification(y,b),notifySession:(y,b,V)=>e.notifySession(y,b,V),clearRetryTimersForSession:y=>l.clearRetryTimersForSession(y),hasTurnCompleteWakeMarker:y=>e.lastTurnCompleteMarkers.has(y),shouldEmitTurnCompleteWake:y=>e.shouldEmitTurnCompleteWake(y),shouldEmitTerminalWake:y=>e.shouldEmitTerminalWake(y),resolvePlanApprovalMode:y=>e.resolvePlanApprovalMode(y),getPlanApprovalButtons:(y,b)=>a.getPlanApprovalButtons(y,b),getResumeButtons:(y,b)=>a.getResumeButtons(y,b),getQuestionButtons:(y,b,V)=>a.getQuestionButtons(y,b,V),extractLastOutputLine:y=>e.extractLastOutputLine(y),getOutputPreview:(y,b)=>e.getOutputPreview(y,b),originThreadLine:y=>e.originThreadLine(y),debounceWaitingEvent:(y,b)=>e.debounceWaitingEvent(y,b),isAlreadyMerged:y=>e.isAlreadyMerged(y),questionContextSummaryProvider:n.questionContextSummaryProvider??iu()}),w=new xo({getPersistedSession:y=>i.getPersistedSession(y),resolveActiveSession:y=>d.resolveActive(y),resolveWorktreeRepoDir:(y,b)=>e.resolveWorktreeRepoDir(y,b),updatePersistedSession:(y,b)=>e.updatePersistedSession(y,b),dispatchNotification:(y,b)=>c.dispatch(y,b),buildRoutingProxy:y=>e.buildRoutingProxy(y)}),A=new Co({hydrateSpawnedSession:(y,b,V)=>{p.hydrateSpawnedSession(y,b,V)},markRunning:y=>{i.markRunning(y),e.onPersistedSessionChanged(i.getPersistedSession(y.id))},handleTerminal:async y=>e.onSessionTerminal(y),handleTurnEnd:(y,b)=>x.handleTurnEnd(y,b),formatLaunchWorkdirLabel:y=>e.formatLaunchWorkdirLabel(y),notifySession:(y,b,V)=>e.notifySession(y,b,V)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:l,interactions:a,notifications:c,worktrees:m,questions:k,lifecycle:x,restore:p,stateSync:u,references:d,worktreeStrategy:h,worktreeDecisions:w,runtimeBootstrap:A,worktreeMessages:f,maintenance:I}}get persisted(){return this.store.persisted}get idIndex(){return this.store.idIndex}get nameIndex(){return this.store.nameIndex}uniqueName(e){return this.registry.uniqueName(e)}syncRuntimeGcDeadline(e){this.maintenance.syncRuntimeGcDeadline(e)}onPersistedSessionChanged(e){e&&(this.syncPersistedSessionMaintenance(e),this.enforcePersistedRetention())}syncPersistedSessionMaintenance(e){this.maintenance.syncPersistedSessionMaintenance(e)}syncActionTokenExpiryDeadline(){this.maintenance.syncActionTokenExpiryDeadline()}syncTmpOutputCleanupDeadline(e=Date.now()){this.maintenance.syncTmpOutputCleanupDeadline(e)}enforcePersistedRetention(){this.maintenance.enforcePersistedRetention()}bootstrapMaintenanceSchedules(){this.maintenance.bootstrapMaintenanceSchedules()}disposeMaintenance(){this.maintenance.dispose()}spawn(e,n={}){if(this.registry.activeSessionCount()>=this.maxSessions)throw new Error(`Max sessions reached (${this.maxSessions}). Use agent_sessions to list active sessions and agent_kill to end one.`);if(e.sessionIdOverride){let p=this.registry.get(e.sessionIdOverride);if(p?.status==="starting"||p?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${p.status}.`);p&&this.registry.remove(p.id),this.clearWaitingTimestampsForSession(e.sessionIdOverride),this.lastTurnCompleteMarkers.delete(e.sessionIdOverride),this.lastTerminalWakeMarkers.delete(e.sessionIdOverride),this.maintenance.cancelRuntimeGc(e.sessionIdOverride)}let o=e.name||da(e.prompt),i=this.uniqueName(o);if(i!==o&&`${o}${i}`,!e.route?.provider||!e.route.target)throw new Error(`Cannot launch session "${i}": missing explicit route metadata.`);let s=this.checkRepoPolicyForLaunch(e.workdir,e.worktreeStrategy);if(!s.ok){let p=s;throw new Error(p.text)}e.repoIntegrationPolicy=s.resolution.policy,e.repoIntegrationPolicySource=s.resolution.source==="none"?void 0:s.resolution.source,e.repoProvider=s.resolution.provider;let l=this.restore.prepareSpawn(e,i),a=e.harness??"claude-code",d=this,u,c=a==="claude-code"&&!e.canUseTool?async(p,f)=>{if(!u)throw new Error("canUseTool called before session ID was set");return d.handleAskUserQuestion(u,f)}:e.canUseTool,m=new mr({...e,workdir:l.actualWorkdir,systemPrompt:l.effectiveSystemPrompt,canUseTool:c},i);return u=m.id,this.registry.add(m),this.metrics.incrementLaunched(),this.runtimeBootstrap.initializeSession(m,l,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(mu.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=(a,d)=>{if(d==="running"){l(),o();return}mu.has(d)&&(l(),i(new Error(this.describeLaunchFailure(e))))},l=()=>{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 xn({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??D.permissionMode,planApproval:e.planApproval,resumeSessionId:e.resumeSessionId,forkSession:e.forkSession,forceNewSession:e.forceNewSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},n)}shouldRunWorktreeStrategy(e){let n=e.lifecycle;return!(n==="starting"||n==="awaiting_plan_decision"||n==="awaiting_user_input"||e.pendingPlanApproval)}resolveRepoPolicy(e){let n=pn(e);if(!n)return{source:"none",provider:"unsupported",prAvailable:!1};let r=this.store.getRepoPolicy(n.key);if(r)return{identity:n,policy:r.policy,source:"stored",provider:n.provider,prAvailable:n.provider==="github"&&Ae(),record:r};let o=ul(n);if(o){let i=xi(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:Ti({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:Ti({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:Ci(o.identity,r,o.prAvailable)}:{ok:!0,resolution:o}}getRepoPolicyRecordForWorkdir(e){return this.resolveRepoPolicy(e).record}listRepoPolicies(){return this.store.listRepoPolicies()}cleanupRepoPolicies(){let e=[...this.store.cleanupRepoPolicies()],n=[];for(let r of this.store.listRepoPolicies()){let o=pn(r.repoRoot);!o||o.key===r.key||n.push(r.key)}return e.push(...this.store.removeRepoPolicies(n)),e.sort((r,o)=>r.repoRoot.localeCompare(o.repoRoot)||r.key.localeCompare(o.key))}setRepoPolicy(e,n){let r=pn(e);if(r)return this.store.setRepoPolicy(xi(r,n,"stored"))}resetRepoPolicy(e){let n=pn(e);return n?this.store.resetRepoPolicy(n.key):!1}requestRepoPolicyForLaunch(e){let n=e.worktreeStrategy??D.defaultWorktreeStrategy??"off",r=this.resolveRepoPolicy(e.workdir);if(!r.identity)return`Error: ${e.workdir} is not a git repository.`;let o=Ci(r.identity,n,r.prAvailable);if(!e.route?.provider||!e.route.target)return o;let i=`repo-policy:${r.identity.key}`,s=this.interactions.getRepoPolicyChoiceButtons({choiceId:i,route:e.route,repoRoot:r.identity.repoRoot,launchPrompt:e.prompt,launchWorkdir:e.workdir,launchName:e.name,launchModel:e.model,launchReasoningEffort:e.reasoningEffort,launchFastMode:e.fastMode,launchSystemPrompt:e.systemPrompt,launchAllowedTools:e.allowedTools,launchResumeSessionId:e.resumeSessionId,launchResumeWorktreeFrom:e.resumeWorktreeFrom,launchSessionIdOverride:e.sessionIdOverride,launchClearedPersistedCodexResume:e.clearedPersistedCodexResume,launchForkSession:e.forkSession,launchForceNewSession:e.forceNewSession,launchPermissionMode:e.permissionMode,launchPlanApproval:e.planApproval,launchHarness:e.harness,launchWorktreeStrategy:n,launchWorktreeBaseBranch:e.worktreeBaseBranch,launchWorktreePrTargetRepo:e.worktreePrTargetRepo,launchOriginAgentId:e.originAgentId,prAvailable:r.prAvailable}),l=Cy(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}:${l}`,userMessage:[o,"","After you choose a policy, OCA will continue this launch automatically."].join(`
264
+ `)}}buildDelegateNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,policyReason:s,allowedActions:l,originThreadLine:a}=e,d=i.commitMessages.slice(0,5).map(m=>`• ${m.hash} ${m.message} (${m.author})`),u=i.commits>5?`...and ${i.commits-5} more`:void 0,c=n.prompt?n.prompt.slice(0,500):"(no prompt)";return{label:"worktree-delegate",idempotencyKey:["worktree-delegate",n.id,r,o,i.commits,i.commitMessages.map(m=>m.hash).join(",")].join(":"),wakeMessage:Zi({sessionName:n.name,sessionId:n.id,branchName:r,baseBranch:o,promptSnippet:c,commitLines:d,moreNote:u,originThreadLine:a,diffSummary:i,allowedActions:l,policyReason:s}),notifyUser:"never"}}};function cu(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
265
+ `):xy(t);return n?o:o.length>e?pu(t)?ma(o,e):fa(o,e):o}function xy(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
266
+ `).trim();return n?pu(t)?Ty(n)??n:e.slice(-20).join(`
267
+ `):""}function pu(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 Ty(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(`
268
+ `)?n:void 0}be();he();ie();import{unlinkSync as Cy}from"fs";var _o=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()}};Z();dn();he();var mu=10080*60*1e3,My=300*1e3,fu="tmp-output:cleanup",_y=60*1e3;function $y(t){return t instanceof Error?t.message:String(t)}var $o=class{constructor(e){this.deps=e}deps;scheduler=new _o;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),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=Ke(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 l=new Date(i).getTime();Number.isFinite(l)&&this.schedule(this.persistedMaintenanceKey(n,"worktree-retention"),l+mu,()=>{let a=this.deps.store.getPersistedSession(n);a&&this.reconcileResolvedWorktreeRetention(a,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=Ke(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<mu))try{if(!e.worktreePath&&!le(e))return;let l=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!l)return;let a=le(e)?!1:ce(l,e.worktreePath);if(!le(e)&&!a)return;for(let d of ue(e))this.deps.updatePersistedSession(d,{worktreePath:void 0,worktreeBranch:void 0,worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{...e.worktreeLifecycle??r.lifecycle,state:r.cleanupSafe?r.derivedState:s??r.derivedState,updatedAt:new Date(n).toISOString(),resolvedAt:e.worktreeLifecycle?.resolvedAt??o,resolutionSource:e.worktreeLifecycle?.resolutionSource??"maintenance",notes:r.reasons}})}catch(l){`${e.worktreePath}${$y(l)}`}}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(fu);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(fu,this.getTmpOutputCleanupScheduleAt(n,e),()=>{let r=Date.now();this.runTmpOutputCleanup(r),this.syncTmpOutputCleanupDeadline(r)})}enforcePersistedRetention(){let e=this.deps.store.evictOldestPersisted(this.deps.getMaxPersistedSessions());for(let n of e)this.cancelPersistedMaintenance(n),n.sessionId&&this.cancelRuntimeGc(n.sessionId),this.cleanupOutputPathIfUnreferenced(n.outputPath)}dispose(){this.scheduler.dispose()}persistedMaintenanceRef(e){return e.sessionId??$(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(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+_y;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()+My))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{Cy(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"}};fn();var gu=new Set(["completed","failed","killed"]),Ey=new Set(["starting","running"]),Dy=5e3;function Oy(t,e){return hu("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.prompt,workdir:t.workdir,name:t.name,model:t.model,reasoningEffort:t.reasoningEffort,fastMode:t.fastMode,systemPrompt:t.systemPrompt,allowedTools:t.allowedTools?[...t.allowedTools].sort():t.allowedTools,resumeSessionId:t.resumeSessionId,resumeWorktreeFrom:t.resumeWorktreeFrom,sessionIdOverride:t.sessionIdOverride,clearedPersistedCodexResume:t.clearedPersistedCodexResume,forkSession:t.forkSession,forceNewSession:t.forceNewSession,permissionMode:t.permissionMode,planApproval:t.planApproval,harness:t.harness,worktreeStrategy:t.worktreeStrategy,effectiveWorktreeStrategy:e,worktreeBaseBranch:t.worktreeBaseBranch,worktreePrTargetRepo:t.worktreePrTargetRepo,originAgentId:t.originAgentId})).digest("hex").slice(0,16)}function Wy(t){return hu("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.launchPrompt,workdir:t.launchWorkdir,name:t.launchName,model:t.launchModel,reasoningEffort:t.launchReasoningEffort,fastMode:t.launchFastMode,systemPrompt:t.launchSystemPrompt,allowedTools:t.launchAllowedTools?[...t.launchAllowedTools].sort():t.launchAllowedTools,resumeSessionId:t.launchResumeSessionId,resumeWorktreeFrom:t.launchResumeWorktreeFrom,sessionIdOverride:t.launchSessionIdOverride,clearedPersistedCodexResume:t.launchClearedPersistedCodexResume,forkSession:t.launchForkSession,forceNewSession:t.launchForceNewSession,permissionMode:t.launchPermissionMode,planApproval:t.launchPlanApproval,harness:t.launchHarness,worktreeStrategy:t.launchWorktreeStrategy,worktreeBaseBranch:t.launchWorktreeBaseBranch,worktreePrTargetRepo:t.launchWorktreePrTargetRepo,originAgentId:t.launchOriginAgentId})).digest("hex").slice(0,16)}var Eo=class t{registry;sessions;maxSessions;maxPersistedSessions;lastWaitingEventTimestamps=new Map;lastTurnCompleteMarkers=new Map;lastTerminalWakeMarkers=new Map;mergeQueue=new Bt;pendingAskUserQuestions=new Map;store;metrics;wakeDispatcher;interactions;notifications;worktrees;questions;lifecycle;restore;stateSync;references;worktreeStrategy;worktreeDecisions;runtimeBootstrap;worktreeMessages;maintenance;constructor(e=20,n=50,r={}){this.maxSessions=e,this.maxPersistedSessions=n;let o=t.createServiceBundle(this,r);this.registry=o.registry,this.sessions=o.sessions,this.store=o.store,this.metrics=o.metrics,this.wakeDispatcher=o.wakeDispatcher,this.interactions=o.interactions,this.notifications=o.notifications,this.worktrees=o.worktrees,this.questions=o.questions,this.lifecycle=o.lifecycle,this.restore=o.restore,this.stateSync=o.stateSync,this.references=o.references,this.worktreeStrategy=o.worktreeStrategy,this.worktreeDecisions=o.worktreeDecisions,this.runtimeBootstrap=o.runtimeBootstrap,this.worktreeMessages=o.worktreeMessages,this.maintenance=o.maintenance}static createServiceBundle(e,n){let r=new To,o=r.sessions,i=new io(n.store),s=new so,l=new go,a=new ho(i.actionTokenStore,Ae),d=new zr(o,i),u=new Hr({store:i,sessions:o,resolveSession:y=>d.resolveActive(y)}),c=new vo(l,(y,b)=>u.applySessionPatch(y,b),{getPersistedSession:y=>i.getPersistedSession(y)}),m=new Po,p=new jr(y=>i.getPersistedSession(y)),f=new Mo,h=new eo({shouldRunWorktreeStrategy:y=>e.shouldRunWorktreeStrategy(y),isAlreadyMerged:y=>e.isAlreadyMerged(y),resolveWorktreeRepoDir:(y,b)=>e.resolveWorktreeRepoDir(y,b),getWorktreeCompletionState:(y,b,V,E)=>e.getWorktreeCompletionState(y,b,V,E),updatePersistedSession:(y,b)=>e.updatePersistedSession(y,b),dispatchSessionNotification:(y,b)=>e.dispatchSessionNotification(y,b),getOutputPreview:(y,b)=>e.getOutputPreview(y,b),originThreadLine:y=>e.originThreadLine(y),getWorktreeDecisionButtons:y=>e.getWorktreeDecisionButtons(y),getPolicyAwareWorktreeDecisionButtons:(y,b,V)=>e.getWorktreeDecisionButtons(y,b,V),makeOpenPrButton:y=>e.makeActionButton(y,"worktree-create-pr","Open PR"),isPrAvailable:y=>e.resolveRepoPolicy(y).prAvailable,resolveRepoPolicy:y=>e.resolveRepoPolicy(y),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:f,enqueueMerge:(y,b,V)=>e.enqueueMerge(y,b,V),mergeBranch:cr,spawnConflictResolver:async({session:y,worktreePath:b,prompt:V})=>e.spawn({prompt:V,workdir:b,name:`${y.name}-conflict-resolver`,harness:y.harnessName||ae(),model:y.model,reasoningEffort:y.reasoningEffort,fastMode:y.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:y.id,route:y.route,originChannel:y.originChannel,originThreadId:y.originThreadId,originAgentId:y.originAgentId,originSessionKey:y.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(y,b)=>{let{makeAgentPrTool:V}=await Promise.resolve().then(()=>(Er(),wl));return{success:(await V().execute("auto-pr",{session:y.id,base_branch:b}))?.meta?.success===!0}}}),k=new wo(e.pendingAskUserQuestions,(y,b)=>e.dispatchSessionNotification(y,b),y=>{e.clearWaitingTimestampsForSession(y)},(y,b,V)=>a.getQuestionButtons(y,b,V)),v=new bo(y=>e.buildRoutingProxy(y),(y,b)=>c.dispatch(y,b),(y,b)=>e.updatePersistedSession(y,b),(y,b)=>e.getPolicyAwareWorktreeDecisionButtons(y,{},void 0,b)),I=new $o({store:i,sessions:o,reminders:v,removeRuntimeSession:y=>r.remove(y),persistSession:(y,b)=>e.persistSession(y,b),clearRuntimeSessionState:y=>{e.clearWaitingTimestampsForSession(y),e.lastTurnCompleteMarkers.delete(y),e.lastTerminalWakeMarkers.delete(y)},resolveWorktreeRepoDir:(y,b)=>e.resolveWorktreeRepoDir(y,b),updatePersistedSession:(y,b)=>e.updatePersistedSession(y,b),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let x=new Io({persistSession:y=>e.persistSession(y),clearWaitingTimestamp:y=>{e.clearWaitingTimestampsForSession(y)},handleWorktreeStrategy:y=>e.handleWorktreeStrategy(y),resolveWorktreeRepoDir:(y,b)=>e.resolveWorktreeRepoDir(y,b),updatePersistedSession:(y,b)=>e.updatePersistedSession(y,b),dispatchSessionNotification:(y,b)=>e.dispatchSessionNotification(y,b),notifySession:(y,b,V)=>e.notifySession(y,b,V),clearRetryTimersForSession:y=>l.clearRetryTimersForSession(y),hasTurnCompleteWakeMarker:y=>e.lastTurnCompleteMarkers.has(y),shouldEmitTurnCompleteWake:y=>e.shouldEmitTurnCompleteWake(y),shouldEmitTerminalWake:y=>e.shouldEmitTerminalWake(y),resolvePlanApprovalMode:y=>e.resolvePlanApprovalMode(y),getPlanApprovalButtons:(y,b)=>a.getPlanApprovalButtons(y,b),getResumeButtons:(y,b)=>a.getResumeButtons(y,b),getQuestionButtons:(y,b,V)=>a.getQuestionButtons(y,b,V),extractLastOutputLine:y=>e.extractLastOutputLine(y),getOutputPreview:(y,b)=>e.getOutputPreview(y,b),originThreadLine:y=>e.originThreadLine(y),debounceWaitingEvent:(y,b)=>e.debounceWaitingEvent(y,b),isAlreadyMerged:y=>e.isAlreadyMerged(y),questionContextSummaryProvider:n.questionContextSummaryProvider??au()}),w=new xo({getPersistedSession:y=>i.getPersistedSession(y),resolveActiveSession:y=>d.resolveActive(y),resolveWorktreeRepoDir:(y,b)=>e.resolveWorktreeRepoDir(y,b),updatePersistedSession:(y,b)=>e.updatePersistedSession(y,b),dispatchNotification:(y,b)=>c.dispatch(y,b),buildRoutingProxy:y=>e.buildRoutingProxy(y)}),A=new Co({hydrateSpawnedSession:(y,b,V)=>{p.hydrateSpawnedSession(y,b,V)},markRunning:y=>{i.markRunning(y),e.onPersistedSessionChanged(i.getPersistedSession(y.id))},handleTerminal:async y=>e.onSessionTerminal(y),handleTurnEnd:(y,b)=>x.handleTurnEnd(y,b),formatLaunchWorkdirLabel:y=>e.formatLaunchWorkdirLabel(y),notifySession:(y,b,V)=>e.notifySession(y,b,V)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:l,interactions:a,notifications:c,worktrees:m,questions:k,lifecycle:x,restore:p,stateSync:u,references:d,worktreeStrategy:h,worktreeDecisions:w,runtimeBootstrap:A,worktreeMessages:f,maintenance:I}}get persisted(){return this.store.persisted}get idIndex(){return this.store.idIndex}get nameIndex(){return this.store.nameIndex}uniqueName(e){return this.registry.uniqueName(e)}syncRuntimeGcDeadline(e){this.maintenance.syncRuntimeGcDeadline(e)}onPersistedSessionChanged(e){e&&(this.syncPersistedSessionMaintenance(e),this.enforcePersistedRetention())}syncPersistedSessionMaintenance(e){this.maintenance.syncPersistedSessionMaintenance(e)}syncActionTokenExpiryDeadline(){this.maintenance.syncActionTokenExpiryDeadline()}syncTmpOutputCleanupDeadline(e=Date.now()){this.maintenance.syncTmpOutputCleanupDeadline(e)}enforcePersistedRetention(){this.maintenance.enforcePersistedRetention()}bootstrapMaintenanceSchedules(){this.maintenance.bootstrapMaintenanceSchedules()}disposeMaintenance(){this.maintenance.dispose()}spawn(e,n={}){if(this.registry.activeSessionCount()>=this.maxSessions)throw new Error(`Max sessions reached (${this.maxSessions}). Use agent_sessions to list active sessions and agent_kill to end one.`);if(e.sessionIdOverride){let p=this.registry.get(e.sessionIdOverride);if(p?.status==="starting"||p?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${p.status}.`);p&&this.registry.remove(p.id),this.clearWaitingTimestampsForSession(e.sessionIdOverride),this.lastTurnCompleteMarkers.delete(e.sessionIdOverride),this.lastTerminalWakeMarkers.delete(e.sessionIdOverride),this.maintenance.cancelRuntimeGc(e.sessionIdOverride)}let o=e.name||ca(e.prompt),i=this.uniqueName(o);if(i!==o&&`${o}${i}`,!e.route?.provider||!e.route.target)throw new Error(`Cannot launch session "${i}": missing explicit route metadata.`);let s=this.checkRepoPolicyForLaunch(e.workdir,e.worktreeStrategy);if(!s.ok){let p=s;throw new Error(p.text)}e.repoIntegrationPolicy=s.resolution.policy,e.repoIntegrationPolicySource=s.resolution.source==="none"?void 0:s.resolution.source,e.repoProvider=s.resolution.provider;let l=this.restore.prepareSpawn(e,i),a=e.harness??"claude-code",d=this,u,c=a==="claude-code"&&!e.canUseTool?async(p,f)=>{if(!u)throw new Error("canUseTool called before session ID was set");return d.handleAskUserQuestion(u,f)}:e.canUseTool,m=new mr({...e,workdir:l.actualWorkdir,systemPrompt:l.effectiveSystemPrompt,canUseTool:c},i);return u=m.id,this.registry.add(m),this.metrics.incrementLaunched(),this.runtimeBootstrap.initializeSession(m,l,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(gu.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=(a,d)=>{if(d==="running"){l(),o();return}gu.has(d)&&(l(),i(new Error(this.describeLaunchFailure(e))))},l=()=>{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 xn({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??D.permissionMode,planApproval:e.planApproval,resumeSessionId:e.resumeSessionId,forkSession:e.forkSession,forceNewSession:e.forceNewSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},n)}shouldRunWorktreeStrategy(e){let n=e.lifecycle;return!(n==="starting"||n==="awaiting_plan_decision"||n==="awaiting_user_input"||e.pendingPlanApproval)}resolveRepoPolicy(e){let n=pn(e);if(!n)return{source:"none",provider:"unsupported",prAvailable:!1};let r=this.store.getRepoPolicy(n.key);if(r)return{identity:n,policy:r.policy,source:"stored",provider:n.provider,prAvailable:n.provider==="github"&&Ae(),record:r};let o=pl(n);if(o){let i=Ti(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:Ci({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:Ci({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:Mi(o.identity,r,o.prAvailable)}:{ok:!0,resolution:o}}getRepoPolicyRecordForWorkdir(e){return this.resolveRepoPolicy(e).record}listRepoPolicies(){return this.store.listRepoPolicies()}cleanupRepoPolicies(){let e=[...this.store.cleanupRepoPolicies()],n=[];for(let r of this.store.listRepoPolicies()){let o=pn(r.repoRoot);!o||o.key===r.key||n.push(r.key)}return e.push(...this.store.removeRepoPolicies(n)),e.sort((r,o)=>r.repoRoot.localeCompare(o.repoRoot)||r.key.localeCompare(o.key))}setRepoPolicy(e,n){let r=pn(e);if(r)return this.store.setRepoPolicy(Ti(r,n,"stored"))}resetRepoPolicy(e){let n=pn(e);return n?this.store.resetRepoPolicy(n.key):!1}requestRepoPolicyForLaunch(e){let n=e.worktreeStrategy??D.defaultWorktreeStrategy??"off",r=this.resolveRepoPolicy(e.workdir);if(!r.identity)return`Error: ${e.workdir} is not a git repository.`;let o=Mi(r.identity,n,r.prAvailable);if(!e.route?.provider||!e.route.target)return o;let i=`repo-policy:${r.identity.key}`,s=this.interactions.getRepoPolicyChoiceButtons({choiceId:i,route:e.route,repoRoot:r.identity.repoRoot,launchPrompt:e.prompt,launchWorkdir:e.workdir,launchName:e.name,launchModel:e.model,launchReasoningEffort:e.reasoningEffort,launchFastMode:e.fastMode,launchSystemPrompt:e.systemPrompt,launchAllowedTools:e.allowedTools,launchResumeSessionId:e.resumeSessionId,launchResumeWorktreeFrom:e.resumeWorktreeFrom,launchSessionIdOverride:e.sessionIdOverride,launchClearedPersistedCodexResume:e.clearedPersistedCodexResume,launchForkSession:e.forkSession,launchForceNewSession:e.forceNewSession,launchPermissionMode:e.permissionMode,launchPlanApproval:e.planApproval,launchHarness:e.harness,launchWorktreeStrategy:n,launchWorktreeBaseBranch:e.worktreeBaseBranch,launchWorktreePrTargetRepo:e.worktreePrTargetRepo,launchOriginAgentId:e.originAgentId,prAvailable:r.prAvailable}),l=Oy(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}:${l}`,userMessage:[o,"","After you choose a policy, OCA will continue this launch automatically."].join(`
269
269
  `),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(`
270
- `),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??ae(),o=e.permissionMode??D.permissionMode,i=e.planApproval??D.planApproval,s=this.spawn({prompt:e.prompt,workdir:e.workdir,sessionIdOverride:e.sessionIdOverride,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,allowedTools:e.allowedTools,resumeSessionId:e.resumeSessionId,resumeWorktreeFrom:e.resumeWorktreeFrom,forkSession:e.resumeSessionId?e.forkSession:!1,multiTurn:!0,permissionMode:o,planApproval:i,codexApprovalPolicy:r==="codex"?"never":void 0,originChannel:this.originChannelFromRoute(n),originThreadId:n.threadId,originAgentId:e.originAgentId,originSessionKey:n.sessionKey,route:n,harness:r,worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo});return{session:s,text:this.formatLaunchResult({prompt:e.prompt,workdir:e.workdir,harness:r,permissionMode:o,planApproval:i,forceNewSession:e.forceNewSession,resumeSessionId:e.resumeSessionId,forkSession:e.forkSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},s)}}continueLaunchAfterManualRepoPolicy(e,n){let r=this.resolveRepoPolicy(e);if(!r.identity)return{kind:"none"};let o=this.interactions.listActiveActionTokens("repo-policy-set").filter(u=>u.repoPolicyWorkdir===r.identity?.repoRoot),i=()=>{for(let u of new Set(o.map(c=>c.sessionId)))this.clearRepoPolicyChoiceTokens(u)},s=o.filter(u=>u.repoPolicy===n&&!!u.launchPrompt&&!!u.launchWorkdir&&!!u.route?.provider&&!!u.route?.target);if(s.length===0)return i(),{kind:"none"};let l=new Map;for(let u of s){let c=My(u);l.has(c)||l.set(c,u)}if(l.size>1)return i(),{kind:"ambiguous",count:l.size};let a=[...l.values()][0];if(!a.launchPrompt||!a.launchWorkdir)return{kind:"none"};let d=this.launchAfterRepoPolicyChoice({route:a.route,prompt:a.launchPrompt,workdir:a.launchWorkdir,name:a.launchName,model:a.launchModel,reasoningEffort:a.launchReasoningEffort,fastMode:a.launchFastMode,systemPrompt:a.launchSystemPrompt,allowedTools:a.launchAllowedTools,resumeSessionId:a.launchResumeSessionId,resumeWorktreeFrom:a.launchResumeWorktreeFrom,sessionIdOverride:a.launchSessionIdOverride,clearedPersistedCodexResume:a.launchClearedPersistedCodexResume,forkSession:a.launchForkSession,forceNewSession:a.launchForceNewSession,permissionMode:a.launchPermissionMode,planApproval:a.launchPlanApproval,harness:a.launchHarness,worktreeStrategy:a.launchWorktreeStrategy,worktreeBaseBranch:a.launchWorktreeBaseBranch,worktreePrTargetRepo:a.launchWorktreePrTargetRepo,originAgentId:a.launchOriginAgentId});return this.consumeActionToken(a.id),this.clearRepoPolicyChoiceTokens(a.sessionId),{kind:"launched",...d}}makeActionButton(e,n,r,o={}){return this.interactions.makeActionButton(e,n,r,o)}consumeActionToken(e){return this.interactions.consumeActionToken(e)}getActionToken(e){return this.interactions.getActionToken(e)}clearRepoPolicyChoiceTokens(e){this.interactions.clearRepoPolicyChoiceTokens(e)}clearPlanDecisionTokens(e,n){this.interactions.clearPlanDecisionTokens(e,n)}isCurrentPendingPlanDecision(e,n){let r=this.resolve(e)??this.getPersistedSession(e);return An(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:Pn({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:Ft(e,n,!0),wakeMessageOnNotifyFailed:Ro({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),l=this.resolveWorktreeRepoDir(i?.originalWorkdir??s?.workdir,i?.worktreePath??s?.worktreePath),a=l?this.resolveRepoPolicy(l):void 0,d=i?.repoIntegrationPolicy??s?.repoIntegrationPolicy,u=d??a?.policy,c=!!u,m=a?.prAvailable??!!(d&&d!=="never-pr"&&d!=="manual"),p={merge:!c||u!=="pr-required"&&u!=="manual",pr:!c||u!=="never-pr"&&u!=="manual"&&m};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=ns(r),i=this.resolve(e),s=i?void 0:this.getPersistedSession(e),l=i??s;if(!l)return`Error: Session "${e}" not found.`;if(!l.pendingPlanApproval)return`Error: Session "${e}" is not awaiting plan approval.`;let a=K(i??s??{id:e})??e;if(this.resolvePlanApprovalMode(l)!=="delegate")return`Error: Session "${e}" already uses direct user plan approval. Do not send a duplicate approval prompt.`;let d=l.actionablePlanDecisionVersion??l.planDecisionVersion;if(Rn(l,d))return[`An actionable plan review prompt already exists for session ${l.name} [${a}].`,"Wait for the user's Approve, Revise, or Reject response.","Do not send a separate plain-text approval message."].join(" ");if(l.deliveryState==="notifying")return[`A plan approval prompt is already being delivered for session ${l.name} [${a}].`,"Wait for delivery to finish before retrying."].join(" ");let u=this.interactions.getPlanApprovalButtons(a,{...l,planDecisionVersion:d}),c=[`📋 [${l.name}] Plan v${d??"?"} needs your decision:`,"","Why this was escalated:","",o,"","Choose Approve, Revise, or Reject below."].join(`
270
+ `),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??ae(),o=e.permissionMode??D.permissionMode,i=e.planApproval??D.planApproval,s=this.spawn({prompt:e.prompt,workdir:e.workdir,sessionIdOverride:e.sessionIdOverride,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,allowedTools:e.allowedTools,resumeSessionId:e.resumeSessionId,resumeWorktreeFrom:e.resumeWorktreeFrom,forkSession:e.resumeSessionId?e.forkSession:!1,multiTurn:!0,permissionMode:o,planApproval:i,codexApprovalPolicy:r==="codex"?"never":void 0,originChannel:this.originChannelFromRoute(n),originThreadId:n.threadId,originAgentId:e.originAgentId,originSessionKey:n.sessionKey,route:n,harness:r,worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo});return{session:s,text:this.formatLaunchResult({prompt:e.prompt,workdir:e.workdir,harness:r,permissionMode:o,planApproval:i,forceNewSession:e.forceNewSession,resumeSessionId:e.resumeSessionId,forkSession:e.forkSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},s)}}continueLaunchAfterManualRepoPolicy(e,n){let r=this.resolveRepoPolicy(e);if(!r.identity)return{kind:"none"};let o=this.interactions.listActiveActionTokens("repo-policy-set").filter(u=>u.repoPolicyWorkdir===r.identity?.repoRoot),i=()=>{for(let u of new Set(o.map(c=>c.sessionId)))this.clearRepoPolicyChoiceTokens(u)},s=o.filter(u=>u.repoPolicy===n&&!!u.launchPrompt&&!!u.launchWorkdir&&!!u.route?.provider&&!!u.route?.target);if(s.length===0)return i(),{kind:"none"};let l=new Map;for(let u of s){let c=Wy(u);l.has(c)||l.set(c,u)}if(l.size>1)return i(),{kind:"ambiguous",count:l.size};let a=[...l.values()][0];if(!a.launchPrompt||!a.launchWorkdir)return{kind:"none"};let d=this.launchAfterRepoPolicyChoice({route:a.route,prompt:a.launchPrompt,workdir:a.launchWorkdir,name:a.launchName,model:a.launchModel,reasoningEffort:a.launchReasoningEffort,fastMode:a.launchFastMode,systemPrompt:a.launchSystemPrompt,allowedTools:a.launchAllowedTools,resumeSessionId:a.launchResumeSessionId,resumeWorktreeFrom:a.launchResumeWorktreeFrom,sessionIdOverride:a.launchSessionIdOverride,clearedPersistedCodexResume:a.launchClearedPersistedCodexResume,forkSession:a.launchForkSession,forceNewSession:a.launchForceNewSession,permissionMode:a.launchPermissionMode,planApproval:a.launchPlanApproval,harness:a.launchHarness,worktreeStrategy:a.launchWorktreeStrategy,worktreeBaseBranch:a.launchWorktreeBaseBranch,worktreePrTargetRepo:a.launchWorktreePrTargetRepo,originAgentId:a.launchOriginAgentId});return this.consumeActionToken(a.id),this.clearRepoPolicyChoiceTokens(a.sessionId),{kind:"launched",...d}}makeActionButton(e,n,r,o={}){return this.interactions.makeActionButton(e,n,r,o)}consumeActionToken(e){return this.interactions.consumeActionToken(e)}getActionToken(e){return this.interactions.getActionToken(e)}clearRepoPolicyChoiceTokens(e){this.interactions.clearRepoPolicyChoiceTokens(e)}clearPlanDecisionTokens(e,n){this.interactions.clearPlanDecisionTokens(e,n)}isCurrentPendingPlanDecision(e,n){let r=this.resolve(e)??this.getPersistedSession(e);return An(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:Pn({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:Ft(e,n,!0),wakeMessageOnNotifyFailed:Ro({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),l=this.resolveWorktreeRepoDir(i?.originalWorkdir??s?.workdir,i?.worktreePath??s?.worktreePath),a=l?this.resolveRepoPolicy(l):void 0,d=i?.repoIntegrationPolicy??s?.repoIntegrationPolicy,u=d??a?.policy,c=a?.prAvailable??!!(d&&d!=="never-pr"&&d!=="manual"),m=u?xi({policy:u,prAvailable:c}):{merge:!0,pr:!0};return this.getWorktreeDecisionButtons(e,n,m)}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=rs(r),i=this.resolve(e),s=i?void 0:this.getPersistedSession(e),l=i??s;if(!l)return`Error: Session "${e}" not found.`;if(!l.pendingPlanApproval)return`Error: Session "${e}" is not awaiting plan approval.`;let a=K(i??s??{id:e})??e;if(this.resolvePlanApprovalMode(l)!=="delegate")return`Error: Session "${e}" already uses direct user plan approval. Do not send a duplicate approval prompt.`;let d=l.actionablePlanDecisionVersion??l.planDecisionVersion;if(Rn(l,d))return[`An actionable plan review prompt already exists for session ${l.name} [${a}].`,"Wait for the user's Approve, Revise, or Reject response.","Do not send a separate plain-text approval message."].join(" ");if(l.deliveryState==="notifying")return[`A plan approval prompt is already being delivered for session ${l.name} [${a}].`,"Wait for delivery to finish before retrying."].join(" ");let u=this.interactions.getPlanApprovalButtons(a,{...l,planDecisionVersion:d}),c=[`📋 [${l.name}] Plan v${d??"?"} needs your decision:`,"","Why this was escalated:","",o,"","Choose Approve, Revise, or Reject below."].join(`
271
271
  `);return this.notifications.dispatch(this.buildRoutingProxy({id:a,name:l.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:${a}:v${d??"unknown"}:canonical`,userMessage:c,notifyUser:"always",buttons:u,hooks:{onNotifyStarted:()=>{this.updatePersistedSession(a,{approvalPromptRequiredVersion:d,approvalPromptStatus:"sending",approvalPromptVersion:d,approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.updatePersistedSession(a,{canonicalPlanPromptVersion:d,approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.updatePersistedSession(a,{approvalPromptRequiredVersion:d,approvalPromptVersion:d,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>this.isCurrentPendingPlanDecision(a,d),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(this.buildRoutingProxy({id:a,name:l.name,sessionId:s?.sessionId,harnessSessionId:i?.harnessSessionId??s?.harnessSessionId,backendRef:i?.backendRef??s?.backendRef,route:i?.route??s?.route}),d,o),wakeMessageOnNotifySuccess:Ft({id:a,name:l.name},d)}),[`Canonical plan approval prompt sent for session ${l.name} [${a}].`,"Wait for the user's Approve, Revise, or Reject response.","Do not send a separate plain-text approval message."].join(" ")}requestWorktreeDecisionFromUser(e,n){let r=n.trim();if(!r)return"Error: summary must not be empty.";let o=this.resolve(e),i=this.getPersistedSession(e),s=o??i;if(!s)return`Error: Session "${e}" not found.`;if(s.worktreeStrategy!=="delegate")return`Error: Session "${e}" already uses direct user worktree decisions. Do not send a duplicate decision prompt.`;if(!(!!("pendingWorktreeDecisionSince"in s?s.pendingWorktreeDecisionSince:void 0)||s.worktreeState==="pending_decision"||s.worktreeLifecycle?.state==="pending_decision"))return`Error: Session "${e}" is not awaiting a delegated worktree decision.`;let d=K(o??i??{id:e})??e,u=o?.worktreePath??i?.worktreePath,c=o?.worktreeBranch??i?.worktreeBranch,m=this.resolveWorktreeRepoDir(o?.originalWorkdir??i?.workdir,u);if(!u)return`Error: Session "${e}" has no managed worktree path.`;if(!c)return`Error: Session "${e}" has no managed worktree branch.`;if(!m)return`Error: Session "${e}" has no resolvable repository root for worktree ${u}.`;let p=o?.worktreeBaseBranch??i?.worktreeBaseBranch??Te(m),f=Ee(m,c,p);if(!f)return`Error: Could not compute worktree diff summary for session "${e}".`;let h=this.getPolicyAwareWorktreeDecisionButtons(d,{allowDelegate:!0},o,i);if(!h||h.length===0)return`Error: Could not create worktree decision buttons for session "${e}".`;let k=r.split(/\r?\n/).map(v=>v.replace(/^[-*]\s+/,"").trim()).filter(v=>v.length>0);return this.notifications.dispatch(this.buildRoutingProxy({id:d,name:s.name,sessionId:i?.sessionId,harnessSessionId:o?.harnessSessionId??i?.harnessSessionId,backendRef:o?.backendRef??i?.backendRef,route:o?.route??i?.route}),this.worktreeMessages.buildAskNotification({session:{id:d,name:s.name,worktreePrTargetRepo:o?.worktreePrTargetRepo??i?.worktreePrTargetRepo},branchName:c,baseBranch:p,diffSummary:f,summaryLines:k,buttons:h})),[`Canonical worktree decision prompt sent for session ${s.name} [${d}].`,"Wait for the user's Merge, Open PR, Later, or Discard response.","Do not send a separate plain-text worktree decision message."].join(" ")}buildRoutingProxy(e){return{id:K(e)??$(e)??e.harnessSessionId??"unknown-session",name:e.name,harnessSessionId:e.harnessSessionId,backendRef:e.backendRef?{...e.backendRef}:void 0,route:e.route}}resolveWorktreeRepoDir(e,n){return e&&(!n||!Gr(e,n))||!n?e:ar(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",l=r?.worktreePath??o?.worktreePath??"(unknown worktree)",a=r?.worktreeBaseBranch??o?.worktreeBaseBranch,d=r?.worktreePrTargetRepo??o?.worktreePrTargetRepo,u=r?.worktreePushRemote??o?.worktreePushRemote;this.updatePersistedSession(n,wr({worktreeBaseBranch:a,worktreePrTargetRepo:d,worktreePushRemote:u},{clearResolverSessionId:!0,notes:[e.status==="completed"?"auto_merge_conflict_resolver_completed_without_retry_target":"auto_merge_conflict_resolver_failed"]})),this.dispatchSessionNotification(i,{label:"worktree-merge-conflict-resolver-failed",idempotencyKey:`worktree-merge-conflict-resolver-failed:${n}:${e.id}`,userMessage:[`⚠️ [${i.name}] Auto-merge conflict resolution did not complete successfully.`,`Branch \`${s}\` was preserved for manual follow-up in ${l}.`,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(`
272
272
  `),buttons:this.getPolicyAwareWorktreeDecisionButtons(n,{allowDelegate:!0},r,o)})}persistSession(e,n={}){let r=n.scheduleRuntimeGc??!0;this.store.hasRecordedSession(e.id)||this.metrics.recordSession(e),this.store.persistTerminal(e),r&&this.syncRuntimeGcDeadline(e),this.onPersistedSessionChanged(this.store.getPersistedSession(e.id)),this.syncTmpOutputCleanupDeadline()}getMetrics(){return this.metrics.getMetrics()}notifySession(e,n,r="notification"){this.dispatchSessionNotification(e,{label:r,idempotencyKey:r==="agent-respond"?void 0:`notify:${e.id}:${r}:${n}`,userMessage:n,notifyUser:"always"})}sendPlanOffer(e){let n=this.interactions.getPlanOfferButtons({offerId:e.offerId,route:e.route,planName:e.planName,planPrompt:e.planPrompt,planWorkdir:e.planWorkdir,planWorktreeStrategy:e.planWorktreeStrategy});this.dispatchSessionNotification(this.buildRoutingProxy({id:e.offerId,route:e.route}),{label:"plan-offer",idempotencyKey:`plan-offer:${e.offerId}`,userMessage:e.text,notifyUser:"always",buttons:n})}emitGoalTaskUpdate(e,n,r="goal-task"){let o=e.sessionId??e.id,i=this.buildRoutingProxy({id:o,name:e.sessionName??e.name,route:e.route});i.originChannel=e.originChannel,i.originThreadId=e.originThreadId,i.originSessionKey=e.originSessionKey;let s=r==="goal-task-succeeded",l=[`✅ [${e.name}] Goal task succeeded`,e.sessionId?`Session: ${e.sessionName??e.name} [${e.sessionId}]`:void 0].filter(d=>!!d).join(`
273
- `),a=d=>zi({sessionId:o,sessionName:e.sessionName,taskName:e.name,summary:n,originThreadLine:Gt(i),canonicalStatusDelivered:d});this.dispatchSessionNotification(i,{label:r,idempotencyKey:`goal:${e.id}:${r}:${s?"success":n}`,userMessage:s?l: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?a(!0):void 0,wakeMessageOnNotifyFailed:s?a(!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:ae(),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<Ty?!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 Gt(e)}extractLastOutputLine(e){return e.getOutput(3).filter(o=>o.trim()).pop()?.trim()||void 0}getOutputPreview(e,n=1e3){return du(e,n)}resolvePlanApprovalMode(e){return e.planApproval??D.planApproval??"delegate"}shouldEmitTurnCompleteWake(e){let n=`${e.result?.session_id??""}|${e.result?.num_turns??0}|${e.result?.duration_ms??0}`;return this.lastTurnCompleteMarkers.get(e.id)===n?(`${e.id}${n}`,!1):(this.lastTurnCompleteMarkers.set(e.id,n),!0)}shouldEmitTerminalWake(e){let n=`${e.status}|${e.completedAt??0}|${e.result?.session_id??""}|${e.result?.num_turns??0}|${e.killReason}`;return this.lastTerminalWakeMarkers.get(e.id)===n?!1:(this.lastTerminalWakeMarkers.set(e.id,n),!0)}resolve(e){return this.references.resolveActive(e)}get(e){return this.registry.get(e)}list(e){let n=this.registry.list();return e&&e!=="all"&&(n=n.filter(r=>r.status===e)),n.sort((r,o)=>o.startedAt-r.startedAt)}kill(e,n){let r=this.registry.get(e);if(!r)return!1;if(r.pendingPlanApproval){this.clearPlanDecisionTokens(r.id);let o={lifecycle:"terminal",runtimeState:"stopped",pendingPlanApproval:!1,planApprovalContext:void 0,approvalState:r.approvalState==="pending"?"rejected":r.approvalState,planDecisionVersion:(r.planDecisionVersion??0)+1,actionablePlanDecisionVersion:void 0,canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:void 0,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",approvalPromptTransport:"none",approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:void 0};r.applyControlPatch(o),Object.assign(r,o),this.updatePersistedSession(r.id,o)}return r.kill(n??"user"),!0}killAll(e="user"){for(let n of this.sessions.values())xy.has(n.status)&&this.kill(n.id,e)}resolveBackendConversationId(e){return this.references.resolveBackendConversationId(e)}resolveHarnessSessionId(e){return this.resolveBackendConversationId(e)}getPersistedSession(e){return this.references.getPersistedSession(e)}isAlreadyMerged(e){if(!e)return!1;let n=this.store.getPersistedSession(e);return n?.worktreeMerged===!0||n?.worktreeLifecycle?.state==="merged"||n?.worktreeLifecycle?.state==="released"}async enqueueMerge(e,n,r){return this.mergeQueue.enqueue(e,n,r)}updatePersistedSession(e,n){let r=this.stateSync.applySessionPatch(e,n);return r&&this.onPersistedSessionChanged(this.store.getPersistedSession(e)),r}listPersistedSessions(){return this.store.listPersistedSessions()}async handleAskUserQuestion(e,n){let r=this.sessions.get(e);if(!r)throw new Error(`Session "${e}" not found for AskUserQuestion intercept`);return this.questions.handleAskUserQuestion(r,n)}resolveAskUserQuestion(e,n,r={}){return this.questions.resolveAskUserQuestion(e,n,r)}async resolvePendingInputOption(e,n,r={}){let o=this.sessions.get(e);return o?.canSubmitPendingInputOption?.()?await o.submitPendingInputOption(n,r)?(this.clearWaitingTimestampsForSession(e),!0):!1:this.questions.resolveAskUserQuestion(e,n,r)}dispose(){this.disposeMaintenance(),this.questions.dispose(),this.notifications.dispose()}};L();ie();import{definePluginEntry as gu}from"openclaw/plugin-sdk/plugin-entry";function Oy(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(a=>a.worktreePath).filter(a=>typeof a=="string"&&a.length>0)),i=new Set,s=process.env.OPENCLAW_WORKTREE_DIR??D.worktreeDir;if(s)i.add(s);else for(let a of t.listPersistedSessions())if(a.workdir)try{let d=Dy("git",["rev-parse","--show-toplevel"],{cwd:a.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();d&&i.add(hu(d,".worktrees"))}catch{}if(i.size===0)return;let l=0;for(let a of i)try{let d=_y(a);for(let u of d){if(!u.startsWith("openclaw-worktree-"))continue;let c=hu(a,u);try{let m=$y(c);if(!m.isDirectory()||m.mtimeMs>r||o.has(c))continue;Ey(c,{recursive:!0,force:!0}),l++}catch(m){`${c}${m instanceof Error?m.message:String(m)}`}}}catch{}l>0&&`${l}${e}`}function Wy(t){let e=null,n=null,r=!1,o=!1,i=t.registerTool;kt(t.runtime);let s=c=>{if(r){c&&!o&&(kt(t.runtime,c.config),o=!0);return}let m=t.pluginConfig??{};As(m),c?(kt(t.runtime,c.config),o=!0):(kt(t.runtime),o=!1),e=new Eo(D.maxSessions,D.maxPersistedSessions,{worktreeSummaryProvider:Ad()}),n=new Vr(e),No(e),Lo(n),n.start(),Oy(e),e.bootstrapMaintenanceSchedules(),r=!0},l=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=!1,o=!1,kt(void 0),Lo(null),No(null)},a=(c,m)=>{i(p=>(s(),c(p)),m)},d={...t,registerCommand(c){t.registerCommand({...c,handler:m=>(s(),c.handler(m))})}},u=c=>{let m=Dl(c);t.registerInteractiveHandler({...m,handler:async p=>(s(),m.handler(p))})};a(c=>ka(c),{optional:!1,name:"agent_launch"}),a(c=>za(c),{optional:!1,name:"agent_sessions"}),a(c=>Qa(c),{optional:!1,name:"agent_kill"}),a(c=>kr(c),{optional:!1,name:"agent_output"}),a(c=>tl(c),{optional:!1,name:"agent_respond"}),a(c=>nl(c),{optional:!1,name:"agent_request_plan_approval"}),a(c=>rl(c),{optional:!1,name:"agent_request_worktree_decision"}),a(c=>sl(c),{optional:!1,name:"agent_send_plan_offer"}),a(c=>al(c),{optional:!1,name:"agent_stats"}),a(c=>pl(c),{optional:!1,name:"agent_repo_policy"}),a(c=>Tr(c),{optional:!1,name:"agent_merge"}),a(c=>Sn(c),{optional:!1,name:"agent_pr"}),a(c=>Pl(c),{optional:!1,name:"agent_worktree_cleanup"}),a(c=>wl(c),{optional:!1,name:"agent_worktree_status"}),a(c=>bl(c),{optional:!1,name:"goal_launch"}),a(c=>Al(c),{optional:!1,name:"goal_status"}),a(c=>Il(c),{optional:!1,name:"goal_stop"}),a(c=>xl(c),{optional:!1,name:"goal_edit"}),u("telegram"),u("discord"),Wl(d),Nl(d),Ll(d),Bl(d),Fl(d),ql(d),Kl(d),Vl(d),Gl(d),jl(d),zl(d),t.registerService({id:"openclaw-code-agent",start:s,stop:l})}var wx=gu({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:Wy});export{wx as default,Wy as register};
273
+ `),a=d=>Qi({sessionId:o,sessionName:e.sessionName,taskName:e.name,summary:n,originThreadLine:Gt(i),canonicalStatusDelivered:d});this.dispatchSessionNotification(i,{label:r,idempotencyKey:`goal:${e.id}:${r}:${s?"success":n}`,userMessage:s?l: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?a(!0):void 0,wakeMessageOnNotifyFailed:s?a(!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:ae(),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<Dy?!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 Gt(e)}extractLastOutputLine(e){return e.getOutput(3).filter(o=>o.trim()).pop()?.trim()||void 0}getOutputPreview(e,n=1e3){return cu(e,n)}resolvePlanApprovalMode(e){return e.planApproval??D.planApproval??"delegate"}shouldEmitTurnCompleteWake(e){let n=`${e.result?.session_id??""}|${e.result?.num_turns??0}|${e.result?.duration_ms??0}`;return this.lastTurnCompleteMarkers.get(e.id)===n?(`${e.id}${n}`,!1):(this.lastTurnCompleteMarkers.set(e.id,n),!0)}shouldEmitTerminalWake(e){let n=`${e.status}|${e.completedAt??0}|${e.result?.session_id??""}|${e.result?.num_turns??0}|${e.killReason}`;return this.lastTerminalWakeMarkers.get(e.id)===n?!1:(this.lastTerminalWakeMarkers.set(e.id,n),!0)}resolve(e){return this.references.resolveActive(e)}get(e){return this.registry.get(e)}list(e){let n=this.registry.list();return e&&e!=="all"&&(n=n.filter(r=>r.status===e)),n.sort((r,o)=>o.startedAt-r.startedAt)}kill(e,n){let r=this.registry.get(e);if(!r)return!1;if(r.pendingPlanApproval){this.clearPlanDecisionTokens(r.id);let o={lifecycle:"terminal",runtimeState:"stopped",pendingPlanApproval:!1,planApprovalContext:void 0,approvalState:r.approvalState==="pending"?"rejected":r.approvalState,planDecisionVersion:(r.planDecisionVersion??0)+1,actionablePlanDecisionVersion:void 0,canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:void 0,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",approvalPromptTransport:"none",approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:void 0};r.applyControlPatch(o),Object.assign(r,o),this.updatePersistedSession(r.id,o)}return r.kill(n??"user"),!0}killAll(e="user"){for(let n of this.sessions.values())Ey.has(n.status)&&this.kill(n.id,e)}resolveBackendConversationId(e){return this.references.resolveBackendConversationId(e)}resolveHarnessSessionId(e){return this.resolveBackendConversationId(e)}getPersistedSession(e){return this.references.getPersistedSession(e)}isAlreadyMerged(e){if(!e)return!1;let n=this.store.getPersistedSession(e);return n?.worktreeMerged===!0||n?.worktreeLifecycle?.state==="merged"||n?.worktreeLifecycle?.state==="released"}async enqueueMerge(e,n,r){return this.mergeQueue.enqueue(e,n,r)}updatePersistedSession(e,n){let r=this.stateSync.applySessionPatch(e,n);return r&&this.onPersistedSessionChanged(this.store.getPersistedSession(e)),r}listPersistedSessions(){return this.store.listPersistedSessions()}async handleAskUserQuestion(e,n){let r=this.sessions.get(e);if(!r)throw new Error(`Session "${e}" not found for AskUserQuestion intercept`);return this.questions.handleAskUserQuestion(r,n)}resolveAskUserQuestion(e,n,r={}){return this.questions.resolveAskUserQuestion(e,n,r)}async resolvePendingInputOption(e,n,r={}){let o=this.sessions.get(e);return o?.canSubmitPendingInputOption?.()?await o.submitPendingInputOption(n,r)?(this.clearWaitingTimestampsForSession(e),!0):!1:this.questions.resolveAskUserQuestion(e,n,r)}dispose(){this.disposeMaintenance(),this.questions.dispose(),this.notifications.dispose()}};L();ie();import{definePluginEntry as yu}from"openclaw/plugin-sdk/plugin-entry";function qy(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(a=>a.worktreePath).filter(a=>typeof a=="string"&&a.length>0)),i=new Set,s=process.env.OPENCLAW_WORKTREE_DIR??D.worktreeDir;if(s)i.add(s);else for(let a of t.listPersistedSessions())if(a.workdir)try{let d=Fy("git",["rev-parse","--show-toplevel"],{cwd:a.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();d&&i.add(ku(d,".worktrees"))}catch{}if(i.size===0)return;let l=0;for(let a of i)try{let d=Ny(a);for(let u of d){if(!u.startsWith("openclaw-worktree-"))continue;let c=ku(a,u);try{let m=Ly(c);if(!m.isDirectory()||m.mtimeMs>r||o.has(c))continue;By(c,{recursive:!0,force:!0}),l++}catch(m){`${c}${m instanceof Error?m.message:String(m)}`}}}catch{}l>0&&`${l}${e}`}function Ky(t){let e=null,n=null,r=!1,o=!1,i=t.registerTool;kt(t.runtime);let s=c=>{if(r){c&&!o&&(kt(t.runtime,c.config),o=!0);return}let m=t.pluginConfig??{};Is(m),c?(kt(t.runtime,c.config),o=!0):(kt(t.runtime),o=!1),e=new Eo(D.maxSessions,D.maxPersistedSessions,{worktreeSummaryProvider:xd()}),n=new Vr(e),No(e),Lo(n),n.start(),qy(e),e.bootstrapMaintenanceSchedules(),r=!0},l=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=!1,o=!1,kt(void 0),Lo(null),No(null)},a=(c,m)=>{i(p=>(s(),c(p)),m)},d={...t,registerCommand(c){t.registerCommand({...c,handler:m=>(s(),c.handler(m))})}},u=c=>{let m=Wl(c);t.registerInteractiveHandler({...m,handler:async p=>(s(),m.handler(p))})};a(c=>va(c),{optional:!1,name:"agent_launch"}),a(c=>Ja(c),{optional:!1,name:"agent_sessions"}),a(c=>Ya(c),{optional:!1,name:"agent_kill"}),a(c=>kr(c),{optional:!1,name:"agent_output"}),a(c=>rl(c),{optional:!1,name:"agent_respond"}),a(c=>ol(c),{optional:!1,name:"agent_request_plan_approval"}),a(c=>il(c),{optional:!1,name:"agent_request_worktree_decision"}),a(c=>ll(c),{optional:!1,name:"agent_send_plan_offer"}),a(c=>dl(c),{optional:!1,name:"agent_stats"}),a(c=>fl(c),{optional:!1,name:"agent_repo_policy"}),a(c=>Tr(c),{optional:!1,name:"agent_merge"}),a(c=>Sn(c),{optional:!1,name:"agent_pr"}),a(c=>bl(c),{optional:!1,name:"agent_worktree_cleanup"}),a(c=>Rl(c),{optional:!1,name:"agent_worktree_status"}),a(c=>Al(c),{optional:!1,name:"goal_launch"}),a(c=>xl(c),{optional:!1,name:"goal_status"}),a(c=>Tl(c),{optional:!1,name:"goal_stop"}),a(c=>Cl(c),{optional:!1,name:"goal_edit"}),u("telegram"),u("discord"),Ll(d),Bl(d),Fl(d),ql(d),Kl(d),Ul(d),Vl(d),jl(d),Hl(d),zl(d),Jl(d),t.registerService({id:"openclaw-code-agent",start:s,stop:l})}var Tx=yu({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:Ky});export{Tx as default,Ky as register};