openclaw-code-agent 4.7.4 → 4.7.5

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
@@ -3,14 +3,14 @@ var Yc=Object.defineProperty;var J=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(
3
3
  `)}function je(t,e,n){return za(t,e,n).join(`
4
4
  `)}var Pn=J(()=>{});function Vt(t){return{type:"backend_ref",ref:t}}function jt(t){return{type:"run_started",...t?{runId:t}:{}}}function St(t){return{type:"text_delta",text:t}}function cr(t,e){return{type:"tool_call",name:t,input:e}}function Le(t){return{type:"pending_input",state:t}}function dt(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function pr(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function Gt(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function Ge(t){return{type:"run_completed",data:t}}var at,mr=J(()=>{at=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 gr from"@anthropic-ai/claude-agent-sdk";function nm(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
5
  `)}}function rm(t,e,n){let r=Kt(n),o=r.length>0?0:void 0,i=o!=null?r[o]:void 0,s=i?.options.map(d=>d.label)??[],a=i?je(i,o,r.length):ur(r);return{requestId:`${t||"claude"}-ask-${e}`,kind:"question",promptText:a,options:s,...r.length>0?{questions:r}:{},...o!=null?{activeQuestionIndex:o}:{},allowsFreeText:i?.allowsFreeText===!0||s.length===0}}var fr,Qa=J(()=>{Pn();mr();fr=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 at,r=!1,o="",i=!1,s=0,a=e.resumeSessionId??"",d=e.canUseTool,l={cwd:e.cwd,model:e.model,...e.reasoningEffort?{effort:e.reasoningEffort}:{},permissionMode:e.permissionMode,allowDangerouslySkipPermissions:!0,allowedTools:e.allowedTools,systemPrompt:e.systemPrompt,includePartialMessages:!0,abortController:e.abortController,mcpServers:e.mcpServers,...d?{canUseTool:async(m,c)=>{if(m!=="AskUserQuestion")return{behavior:"allow"};let h=rm(a,++s,c);n.enqueue(Le(h));try{let S=await d(m,c);return n.enqueue(dt(h.requestId)),S}catch(S){throw n.enqueue(dt(h.requestId)),S}}}:{}};e.resumeSessionId&&(l.resume=e.resumeSessionId,l.forkSession=e.forkSession??!1);let u=e.prompt,f=this.deps.query??gr.query,p=this.deps.startup??gr.startup,k=(async()=>{if(typeof p!="function")return f({prompt:u,options:l});let m=await p({options:l});try{return m.query(u)}catch(c){throw await m.close?.(),c}})();return(async()=>{try{let m=await k;for await(let c of m){let h=c;if(h.type==="system"&&h.subtype==="init"){a=h.session_id??a,n.enqueue(Vt({kind:"claude-code",conversationId:a}));continue}if(h.type==="system"&&h.subtype==="status"&&h.permissionMode){n.enqueue(Gt(h.permissionMode));continue}if(h.type==="assistant"){r||(r=!0,n.enqueue(jt()));for(let S of h.message?.content??[]){if(S.type==="text"){o+=o?`
6
- ${S.text}`:S.text,n.enqueue(St(S.text));continue}S.type==="tool_use"&&((S.name==="ExitPlanMode"||S.name==="set_permission_mode")&&(i=!0),S.name!=="AskUserQuestion"&&n.enqueue(cr(S.name,S.input)))}continue}if(h.type==="result"){let S=o.trim();if(S&&(e.permissionMode==="plan"||i)){let b={explanation:void 0,steps:[],markdown:S};n.enqueue(pr(b,!0))}n.enqueue(Ge({success:h.subtype==="success",duration_ms:h.duration_ms??0,total_cost_usd:h.total_cost_usd??0,num_turns:h.num_turns??0,result:nm(h),session_id:h.session_id??a})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(m=>{n.enqueue(Ge({success:!1,duration_ms:0,total_cost_usd:0,num_turns:0,result:m instanceof Error?m.message:String(m),session_id:a})),n.close()}),{messages:n.messages(),async setPermissionMode(m){let c=await k;typeof c.setPermissionMode=="function"&&await c.setPermissionMode(m)},async streamInput(m){let c=await k;typeof c.streamInput=="function"&&await c.streamInput(m)},async interrupt(){let m=await k;typeof m.interrupt=="function"&&await m.interrupt()}}}buildUserMessage(e,n){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:n}}}});import{spawn as om}from"node:child_process";import im from"node:readline";function Ja(t){return t instanceof Error?t.message:String(t)}function Ht(t,e){JSON.stringify({component:"CodexAppServerRpc",event:t,at:new Date().toISOString(),...e})}function sm(t,e){return{commandKind:t==="codex"?"codex":"custom",appServerSubcommand:!0,configuredArgCount:e.length}}function am(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function dm(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:Ja(r)}})}}}function ji(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 hr,Ya=J(()=>{hr=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=om(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(Ht("process.spawn",{...sm(this.command,this.args),pid:e.pid,requestTimeoutMs:this.requestTimeoutMs}),!e.stdin||!e.stdout||!e.stderr)throw new Error("codex app server stdio pipes unavailable");this.process=e,im.createInterface({input:e.stdout}).on("line",r=>{this.handleLine(r)}),e.stderr.on("data",r=>{this.stderrTail=`${this.stderrTail}${r.toString("utf8")}`.slice(-4e3)}),e.on("error",r=>{Ht("process.error",{pid:e.pid,error:Ja(r)})}),e.on("close",(r,o)=>{Ht("process.close",{pid:e.pid,code:r,signal:o,pendingRequests:this.pending.size,recentStderr:ji(this.stderrTail.trim())}),this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){Ht("client.close",{pid:this.process?.pid,pendingRequests:this.pending.size}),this.flushPending(new Error("codex app server stdio closed"));let e=this.process;this.process=null,e&&e.kill()}async notify(e,n){this.write({jsonrpc:"2.0",method:e,params:n??{}})}async request(e,n,r){let o=`rpc-${++this.counter}`,i=new Promise((s,a)=>{let d=Math.max(100,r??this.requestTimeoutMs),l=setTimeout(()=>{this.pending.delete(o),Ht("request.timeout",{id:o,method:e,timeoutMs:d,pid:this.process?.pid,recentStderr:ji(this.stderrTail.trim())}),a(new Error(this.buildTimeoutErrorMessage(e,d)))},d);l.unref?.(),this.pending.set(o,{resolve:s,reject:a,timer:l})});return this.write({jsonrpc:"2.0",id:o,method:e,params:n??{}}),await i}write(e){if(!this.process?.stdin)throw new Error("codex app server stdio not connected");this.process.stdin.write(`${JSON.stringify(e)}
7
- `)}async handleLine(e){let n=am(e);n&&await dm(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){this.pending.size>0&&Ht("pending.flush",{pendingRequests:this.pending.size,error:e.message,pid:this.process?.pid});for(let[n,r]of this.pending)clearTimeout(r.timer),r.reject(e),this.pending.delete(n)}buildTimeoutErrorMessage(e,n){let r=this.stderrTail.trim(),o=r?`; recent stderr: ${ji(r)}`:"";return`codex app server timeout after ${n}ms: ${e}${o}`}}});function Za(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>n.includes(r.toLowerCase()))}var Xa=J(()=>{});function He(t,e){let n=e?.trim();if(!n)return;if(t!=="codex")return n;let[r,...o]=n.split("/");return r?.toLowerCase()==="openai"&&o.length===1&&o[0]?.trim()?o[0].trim():n}function lm(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>He("codex",r)?.toLowerCase()===n)}function yr(t,e,n){return t==="codex"?lm(e,n):Za(e,n)}function zt(t,e){return t!=="codex"||!e?!0:!e.includes("/")}function kr(t,e,n){if(t!=="codex"||!e||!n||n.length===0)return e;let r=e.toLowerCase(),o=n.find(i=>He("codex",i)?.toLowerCase()===r);return He("codex",o)??e}var Sr=J(()=>{Xa()});function um(t){return t instanceof Error?t.message:String(t)}function ed(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function lt(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>lt(n)).join("");let e=j(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=lt(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=lt(e[n]);if(r)return r}return""}function bn(t){let e=j(t);if(!e)return{};let n=j(e.thread)??j(e.session),r=j(e.turn)??j(e.run),o=j(e.item),i=j(e.serverRequest);return{threadId:H(e,["threadId","thread_id","conversationId","conversation_id"])??H(n,["id","threadId","thread_id","conversationId"]),runId:H(e,["turnId","turn_id","runId","run_id"])??H(r,["id","turnId","turn_id","runId","run_id"]),requestId:H(e,["requestId","request_id","serverRequestId"])??H(i,["id","requestId","request_id"]),itemId:H(e,["itemId","item_id"])??H(o,["id","itemId","item_id"])}}function vr(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=vr(i,e,n+1);if(s)return s}return}let r=j(t);if(!r)return;let o=H(r,e);if(o)return o;for(let i of Object.values(r)){let s=vr(i,e,n+1);if(s)return s}}function Rn(t){return{threadId:bn(t).threadId,cwd:vr(t,["cwd","workdir","directory"])}}function td(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function nd(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 wr(t){let e=j(t);if(!e)return;let n=j(e.item)??e;return H(n,["id","itemId","item_id","messageId","message_id"])}function cm(t,e=!1){let n=j(t);if(!n)return"";let r=j(n.item)??n;return H(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?lt(r):H(r,["text"],{trim:!1})??lt(r)}function rd(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:lt(e),itemId:wr(e)}:n==="item/completed"?{mode:"snapshot",text:cm(e),itemId:wr(e)}:{mode:"ignore",text:""}}function od(t){return{itemId:wr(t),delta:lt(t)}}function id(t){let e=j(t),n=j(e?.plan),o=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(i=>{let s=j(i),a=H(s,["step","title","text"]);if(!a)return null;let d=H(s,["status"])?.toLowerCase()??"pending";return{step:a,status:d==="inprogress"||d==="in_progress"?"inProgress":d==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:H(n,["explanation"])??H(e,["explanation"]),steps:o}}function sd(t){let e=j(t);if(!e)return{};let n=j(e.item)??e;return H(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:wr(n),text:H(n,["text"],{trim:!1})??lt(n)}}function ad(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=j(e)??{},o=j(r.turn)??r,i=H(o,["status"])?.toLowerCase();return i==="failed"?"failed":i==="interrupted"||i==="cancelled"?"interrupted":"completed"}function dd(t,e){let n=j(e)??{},r=j(n.turn)??n,o=j(r.error)??j(n.error);if(o)return H(o,["message","text","summary","reason"])}function pm(t,e){let n=um(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 fm(t){return mm.has(t.trim().toLowerCase())}function gm(t){let e=j(t);return e?!!H(e,["threadId","thread_id"]):!1}async function An(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(fm(n)&&!gm(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,!pm(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function ld(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 ud(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 hm(t){return[{type:"text",text:t}]}function ym(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 cd(t){let e={threadId:t.threadId,input:hm(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=ym(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function pd(t){return[{threadId:t.threadId,turnId:t.turnId}]}function km(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 md(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=Kt(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let a=o?lr(n):[],d=s.length>0?0:void 0,l=d!=null?s[d]:void 0,u=l?l.options:[],p=(o&&u.length===0?a:u).map(c=>c.label),k=(l?je(l,d??0,s.length):ur(s))??(o?vr(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,m=o?p.map(c=>({kind:"approval",label:c,decision:km(c),responseDecision:c})):p.map(c=>({kind:"option",label:c,value:c}));return{requestId:e,kind:o?"approval":"question",promptText:k,options:p,...s.length>0?{questions:s}:{},...d!=null?{activeQuestionIndex:d}:{},actions:m,allowsFreeText:!0}}function fd(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function Gi(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var mm,gd=J(()=>{Pn();mm=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function Rm(t){let e=t?.trim();return e&&bm.test(e)?e:void 0}function Am(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return Hi;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:Hi}function In(t){return t instanceof Error?t.message:String(t)}function Ce(t,e){JSON.stringify({component:"CodexHarness",event:t,at:new Date().toISOString(),...e})}function Im(t){return{commandKind:t.command==="codex"?"codex":"custom",configuredArgCount:t.args.length,requestTimeoutMs:t.requestTimeoutMs}}function ze(t){return{hasThreadId:!!t.threadId,hasTurnId:!!t.turnId,hasBackendWorktreePath:!!t.backendWorktreePath,hasBackendWorktreeId:!!t.backendWorktreeId}}function xm(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 yd(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:je(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}function Tm(t){if(t===void 0)return hd;let e=ed(t);return e.length>0?e:hd}var Sm,Hi,hd,vm,wm,Pm,bm,Pr,kd=J(()=>{Ya();mr();Pn();Sr();gd();Sm="1.0",Hi=12e4,hd=["--listen","stdio://"],vm="OPENCLAW_CODEX_APP_SERVER_COMMAND",wm="OPENCLAW_CODEX_APP_SERVER_ARGS",Pm="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS",bm=/^(?: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}$/;Pr=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[vm]?.trim()||"codex",args:Tm(process.env[wm]),requestTimeoutMs:Am(process.env[Pm])},r=this.deps.createClient?.(n)??new hr(n.command,n.args,n.requestTimeoutMs),o=new at,i=Rm(e.resumeSessionId);e.resumeSessionId;let s,a=e.backendRef?.worktreePath,d=e.backendRef?.worktreeId,l=e.permissionMode??"default",u=He(this.name,e.model);if(!zt(this.name,u))throw new Error(`Codex model "${e.model}" is not supported. Use a bare Codex model id such as "gpt-5.6-sol".`);let f,p=0,k="",m=[],c,h=new Map,S=new Set,b=W=>{let I=W?.trim();if(!I)return;let R=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&I!==R&&td(I)&&(a=I,d=nd(I))},x=()=>{i&&o.enqueue(Vt({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...d?{worktreeId:d}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async(W,I)=>{let R=W.trim().toLowerCase(),_=bn(I),q=Rn(I);if(_.threadId&&i&&_.threadId!==i)return;if(_.threadId&&(i=_.threadId),_.runId&&(s=_.runId),b(q.cwd),(_.threadId||_.runId||q.cwd)&&x(),R==="serverrequest/resolved"){f&&(o.enqueue(dt(f.requestId)),f=void 0);return}if(R==="turn/plan/updated"){let F=id(I);k=F.explanation??k,F.steps.length>0&&(m=F.steps);return}if(R==="item/plan/delta"){let F=od(I);if(F.itemId&&F.delta){let Q=h.get(F.itemId)??"";h.set(F.itemId,`${Q}${F.delta}`)}return}if(R==="item/completed"){let F=sd(I);if(F.text?.trim()){let Q={explanation:k||void 0,steps:m,markdown:F.text.trim()};o.enqueue(pr(Q,!0));return}}let N=rd(R,I);if(N.mode==="delta"&&N.text){N.itemId&&S.add(N.itemId),o.enqueue(St(N.text));return}N.mode==="snapshot"&&N.text&&(!N.itemId||!S.has(N.itemId))&&o.enqueue(St(N.text)),(R==="turn/completed"||R==="turn/failed"||R==="turn/cancelled")&&c&&(c.method=W,c.params=I,c.resolve())}),r.setRequestHandler(async(W,I)=>{if(!fd(W))return{};let R=bn(I),_=Rn(I);if(R.threadId&&i&&R.threadId!==i)return{};R.threadId&&(i=R.threadId),R.runId&&(s=R.runId),b(_.cwd),(R.threadId||R.runId||_.cwd)&&x();let q=R.requestId??`${i??"codex"}-${Date.now().toString(36)}`,N;try{N=md(W,q,I)}catch(cn){let pn=In(cn);return`${pn}`,{error:pn}}let F=W.trim().toLowerCase(),Q=N.options,Y=N.actions??[],gt=await new Promise(cn=>{f={requestId:q,methodLower:F,state:N,options:Q,actions:Y,answers:{...N.answers??{}},resolveResponse:cn},o.enqueue(Le(N))});return f=void 0,o.enqueue(dt(q)),gt});let T=async()=>{Ce("client.initialize.start",{...Im(n),hasResumeSessionId:!!e.resumeSessionId}),await r.connect(),await r.request("initialize",{protocolVersion:Sm,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},n.requestTimeoutMs),await r.notify("initialized",{}),Ce("client.initialize.done",{hasResumeSessionId:!!e.resumeSessionId})},A=async()=>{let W=Gi(l,e.codexApprovalPolicy);if(i){Ce("thread.resume.start",ze({threadId:i}));let _=await An({client:r,methods:["thread/resume"],payloads:ud({threadId:i,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),q=Rn(_);i=q.threadId??i,b(q.cwd),x(),Ce("thread.resume.done",{...ze({threadId:i,backendWorktreePath:a,backendWorktreeId:d})});return}Ce("thread.start.start",{hasCwd:!!e.cwd});let I=await An({client:r,methods:["thread/start","thread/new"],payloads:ld({cwd:e.cwd,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),R=Rn(I);if(i=R.threadId,!i)throw new Error("Codex App Server did not return a thread id.");b(R.cwd),x(),Ce("thread.start.done",{...ze({threadId:i,backendWorktreePath:a,backendWorktreeId:d})})},y=async W=>{await A(),Ce("turn.start",{...ze({threadId:i}),runCounter:p+1,promptChars:W.length,permissionMode:l}),o.enqueue(jt()),p+=1,k="",m=[],h.clear(),S.clear();let I="",R,_,q=new Promise(N=>{_=N});c={resolve:_};try{let N=Gi(l,e.codexApprovalPolicy),F=await An({client:r,methods:["turn/start"],payloads:cd({threadId:i,prompt:W,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:l,approvalPolicy:N.approvalPolicy,sandbox:N.sandbox}),timeoutMs:n.requestTimeoutMs}),Q=bn(F);Q.runId&&(s=Q.runId,x()),await q,I=c?.method??"turn/failed",R=c?.params;let Y=ad(I,R);Ce("turn.terminal",{...ze({threadId:i,turnId:s}),terminalMethod:I,outcome:Y}),o.enqueue(Ge({success:Y==="completed",outcome:Y,duration_ms:0,total_cost_usd:0,num_turns:p,result:dd(I,R),session_id:i}))}catch(N){Ce("turn.error",{...ze({threadId:i,turnId:s}),error:In(N)}),o.enqueue(Ge({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:In(N),session_id:i??""}))}finally{c=void 0}},w=async W=>{let I=f;if(!I)return!1;let R=W.trim();if(I.methodLower.includes("requestapproval"))return I.resolveResponse({decision:R||"decline"}),!0;let _=I.state.questions??[];if(_.length>0){if(!R)return!1;let q=I.state.activeQuestionIndex??0,N=_[q];if(!N)return!1;I.answers={...I.answers,[N.id]:{answers:[R]}};let F=q+1;if(F<_.length)return I.state=yd(I.state,F,I.answers),I.options=I.state.options,o.enqueue(Le(I.state)),!0;I.resolveResponse({answers:I.answers})}else I.resolveResponse({text:R});return!0},L=async(W,I={})=>{let R=f;if(!R||I.requestId&&I.requestId!==R.state.requestId)return!1;let _=R.actions[W];if(_?.kind==="approval")return R.resolveResponse({decision:_.responseDecision,..._.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:_.proposedExecpolicyAmendment}:{}}),!0;let q=R.state.questions??[],N=R.state.activeQuestionIndex??0,F=q.length>0?q[N]:void 0;if(I.questionId&&I.questionId!==F?.id)return!1;let Q=F?.options[W];if(F&&Q){R.answers={...R.answers,[F.id]:{answers:[Q.value??Q.label]}};let gt=N+1;return gt<q.length?(R.state=yd(R.state,gt,R.answers),R.options=R.state.options,o.enqueue(Le(R.state)),!0):(R.resolveResponse({answers:R.answers}),!0)}let Y=R.options[W];return Y?(R.methodLower.includes("requestapproval")?R.resolveResponse({decision:Y}):R.resolveResponse({option:Y,index:W}),!0):!1},K=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{await T();for await(let W of K){let I=xm(W).trim();!I||await w(I)||await y(I)}}catch(W){Ce("session.error",{...ze({threadId:i,turnId:s}),error:In(W)}),o.enqueue(Ge({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:In(W),session_id:i??e.resumeSessionId??""}))}finally{Ce("client.close.start",ze({threadId:i,turnId:s})),await r.close().catch(()=>{}),Ce("client.close.done",ze({threadId:i,turnId:s})),o.close()}})(),{messages:o.messages(),async setPermissionMode(W){l=W,o.enqueue(Gt(W))},async submitPendingInputOption(W,I){return L(W,I)},async submitPendingInputText(W){return w(W)},async interrupt(){!i||!s||await An({client:r,methods:["turn/interrupt"],payloads:pd({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as Cm}from"node:child_process";import{constants as Mm,accessSync as _m}from"node:fs";import{createServer as $m}from"node:net";import{delimiter as Em,dirname as zi,join as wd,sep as Dm}from"node:path";function Jt(t){return t instanceof Error?t.message:String(t)}function Bm(t){try{return _m(t,Mm.X_OK),!0}catch{return!1}}function Fm(t){return t.includes("/")||Dm==="\\"&&t.includes("\\")}function qm(t){let e=(t??"").split(Em).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(wd(zi(zi(zi(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function Um(t,e=process.env.PATH){if(Fm(t))return t;for(let n of qm(e)){let r=wd(n,t);if(Bm(r))return r}return t}function de(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Km(t){if(typeof t=="string")return t;if(!de(t))return String(t);if(typeof t.text=="string")return t.text;let e=de(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function Pd(t){let e=t?.trim();if(!e)return;let n=e.indexOf("/");if(!(n<=0||n===e.length-1))return{providerID:e.slice(0,n),modelID:e.slice(n+1)}}function Vm(t){let e=Pd(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function Sd(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return Lm.map(r=>({permission:r,pattern:"*",action:n}))}function Qi(){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 jm(){return new Promise((t,e)=>{let n=$m();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 bd(t){await new Promise(e=>setTimeout(e,t))}async function br(t,e){if(e.signal?.aborted)throw new Error(e.abortMessage??"Operation was aborted.");return await new Promise((n,r)=>{let o=!1,i=()=>{clearTimeout(d),e.signal?.removeEventListener("abort",a)},s=l=>{o||(o=!0,i(),l())},a=()=>{s(()=>r(new Error(e.abortMessage??"Operation was aborted.")))},d=setTimeout(()=>{s(()=>{e.onTimeout?.(),r(new Error(e.timeoutMessage))})},e.timeoutMs);e.signal?.addEventListener("abort",a,{once:!0}),t.then(l=>s(()=>n(l)),l=>s(()=>r(l)))})}async function Qt(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 Gm(t){return t.headers.get("content-type")?.toLowerCase()??""}function Yi(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function Hm(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function zm(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=Yi(r),s=Hm(n,r)?" (looks like the OpenCode web UI HTML app shell)":"";return`OpenCode ${t} ${e} expected JSON API response but received ${o}${s}${i?`: ${i}`:""}`}function Qm(t,e,n){let r=Pd(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function Jm(t,e){if(!de(t))return!1;if(!(e in t))return!0;let n=t[e];return de(n)&&n.type==="idle"}function Ym(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function Zm(t){return new Promise((e,n)=>{vd=vd.then(()=>t().then(e,n)).catch(()=>{})})}async function Xm(t){return Zm(async()=>{let e=await jm(),n=process.env[Om]?.trim()||"opencode",r=Um(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??es,1e4),a=t.startupTimeoutMs??Nm,d=Cm(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),l=`http://127.0.0.1:${e}`,u="",f="",p,k=(S,b)=>{let x=S+String(b);return x.length>8e3?x.slice(-8e3):x};d.stdout.on("data",S=>{u=k(u,S)}),d.stderr.on("data",S=>{f=k(f,S)}),d.once("error",S=>{p=S});let m=()=>` Command: ${n===r?r:`${r} (resolved from ${n})`} ${o.join(" ")}. Cwd: ${t.cwd}. Port: ${e}. PATH: ${process.env.PATH??""}.`,c=()=>{let S=[u.trim(),f.trim()].filter(Boolean).join(`
6
+ ${S.text}`:S.text,n.enqueue(St(S.text));continue}S.type==="tool_use"&&((S.name==="ExitPlanMode"||S.name==="set_permission_mode")&&(i=!0),S.name!=="AskUserQuestion"&&n.enqueue(cr(S.name,S.input)))}continue}if(h.type==="result"){let S=o.trim();if(S&&(e.permissionMode==="plan"||i)){let P={explanation:void 0,steps:[],markdown:S};n.enqueue(pr(P,!0))}n.enqueue(Ge({success:h.subtype==="success",duration_ms:h.duration_ms??0,total_cost_usd:h.total_cost_usd??0,num_turns:h.num_turns??0,result:nm(h),session_id:h.session_id??a})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(m=>{n.enqueue(Ge({success:!1,duration_ms:0,total_cost_usd:0,num_turns:0,result:m instanceof Error?m.message:String(m),session_id:a})),n.close()}),{messages:n.messages(),async setPermissionMode(m){let c=await k;typeof c.setPermissionMode=="function"&&await c.setPermissionMode(m)},async streamInput(m){let c=await k;typeof c.streamInput=="function"&&await c.streamInput(m)},async interrupt(){let m=await k;typeof m.interrupt=="function"&&await m.interrupt()}}}buildUserMessage(e,n){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:n}}}});import{spawn as om}from"node:child_process";import im from"node:readline";function Ja(t){return t instanceof Error?t.message:String(t)}function Ht(t,e){JSON.stringify({component:"CodexAppServerRpc",event:t,at:new Date().toISOString(),...e})}function sm(t,e){return{commandKind:t==="codex"?"codex":"custom",appServerSubcommand:!0,configuredArgCount:e.length}}function am(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function dm(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:Ja(r)}})}}}function ji(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 hr,Ya=J(()=>{hr=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=om(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(Ht("process.spawn",{...sm(this.command,this.args),pid:e.pid,requestTimeoutMs:this.requestTimeoutMs}),!e.stdin||!e.stdout||!e.stderr)throw new Error("codex app server stdio pipes unavailable");this.process=e,im.createInterface({input:e.stdout}).on("line",r=>{this.handleLine(r)}),e.stderr.on("data",r=>{this.stderrTail=`${this.stderrTail}${r.toString("utf8")}`.slice(-4e3)}),e.on("error",r=>{Ht("process.error",{pid:e.pid,error:Ja(r)})}),e.on("close",(r,o)=>{Ht("process.close",{pid:e.pid,code:r,signal:o,pendingRequests:this.pending.size,recentStderr:ji(this.stderrTail.trim())}),this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){Ht("client.close",{pid:this.process?.pid,pendingRequests:this.pending.size}),this.flushPending(new Error("codex app server stdio closed"));let e=this.process;this.process=null,e&&e.kill()}async notify(e,n){this.write({jsonrpc:"2.0",method:e,params:n??{}})}async request(e,n,r){let o=`rpc-${++this.counter}`,i=new Promise((s,a)=>{let d=Math.max(100,r??this.requestTimeoutMs),l=setTimeout(()=>{this.pending.delete(o),Ht("request.timeout",{id:o,method:e,timeoutMs:d,pid:this.process?.pid,recentStderr:ji(this.stderrTail.trim())}),a(new Error(this.buildTimeoutErrorMessage(e,d)))},d);l.unref?.(),this.pending.set(o,{resolve:s,reject:a,timer:l})});return this.write({jsonrpc:"2.0",id:o,method:e,params:n??{}}),await i}write(e){if(!this.process?.stdin)throw new Error("codex app server stdio not connected");this.process.stdin.write(`${JSON.stringify(e)}
7
+ `)}async handleLine(e){let n=am(e);n&&await dm(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){this.pending.size>0&&Ht("pending.flush",{pendingRequests:this.pending.size,error:e.message,pid:this.process?.pid});for(let[n,r]of this.pending)clearTimeout(r.timer),r.reject(e),this.pending.delete(n)}buildTimeoutErrorMessage(e,n){let r=this.stderrTail.trim(),o=r?`; recent stderr: ${ji(r)}`:"";return`codex app server timeout after ${n}ms: ${e}${o}`}}});function Za(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>n.includes(r.toLowerCase()))}var Xa=J(()=>{});function He(t,e){let n=e?.trim();if(!n)return;if(t!=="codex")return n;let[r,...o]=n.split("/");return r?.toLowerCase()==="openai"&&o.length===1&&o[0]?.trim()?o[0].trim():n}function lm(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>He("codex",r)?.toLowerCase()===n)}function yr(t,e,n){return t==="codex"?lm(e,n):Za(e,n)}function zt(t,e){return t!=="codex"||!e?!0:!e.includes("/")}function kr(t,e,n){if(t!=="codex"||!e||!n||n.length===0)return e;let r=e.toLowerCase(),o=n.find(i=>He("codex",i)?.toLowerCase()===r);return He("codex",o)??e}var Sr=J(()=>{Xa()});function um(t){return t instanceof Error?t.message:String(t)}function ed(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function lt(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>lt(n)).join("");let e=j(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=lt(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=lt(e[n]);if(r)return r}return""}function bn(t){let e=j(t);if(!e)return{};let n=j(e.thread)??j(e.session),r=j(e.turn)??j(e.run),o=j(e.item),i=j(e.serverRequest);return{threadId:H(e,["threadId","thread_id","conversationId","conversation_id"])??H(n,["id","threadId","thread_id","conversationId"]),runId:H(e,["turnId","turn_id","runId","run_id"])??H(r,["id","turnId","turn_id","runId","run_id"]),requestId:H(e,["requestId","request_id","serverRequestId"])??H(i,["id","requestId","request_id"]),itemId:H(e,["itemId","item_id"])??H(o,["id","itemId","item_id"])}}function vr(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=vr(i,e,n+1);if(s)return s}return}let r=j(t);if(!r)return;let o=H(r,e);if(o)return o;for(let i of Object.values(r)){let s=vr(i,e,n+1);if(s)return s}}function Rn(t){return{threadId:bn(t).threadId,cwd:vr(t,["cwd","workdir","directory"])}}function td(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function nd(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 wr(t){let e=j(t);if(!e)return;let n=j(e.item)??e;return H(n,["id","itemId","item_id","messageId","message_id"])}function cm(t,e=!1){let n=j(t);if(!n)return"";let r=j(n.item)??n;return H(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?lt(r):H(r,["text"],{trim:!1})??lt(r)}function rd(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:lt(e),itemId:wr(e)}:n==="item/completed"?{mode:"snapshot",text:cm(e),itemId:wr(e)}:{mode:"ignore",text:""}}function od(t){return{itemId:wr(t),delta:lt(t)}}function id(t){let e=j(t),n=j(e?.plan),o=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(i=>{let s=j(i),a=H(s,["step","title","text"]);if(!a)return null;let d=H(s,["status"])?.toLowerCase()??"pending";return{step:a,status:d==="inprogress"||d==="in_progress"?"inProgress":d==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:H(n,["explanation"])??H(e,["explanation"]),steps:o}}function sd(t){let e=j(t);if(!e)return{};let n=j(e.item)??e;return H(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:wr(n),text:H(n,["text"],{trim:!1})??lt(n)}}function ad(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=j(e)??{},o=j(r.turn)??r,i=H(o,["status"])?.toLowerCase();return i==="failed"?"failed":i==="interrupted"||i==="cancelled"?"interrupted":"completed"}function dd(t,e){let n=j(e)??{},r=j(n.turn)??n,o=j(r.error)??j(n.error);if(o)return H(o,["message","text","summary","reason"])}function pm(t,e){let n=um(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 fm(t){return mm.has(t.trim().toLowerCase())}function gm(t){let e=j(t);return e?!!H(e,["threadId","thread_id"]):!1}async function An(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(fm(n)&&!gm(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,!pm(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function ld(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 ud(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 hm(t){return[{type:"text",text:t}]}function ym(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 cd(t){let e={threadId:t.threadId,input:hm(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=ym(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function pd(t){return[{threadId:t.threadId,turnId:t.turnId}]}function km(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 md(t,e,n){let r=t.trim().toLowerCase(),o=r.includes("requestapproval"),i=r.includes("requestuserinput"),s=Kt(n);if(i&&s.length===0)throw new Error(`Malformed Codex request_user_input payload for ${e}: expected non-empty questions[]`);let a=o?lr(n):[],d=s.length>0?0:void 0,l=d!=null?s[d]:void 0,u=l?l.options:[],p=(o&&u.length===0?a:u).map(c=>c.label),k=(l?je(l,d??0,s.length):ur(s))??(o?vr(n,["question","prompt","message","text","summary","reason"]):void 0)??void 0,m=o?p.map(c=>({kind:"approval",label:c,decision:km(c),responseDecision:c})):p.map(c=>({kind:"option",label:c,value:c}));return{requestId:e,kind:o?"approval":"question",promptText:k,options:p,...s.length>0?{questions:s}:{},...d!=null?{activeQuestionIndex:d}:{},actions:m,allowsFreeText:!0}}function fd(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function Gi(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var mm,gd=J(()=>{Pn();mm=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function Rm(t){let e=t?.trim();return e&&bm.test(e)?e:void 0}function Am(t){let e=t?.trim();if(!e||!/^\d+$/.test(e))return Hi;let n=Number(e);return Number.isSafeInteger(n)&&n>0?n:Hi}function In(t){return t instanceof Error?t.message:String(t)}function Ce(t,e){JSON.stringify({component:"CodexHarness",event:t,at:new Date().toISOString(),...e})}function Im(t){return{commandKind:t.command==="codex"?"codex":"custom",configuredArgCount:t.args.length,requestTimeoutMs:t.requestTimeoutMs}}function ze(t){return{hasThreadId:!!t.threadId,hasTurnId:!!t.turnId,hasBackendWorktreePath:!!t.backendWorktreePath,hasBackendWorktreeId:!!t.backendWorktreeId}}function xm(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 yd(t,e,n){let r=t.questions??[],o=r[e];return o?{...t,promptText:je(o,e,r.length),options:o.options.map(i=>i.label),activeQuestionIndex:e,answers:n}:t}function Tm(t){if(t===void 0)return hd;let e=ed(t);return e.length>0?e:hd}var Sm,Hi,hd,vm,wm,Pm,bm,Pr,kd=J(()=>{Ya();mr();Pn();Sr();gd();Sm="1.0",Hi=12e4,hd=["--listen","stdio://"],vm="OPENCLAW_CODEX_APP_SERVER_COMMAND",wm="OPENCLAW_CODEX_APP_SERVER_ARGS",Pm="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS",bm=/^(?: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}$/;Pr=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[vm]?.trim()||"codex",args:Tm(process.env[wm]),requestTimeoutMs:Am(process.env[Pm])},r=this.deps.createClient?.(n)??new hr(n.command,n.args,n.requestTimeoutMs),o=new at,i=Rm(e.resumeSessionId);e.resumeSessionId;let s,a=e.backendRef?.worktreePath,d=e.backendRef?.worktreeId,l=e.permissionMode??"default",u=He(this.name,e.model);if(!zt(this.name,u))throw new Error(`Codex model "${e.model}" is not supported. Use a bare Codex model id such as "gpt-5.6-sol".`);let f,p=0,k="",m=[],c,h=new Map,S=new Set,P=W=>{let I=W?.trim();if(!I)return;let R=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&I!==R&&td(I)&&(a=I,d=nd(I))},x=()=>{i&&o.enqueue(Vt({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...d?{worktreeId:d}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async(W,I)=>{let R=W.trim().toLowerCase(),_=bn(I),q=Rn(I);if(_.threadId&&i&&_.threadId!==i)return;if(_.threadId&&(i=_.threadId),_.runId&&(s=_.runId),P(q.cwd),(_.threadId||_.runId||q.cwd)&&x(),R==="serverrequest/resolved"){f&&(o.enqueue(dt(f.requestId)),f=void 0);return}if(R==="turn/plan/updated"){let F=id(I);k=F.explanation??k,F.steps.length>0&&(m=F.steps);return}if(R==="item/plan/delta"){let F=od(I);if(F.itemId&&F.delta){let Q=h.get(F.itemId)??"";h.set(F.itemId,`${Q}${F.delta}`)}return}if(R==="item/completed"){let F=sd(I);if(F.text?.trim()){let Q={explanation:k||void 0,steps:m,markdown:F.text.trim()};o.enqueue(pr(Q,!0));return}}let N=rd(R,I);if(N.mode==="delta"&&N.text){N.itemId&&S.add(N.itemId),o.enqueue(St(N.text));return}N.mode==="snapshot"&&N.text&&(!N.itemId||!S.has(N.itemId))&&o.enqueue(St(N.text)),(R==="turn/completed"||R==="turn/failed"||R==="turn/cancelled")&&c&&(c.method=W,c.params=I,c.resolve())}),r.setRequestHandler(async(W,I)=>{if(!fd(W))return{};let R=bn(I),_=Rn(I);if(R.threadId&&i&&R.threadId!==i)return{};R.threadId&&(i=R.threadId),R.runId&&(s=R.runId),P(_.cwd),(R.threadId||R.runId||_.cwd)&&x();let q=R.requestId??`${i??"codex"}-${Date.now().toString(36)}`,N;try{N=md(W,q,I)}catch(cn){let pn=In(cn);return`${pn}`,{error:pn}}let F=W.trim().toLowerCase(),Q=N.options,Y=N.actions??[],gt=await new Promise(cn=>{f={requestId:q,methodLower:F,state:N,options:Q,actions:Y,answers:{...N.answers??{}},resolveResponse:cn},o.enqueue(Le(N))});return f=void 0,o.enqueue(dt(q)),gt});let C=async()=>{Ce("client.initialize.start",{...Im(n),hasResumeSessionId:!!e.resumeSessionId}),await r.connect(),await r.request("initialize",{protocolVersion:Sm,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},n.requestTimeoutMs),await r.notify("initialized",{}),Ce("client.initialize.done",{hasResumeSessionId:!!e.resumeSessionId})},A=async()=>{let W=Gi(l,e.codexApprovalPolicy);if(i){Ce("thread.resume.start",ze({threadId:i}));let _=await An({client:r,methods:["thread/resume"],payloads:ud({threadId:i,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),q=Rn(_);i=q.threadId??i,P(q.cwd),x(),Ce("thread.resume.done",{...ze({threadId:i,backendWorktreePath:a,backendWorktreeId:d})});return}Ce("thread.start.start",{hasCwd:!!e.cwd});let I=await An({client:r,methods:["thread/start","thread/new"],payloads:ld({cwd:e.cwd,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:W.approvalPolicy,sandbox:W.sandbox}),timeoutMs:n.requestTimeoutMs}),R=Rn(I);if(i=R.threadId,!i)throw new Error("Codex App Server did not return a thread id.");P(R.cwd),x(),Ce("thread.start.done",{...ze({threadId:i,backendWorktreePath:a,backendWorktreeId:d})})},y=async W=>{await A(),Ce("turn.start",{...ze({threadId:i}),runCounter:p+1,promptChars:W.length,permissionMode:l}),o.enqueue(jt()),p+=1,k="",m=[],h.clear(),S.clear();let I="",R,_,q=new Promise(N=>{_=N});c={resolve:_};try{let N=Gi(l,e.codexApprovalPolicy),F=await An({client:r,methods:["turn/start"],payloads:cd({threadId:i,prompt:W,model:u,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:l,approvalPolicy:N.approvalPolicy,sandbox:N.sandbox}),timeoutMs:n.requestTimeoutMs}),Q=bn(F);Q.runId&&(s=Q.runId,x()),await q,I=c?.method??"turn/failed",R=c?.params;let Y=ad(I,R);Ce("turn.terminal",{...ze({threadId:i,turnId:s}),terminalMethod:I,outcome:Y}),o.enqueue(Ge({success:Y==="completed",outcome:Y,duration_ms:0,total_cost_usd:0,num_turns:p,result:dd(I,R),session_id:i}))}catch(N){Ce("turn.error",{...ze({threadId:i,turnId:s}),error:In(N)}),o.enqueue(Ge({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:In(N),session_id:i??""}))}finally{c=void 0}},w=async W=>{let I=f;if(!I)return!1;let R=W.trim();if(I.methodLower.includes("requestapproval"))return I.resolveResponse({decision:R||"decline"}),!0;let _=I.state.questions??[];if(_.length>0){if(!R)return!1;let q=I.state.activeQuestionIndex??0,N=_[q];if(!N)return!1;I.answers={...I.answers,[N.id]:{answers:[R]}};let F=q+1;if(F<_.length)return I.state=yd(I.state,F,I.answers),I.options=I.state.options,o.enqueue(Le(I.state)),!0;I.resolveResponse({answers:I.answers})}else I.resolveResponse({text:R});return!0},L=async(W,I={})=>{let R=f;if(!R||I.requestId&&I.requestId!==R.state.requestId)return!1;let _=R.actions[W];if(_?.kind==="approval")return R.resolveResponse({decision:_.responseDecision,..._.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:_.proposedExecpolicyAmendment}:{}}),!0;let q=R.state.questions??[],N=R.state.activeQuestionIndex??0,F=q.length>0?q[N]:void 0;if(I.questionId&&I.questionId!==F?.id)return!1;let Q=F?.options[W];if(F&&Q){R.answers={...R.answers,[F.id]:{answers:[Q.value??Q.label]}};let gt=N+1;return gt<q.length?(R.state=yd(R.state,gt,R.answers),R.options=R.state.options,o.enqueue(Le(R.state)),!0):(R.resolveResponse({answers:R.answers}),!0)}let Y=R.options[W];return Y?(R.methodLower.includes("requestapproval")?R.resolveResponse({decision:Y}):R.resolveResponse({option:Y,index:W}),!0):!1},K=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{await C();for await(let W of K){let I=xm(W).trim();!I||await w(I)||await y(I)}}catch(W){Ce("session.error",{...ze({threadId:i,turnId:s}),error:In(W)}),o.enqueue(Ge({success:!1,duration_ms:0,total_cost_usd:0,num_turns:p,result:In(W),session_id:i??e.resumeSessionId??""}))}finally{Ce("client.close.start",ze({threadId:i,turnId:s})),await r.close().catch(()=>{}),Ce("client.close.done",ze({threadId:i,turnId:s})),o.close()}})(),{messages:o.messages(),async setPermissionMode(W){l=W,o.enqueue(Gt(W))},async submitPendingInputOption(W,I){return L(W,I)},async submitPendingInputText(W){return w(W)},async interrupt(){!i||!s||await An({client:r,methods:["turn/interrupt"],payloads:pd({threadId:i,turnId:s}),timeoutMs:n.requestTimeoutMs}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as Cm}from"node:child_process";import{constants as Mm,accessSync as _m}from"node:fs";import{createServer as $m}from"node:net";import{delimiter as Em,dirname as zi,join as wd,sep as Dm}from"node:path";function Jt(t){return t instanceof Error?t.message:String(t)}function Bm(t){try{return _m(t,Mm.X_OK),!0}catch{return!1}}function Fm(t){return t.includes("/")||Dm==="\\"&&t.includes("\\")}function qm(t){let e=(t??"").split(Em).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(wd(zi(zi(zi(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function Um(t,e=process.env.PATH){if(Fm(t))return t;for(let n of qm(e)){let r=wd(n,t);if(Bm(r))return r}return t}function de(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Km(t){if(typeof t=="string")return t;if(!de(t))return String(t);if(typeof t.text=="string")return t.text;let e=de(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function Pd(t){let e=t?.trim();if(!e)return;let n=e.indexOf("/");if(!(n<=0||n===e.length-1))return{providerID:e.slice(0,n),modelID:e.slice(n+1)}}function Vm(t){let e=Pd(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function Sd(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return Lm.map(r=>({permission:r,pattern:"*",action:n}))}function Qi(){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 jm(){return new Promise((t,e)=>{let n=$m();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 bd(t){await new Promise(e=>setTimeout(e,t))}async function br(t,e){if(e.signal?.aborted)throw new Error(e.abortMessage??"Operation was aborted.");return await new Promise((n,r)=>{let o=!1,i=()=>{clearTimeout(d),e.signal?.removeEventListener("abort",a)},s=l=>{o||(o=!0,i(),l())},a=()=>{s(()=>r(new Error(e.abortMessage??"Operation was aborted.")))},d=setTimeout(()=>{s(()=>{e.onTimeout?.(),r(new Error(e.timeoutMessage))})},e.timeoutMs);e.signal?.addEventListener("abort",a,{once:!0}),t.then(l=>s(()=>n(l)),l=>s(()=>r(l)))})}async function Qt(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 Gm(t){return t.headers.get("content-type")?.toLowerCase()??""}function Yi(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function Hm(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function zm(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=Yi(r),s=Hm(n,r)?" (looks like the OpenCode web UI HTML app shell)":"";return`OpenCode ${t} ${e} expected JSON API response but received ${o}${s}${i?`: ${i}`:""}`}function Qm(t,e,n){let r=Pd(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function Jm(t,e){if(!de(t))return!1;if(!(e in t))return!0;let n=t[e];return de(n)&&n.type==="idle"}function Ym(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}function Zm(t){return new Promise((e,n)=>{vd=vd.then(()=>t().then(e,n)).catch(()=>{})})}async function Xm(t){return Zm(async()=>{let e=await jm(),n=process.env[Om]?.trim()||"opencode",r=Um(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??es,1e4),a=t.startupTimeoutMs??Nm,d=Cm(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),l=`http://127.0.0.1:${e}`,u="",f="",p,k=(S,P)=>{let x=S+String(P);return x.length>8e3?x.slice(-8e3):x};d.stdout.on("data",S=>{u=k(u,S)}),d.stderr.on("data",S=>{f=k(f,S)}),d.once("error",S=>{p=S});let m=()=>` Command: ${n===r?r:`${r} (resolved from ${n})`} ${o.join(" ")}. Cwd: ${t.cwd}. Port: ${e}. PATH: ${process.env.PATH??""}.`,c=()=>{let S=[u.trim(),f.trim()].filter(Boolean).join(`
8
8
  `).trim();return`${m()}${S?` Output:
9
9
  ${S}`:""}`},h=()=>{Qt(d)};if(t.signal?.aborted)throw await Qt(d),new Error(`OpenCode server startup aborted before readiness.${c()}`);t.signal?.addEventListener("abort",h,{once:!0});try{let S=Date.now();for(;Date.now()-S<a;){if(t.signal?.aborted)throw await Qt(d),new Error(`OpenCode server startup aborted before readiness.${c()}`);if(p)throw new Error(`OpenCode server failed to start: ${p.message}${c()}`);if(d.exitCode!==null)throw new Error(`OpenCode server exited before readiness.${c()}`);try{if(await tf({baseUrl:l,fetchImpl:i,requestTimeoutMs:s,startupSignal:t.signal,timeoutMessage:`OpenCode GET /api/health timed out after ${s}ms during server readiness.${c()}`,abortMessage:`OpenCode server startup aborted before readiness.${c()}`}))return{baseUrl:l,close:async()=>{await Qt(d)}}}catch{if(t.signal?.aborted)throw await Qt(d),new Error(`OpenCode server startup aborted before readiness.${c()}`)}await bd(100)}throw await Qt(d),new Error(`Timed out waiting for OpenCode server readiness.${c()}`)}finally{t.signal?.removeEventListener("abort",h)}})}async function ef(t){for(let e=1;;e+=1)try{return await Xm(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(Jt(n)))throw n}}async function tf(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await br(t.fetchImpl(`${t.baseUrl}/api/health`,{headers:Qi(),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 nf(t){let e=de(t)&&de(t.payload)?t.payload:t;return de(e)?e.type==="sync"?{type:typeof e.name=="string"?e.name.replace(/\.\d+$/,""):void 0,properties:de(e.data)?e.data:{}}:{type:typeof e.type=="string"?e.type:void 0,properties:de(e.properties)?e.properties:e}:{properties:{}}}function rf(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function of(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 sf(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=Kt(t),o=lr(t),i=r.length>0?r:[{id:e,question:n,options:o,allowsFreeText:!0}],s=i.length>0?0:void 0,a=s!=null?i[s]:void 0,d=a?.options.map(l=>l.label)??o.map(l=>l.label);return{requestId:e,kind:"question",promptText:a?je(a,s??0,i.length):n,options:d,...i.length>0?{questions:i}:{},...s!=null?{activeQuestionIndex:s}:{},allowsFreeText:!0}}function af(t,e,n){let r=t.questions??[],o=r[e],i=o?.options.map(s=>s.label)??[];return{...t,promptText:o?je(o,e,r.length):t.promptText,options:i,activeQuestionIndex:e,answers:n}}function df(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
12
  `)}function lf(t){return Xi(t).result}function Xi(t){let e=Array.isArray(t)?t:de(t)&&Array.isArray(t.messages)?t.messages:de(t)&&Array.isArray(t.items)?t.items:[],n=[];for(let r of e){let o=de(r)&&de(r.info)?r.info:r;if(!de(o)||(typeof o.role=="string"?o.role:o.type)!=="assistant")continue;let s=Array.isArray(o.content)?o.content:[],a=de(r)&&Array.isArray(r.parts)?r.parts:[];for(let d of[...s,...a])de(d)&&d.type==="text"&&typeof d.text=="string"&&n.push(d.text)}return{count:n.length,result:n.at(-1)}}var Om,Nm,es,Wm,Lm,Ji,vd,Zi,Rr,Rd=J(()=>{Pn();mr();Om="OPENCLAW_OPENCODE_COMMAND",Nm=15e3,es=6e4,Wm=15*6e4,Lm=["edit","bash","task","todowrite","external_directory"];Ji=class extends Error{constructor(n,r,o,i){super(`OpenCode ${n} ${r} failed with ${o}${i?`: ${i}`:""}`);this.method=n;this.path=r;this.status=o;this.body=i}method;path;status;body};vd=Promise.resolve();Zi=class{constructor(e,n,r=es){this.baseUrl=e;this.fetchImpl=n;this.requestTimeoutMs=r}baseUrl;fetchImpl;requestTimeoutMs;async request(e,n,r,o={}){let i=new AbortController,s=!1,a=!1,d=o.timeoutMs??this.requestTimeoutMs,l=`OpenCode ${e} ${n} timed out after ${d}ms.`,u=`OpenCode ${e} ${n} was aborted.`,f=()=>{s=!0,i.abort()};o.signal?.aborted?(s=!0,i.abort()):o.signal?.addEventListener("abort",f,{once:!0});try{let p=await br(this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:{...Qi(),...r===void 0?{}:{"content-type":"application/json"}},body:r===void 0?void 0:JSON.stringify(r),signal:i.signal}),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!p.ok){let c=await br(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}}).catch(()=>"");throw new Ji(e,n,p.status,Yi(c))}if(p.status===204)return;let k=await br(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!k)return;let m=Gm(p);if(!m.includes("application/json")&&!m.includes("+json"))throw new Error(zm(e,n,m,k));try{return JSON.parse(k)}catch(c){let h=Yi(k);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${Jt(c)}${h?`: ${h}`:""}`)}}catch(p){if(i.signal.aborted){if(a)throw new Error(`OpenCode ${e} ${n} timed out after ${d}ms.`);if(s)throw new Error(`OpenCode ${e} ${n} was aborted.`)}throw p}finally{o.signal?.removeEventListener("abort",f)}}async streamEvents(e,n){let r=await this.fetchImpl(`${this.baseUrl}/event`,{headers:Qi(),signal:n});if(!r.ok)throw new Error(`OpenCode event stream failed with ${r.status}`);if(!r.body)return;let o=r.body.getReader(),i=new TextDecoder,s="",a=async l=>{let u=l.split(/\r?\n/).filter(f=>f.startsWith("data:")).map(f=>f.slice(5).trimStart()).join(`
13
- `).trim();!u||u==="[DONE]"||await e(JSON.parse(u))};for(;;){let{done:l,value:u}=await o.read();if(l)break;s+=i.decode(u,{stream:!0});let f=/\r?\n\r?\n/.exec(s);for(;f;){let p=s.slice(0,f.index);s=s.slice(f.index+f[0].length),await a(p),f=/\r?\n\r?\n/.exec(s)}}let d=s.trim();d&&await a(d)}};Rr=class{constructor(e={}){this.deps=e}deps;name="opencode";backendKind="opencode-server";supportedPermissionModes=["default","plan","bypassPermissions"];capabilities={nativePendingInput:!0,nativePlanArtifacts:!1,worktrees:"plugin-managed"};launch(e){let n=new at,r=this.deps.fetch??fetch,o,i,s,a=e.resumeSessionId,d=0,l=e.permissionMode??"default",u,f=!e.resumeSessionId,p=!1,k=!1,m=new AbortController,c,h=!1,S=!1,b=!1,x=!1,T=!1,A=!1,y,w=new Set,L=M=>x?!1:(x=!0,n.enqueue(Ge(M)),!0),K=(M,C,E)=>L({success:M,outcome:C,duration_ms:0,total_cost_usd:0,num_turns:d,result:E,session_id:a??""}),W=()=>{a&&y!==a&&(y=a,n.enqueue(Vt({kind:"opencode-server",conversationId:a})))},I=M=>{M&&w.has(M)||(M&&w.add(M),n.enqueue(dt(M)),M&&u?.requestId===M&&(u=void 0))},R=async()=>{if(i)return i;s??=(async()=>{let M=await(this.deps.createServer??ef)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(T||e.abortController?.signal.aborted)throw await M.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=M,i=new Zi(M.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(M){throw s=void 0,M}},_=async(M,C)=>{!i||!a||await i.request("POST",`/permission/${encodeURIComponent(M)}/reply`,{reply:C})},q=async(M,C)=>{!i||!a||await i.request("POST",`/question/${encodeURIComponent(M)}/reply`,{answers:[[C]]})},N=async M=>{let C=nf(M),E=rf(C.properties);if(!(E&&E!==a)){if((C.type==="session.next.text.delta"||C.type==="message.part.delta")&&C.properties.field!=="reasoning"&&typeof C.properties.delta=="string"){n.enqueue(St(C.properties.delta));return}if(C.type==="session.next.tool.called"||C.type==="message.part.updated"){let U=de(C.properties.part)?C.properties.part:void 0;if(C.type==="message.part.updated"&&U?.type!=="tool"){n.enqueue({type:"activity"});return}let oe=typeof C.properties.tool=="string"?C.properties.tool:typeof U?.tool=="string"?U.tool:"tool";n.enqueue(cr(oe,C.properties.input));return}if(C.type==="session.next.step.failed"||C.type==="session.error"){let U=de(C.properties.error)&&typeof C.properties.error.message=="string"?C.properties.error.message:`${C.type} failed`;S&&!b&&(c?.abort(),K(!1,"failed",U));return}if(C.type==="permission.asked"){if(l==="bypassPermissions"){let oe=typeof C.properties.id=="string"?C.properties.id:void 0;oe&&(await _(oe,"once").catch(()=>{}),I(oe));return}let U=of(C.properties);u={requestId:U.requestId,kind:"approval",options:U.options,actions:U.actions??[],state:U},n.enqueue(Le(U));return}if(C.type==="permission.replied"){let U=typeof C.properties.requestID=="string"?C.properties.requestID:void 0;I(U);return}if(C.type==="question.asked"){let U=sf(C.properties);u={requestId:U.requestId,kind:"question",options:U.options,actions:[],state:U},n.enqueue(Le(U));return}if(C.type==="question.replied"||C.type==="question.rejected"){let U=typeof C.properties.requestID=="string"?C.properties.requestID:void 0;I(U);return}(C.type?.startsWith("session.next.")||C.type?.startsWith("message.")||C.type==="session.status"||C.type==="session.idle")&&(Ym(C)&&(A=!0),n.enqueue({type:"activity"}))}},F=()=>{h||!i||(h=!0,i.streamEvents(N,m.signal).catch(M=>{!m.signal.aborted&&S&&!b&&(c?.abort(),K(!1,"failed",Jt(M)))}).finally(()=>{h=!1}))},Q=async(M,C)=>await M.request("GET",`/session/${encodeURIComponent(C)}/message`),Y=async(M,C,E,U,oe)=>{await M.request("POST",`/session/${encodeURIComponent(C)}/prompt_async`,Qm(E,e.model,U),{signal:oe})},gt=async(M,C,E,U)=>{let oe=Date.now(),Oe=!1,Pe=E,Xe,Et=0,et,wa=this.deps.turnTimeoutMs??Wm;for(;;){if(U.aborted)throw new Error("wait aborted");let Jc=await Q(M,C).catch(()=>{}),tt=Xi(Jc),Pa=tt.count>E&&!!tt.result;Pa&&tt.count===Pe&&tt.result===Xe?Et+=1:(Et=Pa?1:0,Pe=tt.count,Xe=tt.result);let Pi=!1;try{let mn=await M.request("GET","/session/status",void 0,{signal:U,timeoutMs:Math.min(this.deps.requestTimeoutMs??es,1e4)});Pi=Jm(mn,C),et=void 0,Pi||(Oe=!0)}catch(mn){if(U.aborted)throw new Error("wait aborted");et=Jt(mn)}if(Pi&&(Oe||tt.count>E)||A&&tt.count>E||Et>=2&&et)return;if(Date.now()-oe>wa){let mn=et?` Last status error: ${et}`:"";throw new Error(`Timed out waiting for OpenCode session ${C} to become idle after ${wa}ms.${mn}`)}await bd(250)}},cn=async()=>{let M=await R();if(a){if(e.forkSession&&!p){let U=await M.request("POST",`/session/${encodeURIComponent(a)}/fork`,{});if(!U.id)throw new Error("OpenCode fork did not return a session id.");a=U.id,p=!0,f=!0}else f||(await Q(M,a),f=!0);return W(),F(),a}let C=Vm(e.model),E=await M.request("POST","/session",{...C?{model:C}:{},metadata:{client:"openclaw-code-agent"},permission:Sd(l)});if(!E.id)throw new Error("OpenCode did not return a session id.");return a=E.id,f=!0,W(),F(),a},pn=async(M,C,E=M?"completed":"failed")=>{let U=C;if(M&&i&&a){let oe=await Q(i,a).catch(()=>{});U=U??lf(oe)}K(M,E,U)},zc=async M=>{S=!0,b=!1,x=!1,A=!1;try{let C=await R();if(T)return;let E=await cn();if(T)return;n.enqueue(jt()),d+=1;let U=k?void 0:e.systemPrompt,oe=await Q(C,E).catch(()=>{}),Oe=Xi(oe).count,Pe=new AbortController;c=Pe,await Y(C,E,M,U,Pe.signal),k=!0,await gt(C,E,Oe,Pe.signal),c=void 0,b=!0,await pn(!0)}catch(C){c=void 0,await pn(!1,Jt(C))}finally{S=!1,b=!1}},wi=async(M,C={})=>{let E=u;if(!E||E.kind!=="question"||C.requestId&&C.requestId!==E.requestId)return!1;let U=M.trim();if(!U)return!1;let oe=E.state?.questions??[];if(oe.length>0){let Oe=E.state?.activeQuestionIndex??0,Pe=oe[Oe];if(!Pe||C.questionId&&C.questionId!==Pe.id)return!1;E.answers={...E.answers,[Pe.id]:{answers:[U]}};let Xe=Oe+1;return Xe<oe.length?(E.state=af(E.state,Xe,E.answers),E.options=E.state.options,n.enqueue(Le(E.state)),!0):(await q(E.requestId,df(oe,E.answers)),I(E.requestId),!0)}return await q(E.requestId,U),I(E.requestId),!0},Qc=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 Qc){if(T)break;let C=Km(M).trim();if(C){if(u?.kind==="question"){await wi(C);continue}if(await zc(C),T)break}}}catch(M){T||(S||(x=!1),K(!1,"failed",Jt(M)))}finally{m.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(M){a&&await(await R()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:Sd(M)}),l=M,n.enqueue(Gt(M))},async submitPendingInputOption(M,C={}){let E=u;if(!E||C.requestId&&C.requestId!==E.requestId)return!1;if(E.kind==="approval"){let Et=E.actions[M],et=Et?.kind==="approval"?Et.responseDecision:void 0;return et?(await _(E.requestId,et),I(E.requestId),!0):!1}let U=E.state?.questions??[],oe=E.state?.activeQuestionIndex??0,Oe=U[oe];if(C.questionId&&C.questionId!==Oe?.id)return!1;let Pe=Oe?.options[M],Xe=Pe?.value??Pe?.label??E.options[M];return Xe?await wi(Xe,C):!1},async submitPendingInputText(M){return await wi(M)},async interrupt(){if(T=!0,m.abort(),c?.abort(),S||(x=!1),K(!1,"interrupted"),!i){await o?.close().catch(()=>{});return}if(!a)return;await i.request("POST",`/session/${encodeURIComponent(a)}/abort`).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});function ns(t){ts.set(t.name,t)}function xn(t){let e=ts.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...ts.keys()].join(", ")}`);return e}function Ad(){return xn(fe())}var ts,rs=J(()=>{Qa();kd();Rd();ae();ts=new Map;ns(new fr);ns(new Pr);ns(new Rr)});function O(t){return t.backendRef?.conversationId??t.harnessSessionId}function G(t){return t.id??t.sessionId??t.name??O(t)??t.harnessSessionId}function uf(t){return t.harnessSessionId}function ge(t){let e=[G(t),O(t),uf(t)].filter(n=>!!n);return[...new Set(e)]}function os(t){return t.harnessName??t.persistedHarness??fe()}function Tn(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return xn(os(t)).capabilities.worktrees}catch{return"plugin-managed"}}function is(t){return t==="native-execution"}function Ar(t){return t==="native-restore"}function cf(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function ue(t){let e=Tn(t);return(is(e)||Ar(e))&&cf(t)}var ne=J(()=>{ae();rs()});import{execFileSync as ie}from"child_process";import*as Ur from"fs";import{tmpdir as Vf}from"os";import{dirname as Hd,join as jf}from"path";function Gf(t){try{return ie("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Kr(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(D.worktreeDir)return D.worktreeDir;if(t){let e=Gf(t);if(e)return jf(e,".worktrees")}return Vf()}function zd(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100).replace(/[-.]+$/,"")||"session"}function Vr(t){try{let e=ie("git",["-C",t,"rev-parse","--git-common-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e&&e.endsWith("/.git")?Hd(e):void 0}catch{return}}function Hf(){if(Fr!==void 0)return Fr;try{return ie("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Fr=!0,!0}catch{return Fr=!1,!1}}function ye(){if(qr!==void 0)return qr;try{return ie("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),qr=!0,!0}catch{return qr=!1,!1}}function jr(t){if(!Hf())return!1;try{return ie("git",["rev-parse","--git-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Qd(t){try{let e=Qf(t);if(!e)return`${Kr(t)}`,!0;let n=Ur.statfsSync(e),r=n.bavail*n.bsize;return Jf(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function Pt(t,e){try{return ie("git",["-C",t,"rev-parse","--verify",e],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Gr(t,e,n="origin"){let r=`refs/remotes/${n}/${e}`;try{return ie("git",["-C",t,"fetch",n,`+${e}:${r}`],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ie("git",["-C",t,"rev-parse","--verify",r],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r}catch{return}}function zf(t){let e=t;for(;;){if(Ur.existsSync(e))return e;let n=Hd(e);if(n===e)return;e=n}}function Qf(t){return zf(Kr(t))}function Jf(t){return t>=104857600}function Fe(t){let e=process.env.OPENCLAW_WORKTREE_BASE_BRANCH?.trim();if(e)return e;try{let r=ie("git",["-C",t,"rev-parse","--abbrev-ref","origin/HEAD"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().replace(/^origin\//,"");if(r)return r}catch{}try{return ie("git",["-C",t,"rev-parse","--verify","main"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"main"}catch{}try{return ie("git",["-C",t,"rev-parse","--verify","master"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"master"}catch{return"main"}}function Se(t){try{let n=ie("git",["-C",t,"rev-parse","--abbrev-ref","HEAD"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(n==="HEAD"){`${t}`;return}return n||void 0}catch{return}}function Mn(t,e,n){try{let r=ie("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10);return Number.isFinite(o)?o:void 0}catch{return}}function Jd(t,e,n){try{let r=ie("git",["-C",t,"rev-list","--left-right","--count",`${e}...${n}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),[o,i]=r.split(/\s+/);return{ahead:parseInt(o??"0",10)||0,behind:parseInt(i??"0",10)||0}}catch{return}}function ve(t,e,n){try{return ie("git",["-C",t,"merge-base","--is-ancestor",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Hr(t,e,n){try{let r=ie("git",["-C",t,"merge-tree","--write-tree",n,e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),o=ie("git",["-C",t,"rev-parse",`${n}^{tree}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return!!r&&r===o}catch{return!1}}function be(t,e){try{return ie("git",["-C",t,"branch","-D",e],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(n){return`${e}${n instanceof Error?n.message:String(n)}`,!1}}function _n(t,e){if(e)return e;let n;try{n=ie("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}try{let r=ie("git",["-C",t,"remote","get-url","upstream"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(r&&r!==n){let o=r.match(/[:/]([^/]+\/[^/]+?)(?:\.git)?$/);if(o)return o[1]}}catch{}}var Fr,qr,Zt=J(()=>{ae()});import{execFileSync as Xt}from"child_process";import{randomBytes as Yf}from"crypto";import{appendFileSync as Zf,existsSync as cs,mkdirSync as Yd,readFileSync as Xf,rmSync as us}from"fs";import{relative as eg,sep as Zd}from"path";function tg(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function ng(t){try{return Xt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function rg(t){return t===0?"":`-${t}-${Yf(8).toString("hex")}`}function og(t,e){let n=ng(t);if(!n)return;let r=eg(n,e);if(!r||r.startsWith("..")||r.includes(`..${Zd}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(Zd).join("/").replace(/\/$/,"")}/`;try{let s=cs(o)?Xf(o,"utf-8"):"";s.split(/\r?\n/).map(d=>d.trim()).some(d=>d===i||d===`/${i}`)||Zf(o,`${s.endsWith(`
13
+ `).trim();!u||u==="[DONE]"||await e(JSON.parse(u))};for(;;){let{done:l,value:u}=await o.read();if(l)break;s+=i.decode(u,{stream:!0});let f=/\r?\n\r?\n/.exec(s);for(;f;){let p=s.slice(0,f.index);s=s.slice(f.index+f[0].length),await a(p),f=/\r?\n\r?\n/.exec(s)}}let d=s.trim();d&&await a(d)}};Rr=class{constructor(e={}){this.deps=e}deps;name="opencode";backendKind="opencode-server";supportedPermissionModes=["default","plan","bypassPermissions"];capabilities={nativePendingInput:!0,nativePlanArtifacts:!1,worktrees:"plugin-managed"};launch(e){let n=new at,r=this.deps.fetch??fetch,o,i,s,a=e.resumeSessionId,d=0,l=e.permissionMode??"default",u,f=!e.resumeSessionId,p=!1,k=!1,m=new AbortController,c,h=!1,S=!1,P=!1,x=!1,C=!1,A=!1,y,w=new Set,L=M=>x?!1:(x=!0,n.enqueue(Ge(M)),!0),K=(M,T,E)=>L({success:M,outcome:T,duration_ms:0,total_cost_usd:0,num_turns:d,result:E,session_id:a??""}),W=()=>{a&&y!==a&&(y=a,n.enqueue(Vt({kind:"opencode-server",conversationId:a})))},I=M=>{M&&w.has(M)||(M&&w.add(M),n.enqueue(dt(M)),M&&u?.requestId===M&&(u=void 0))},R=async()=>{if(i)return i;s??=(async()=>{let M=await(this.deps.createServer??ef)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(C||e.abortController?.signal.aborted)throw await M.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=M,i=new Zi(M.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(M){throw s=void 0,M}},_=async(M,T)=>{!i||!a||await i.request("POST",`/permission/${encodeURIComponent(M)}/reply`,{reply:T})},q=async(M,T)=>{!i||!a||await i.request("POST",`/question/${encodeURIComponent(M)}/reply`,{answers:[[T]]})},N=async M=>{let T=nf(M),E=rf(T.properties);if(!(E&&E!==a)){if((T.type==="session.next.text.delta"||T.type==="message.part.delta")&&T.properties.field!=="reasoning"&&typeof T.properties.delta=="string"){n.enqueue(St(T.properties.delta));return}if(T.type==="session.next.tool.called"||T.type==="message.part.updated"){let U=de(T.properties.part)?T.properties.part:void 0;if(T.type==="message.part.updated"&&U?.type!=="tool"){n.enqueue({type:"activity"});return}let oe=typeof T.properties.tool=="string"?T.properties.tool:typeof U?.tool=="string"?U.tool:"tool";n.enqueue(cr(oe,T.properties.input));return}if(T.type==="session.next.step.failed"||T.type==="session.error"){let U=de(T.properties.error)&&typeof T.properties.error.message=="string"?T.properties.error.message:`${T.type} failed`;S&&!P&&(c?.abort(),K(!1,"failed",U));return}if(T.type==="permission.asked"){if(l==="bypassPermissions"){let oe=typeof T.properties.id=="string"?T.properties.id:void 0;oe&&(await _(oe,"once").catch(()=>{}),I(oe));return}let U=of(T.properties);u={requestId:U.requestId,kind:"approval",options:U.options,actions:U.actions??[],state:U},n.enqueue(Le(U));return}if(T.type==="permission.replied"){let U=typeof T.properties.requestID=="string"?T.properties.requestID:void 0;I(U);return}if(T.type==="question.asked"){let U=sf(T.properties);u={requestId:U.requestId,kind:"question",options:U.options,actions:[],state:U},n.enqueue(Le(U));return}if(T.type==="question.replied"||T.type==="question.rejected"){let U=typeof T.properties.requestID=="string"?T.properties.requestID:void 0;I(U);return}(T.type?.startsWith("session.next.")||T.type?.startsWith("message.")||T.type==="session.status"||T.type==="session.idle")&&(Ym(T)&&(A=!0),n.enqueue({type:"activity"}))}},F=()=>{h||!i||(h=!0,i.streamEvents(N,m.signal).catch(M=>{!m.signal.aborted&&S&&!P&&(c?.abort(),K(!1,"failed",Jt(M)))}).finally(()=>{h=!1}))},Q=async(M,T)=>await M.request("GET",`/session/${encodeURIComponent(T)}/message`),Y=async(M,T,E,U,oe)=>{await M.request("POST",`/session/${encodeURIComponent(T)}/prompt_async`,Qm(E,e.model,U),{signal:oe})},gt=async(M,T,E,U)=>{let oe=Date.now(),Oe=!1,Pe=E,Xe,Et=0,et,wa=this.deps.turnTimeoutMs??Wm;for(;;){if(U.aborted)throw new Error("wait aborted");let Jc=await Q(M,T).catch(()=>{}),tt=Xi(Jc),Pa=tt.count>E&&!!tt.result;Pa&&tt.count===Pe&&tt.result===Xe?Et+=1:(Et=Pa?1:0,Pe=tt.count,Xe=tt.result);let Pi=!1;try{let mn=await M.request("GET","/session/status",void 0,{signal:U,timeoutMs:Math.min(this.deps.requestTimeoutMs??es,1e4)});Pi=Jm(mn,T),et=void 0,Pi||(Oe=!0)}catch(mn){if(U.aborted)throw new Error("wait aborted");et=Jt(mn)}if(Pi&&(Oe||tt.count>E)||A&&tt.count>E||Et>=2&&et)return;if(Date.now()-oe>wa){let mn=et?` Last status error: ${et}`:"";throw new Error(`Timed out waiting for OpenCode session ${T} to become idle after ${wa}ms.${mn}`)}await bd(250)}},cn=async()=>{let M=await R();if(a){if(e.forkSession&&!p){let U=await M.request("POST",`/session/${encodeURIComponent(a)}/fork`,{});if(!U.id)throw new Error("OpenCode fork did not return a session id.");a=U.id,p=!0,f=!0}else f||(await Q(M,a),f=!0);return W(),F(),a}let T=Vm(e.model),E=await M.request("POST","/session",{...T?{model:T}:{},metadata:{client:"openclaw-code-agent"},permission:Sd(l)});if(!E.id)throw new Error("OpenCode did not return a session id.");return a=E.id,f=!0,W(),F(),a},pn=async(M,T,E=M?"completed":"failed")=>{let U=T;if(M&&i&&a){let oe=await Q(i,a).catch(()=>{});U=U??lf(oe)}K(M,E,U)},zc=async M=>{S=!0,P=!1,x=!1,A=!1;try{let T=await R();if(C)return;let E=await cn();if(C)return;n.enqueue(jt()),d+=1;let U=k?void 0:e.systemPrompt,oe=await Q(T,E).catch(()=>{}),Oe=Xi(oe).count,Pe=new AbortController;c=Pe,await Y(T,E,M,U,Pe.signal),k=!0,await gt(T,E,Oe,Pe.signal),c=void 0,P=!0,await pn(!0)}catch(T){c=void 0,await pn(!1,Jt(T))}finally{S=!1,P=!1}},wi=async(M,T={})=>{let E=u;if(!E||E.kind!=="question"||T.requestId&&T.requestId!==E.requestId)return!1;let U=M.trim();if(!U)return!1;let oe=E.state?.questions??[];if(oe.length>0){let Oe=E.state?.activeQuestionIndex??0,Pe=oe[Oe];if(!Pe||T.questionId&&T.questionId!==Pe.id)return!1;E.answers={...E.answers,[Pe.id]:{answers:[U]}};let Xe=Oe+1;return Xe<oe.length?(E.state=af(E.state,Xe,E.answers),E.options=E.state.options,n.enqueue(Le(E.state)),!0):(await q(E.requestId,df(oe,E.answers)),I(E.requestId),!0)}return await q(E.requestId,U),I(E.requestId),!0},Qc=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 Qc){if(C)break;let T=Km(M).trim();if(T){if(u?.kind==="question"){await wi(T);continue}if(await zc(T),C)break}}}catch(M){C||(S||(x=!1),K(!1,"failed",Jt(M)))}finally{m.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(M){a&&await(await R()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:Sd(M)}),l=M,n.enqueue(Gt(M))},async submitPendingInputOption(M,T={}){let E=u;if(!E||T.requestId&&T.requestId!==E.requestId)return!1;if(E.kind==="approval"){let Et=E.actions[M],et=Et?.kind==="approval"?Et.responseDecision:void 0;return et?(await _(E.requestId,et),I(E.requestId),!0):!1}let U=E.state?.questions??[],oe=E.state?.activeQuestionIndex??0,Oe=U[oe];if(T.questionId&&T.questionId!==Oe?.id)return!1;let Pe=Oe?.options[M],Xe=Pe?.value??Pe?.label??E.options[M];return Xe?await wi(Xe,T):!1},async submitPendingInputText(M){return await wi(M)},async interrupt(){if(C=!0,m.abort(),c?.abort(),S||(x=!1),K(!1,"interrupted"),!i){await o?.close().catch(()=>{});return}if(!a)return;await i.request("POST",`/session/${encodeURIComponent(a)}/abort`).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});function ns(t){ts.set(t.name,t)}function xn(t){let e=ts.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...ts.keys()].join(", ")}`);return e}function Ad(){return xn(fe())}var ts,rs=J(()=>{Qa();kd();Rd();ae();ts=new Map;ns(new fr);ns(new Pr);ns(new Rr)});function O(t){return t.backendRef?.conversationId??t.harnessSessionId}function G(t){return t.id??t.sessionId??t.name??O(t)??t.harnessSessionId}function uf(t){return t.harnessSessionId}function ge(t){let e=[G(t),O(t),uf(t)].filter(n=>!!n);return[...new Set(e)]}function os(t){return t.harnessName??t.persistedHarness??fe()}function Tn(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return xn(os(t)).capabilities.worktrees}catch{return"plugin-managed"}}function is(t){return t==="native-execution"}function Ar(t){return t==="native-restore"}function cf(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function ue(t){let e=Tn(t);return(is(e)||Ar(e))&&cf(t)}var ne=J(()=>{ae();rs()});import{execFileSync as ie}from"child_process";import*as Ur from"fs";import{tmpdir as Vf}from"os";import{dirname as Hd,join as jf}from"path";function Gf(t){try{return ie("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Kr(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(D.worktreeDir)return D.worktreeDir;if(t){let e=Gf(t);if(e)return jf(e,".worktrees")}return Vf()}function zd(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100).replace(/[-.]+$/,"")||"session"}function Vr(t){try{let e=ie("git",["-C",t,"rev-parse","--git-common-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e&&e.endsWith("/.git")?Hd(e):void 0}catch{return}}function Hf(){if(Fr!==void 0)return Fr;try{return ie("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Fr=!0,!0}catch{return Fr=!1,!1}}function ye(){if(qr!==void 0)return qr;try{return ie("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),qr=!0,!0}catch{return qr=!1,!1}}function jr(t){if(!Hf())return!1;try{return ie("git",["rev-parse","--git-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Qd(t){try{let e=Qf(t);if(!e)return`${Kr(t)}`,!0;let n=Ur.statfsSync(e),r=n.bavail*n.bsize;return Jf(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function Pt(t,e){try{return ie("git",["-C",t,"rev-parse","--verify",e],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Gr(t,e,n="origin"){let r=`refs/remotes/${n}/${e}`;try{return ie("git",["-C",t,"fetch",n,`+${e}:${r}`],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ie("git",["-C",t,"rev-parse","--verify",r],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r}catch{return}}function zf(t){let e=t;for(;;){if(Ur.existsSync(e))return e;let n=Hd(e);if(n===e)return;e=n}}function Qf(t){return zf(Kr(t))}function Jf(t){return t>=104857600}function Fe(t){let e=process.env.OPENCLAW_WORKTREE_BASE_BRANCH?.trim();if(e)return e;try{let r=ie("git",["-C",t,"rev-parse","--abbrev-ref","origin/HEAD"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().replace(/^origin\//,"");if(r)return r}catch{}try{return ie("git",["-C",t,"rev-parse","--verify","main"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"main"}catch{}try{return ie("git",["-C",t,"rev-parse","--verify","master"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"master"}catch{return"main"}}function Se(t){try{let n=ie("git",["-C",t,"rev-parse","--abbrev-ref","HEAD"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(n==="HEAD"){`${t}`;return}return n||void 0}catch{return}}function Mn(t,e,n){try{let r=ie("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10);return Number.isFinite(o)?o:void 0}catch{return}}function Jd(t,e,n){try{let r=ie("git",["-C",t,"rev-list","--left-right","--count",`${e}...${n}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),[o,i]=r.split(/\s+/);return{ahead:parseInt(o??"0",10)||0,behind:parseInt(i??"0",10)||0}}catch{return}}function ve(t,e,n){try{return ie("git",["-C",t,"merge-base","--is-ancestor",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Hr(t,e,n){try{let r=ie("git",["-C",t,"merge-tree","--write-tree",n,e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),o=ie("git",["-C",t,"rev-parse",`${n}^{tree}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return!!r&&r===o}catch{return!1}}function be(t,e){try{return ie("git",["-C",t,"branch","-D",e],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(n){return`${e}${n instanceof Error?n.message:String(n)}`,!1}}function _n(t,e){if(e)return e;let n;try{n=ie("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}try{let r=ie("git",["-C",t,"remote","get-url","upstream"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(r&&r!==n){let o=r.match(/[:/]([^/]+\/[^/]+?)(?:\.git)?$/);if(o)return o[1]}}catch{}}var Fr,qr,Zt=J(()=>{ae()});import{execFileSync as Xt}from"child_process";import{randomBytes as Yf}from"crypto";import{appendFileSync as Zf,existsSync as cs,mkdirSync as Yd,readFileSync as Xf,rmSync as us}from"fs";import{relative as eg,sep as Zd}from"path";function tg(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function ng(t){try{return Xt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function rg(t){return t===0?"":`-${t}-${Yf(8).toString("hex")}`}function og(t,e){let n=ng(t);if(!n)return;let r=eg(n,e);if(!r||r.startsWith("..")||r.includes(`..${Zd}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(Zd).join("/").replace(/\/$/,"")}/`;try{let s=cs(o)?Xf(o,"utf-8"):"";s.split(/\r?\n/).map(d=>d.trim()).some(d=>d===i||d===`/${i}`)||Zf(o,`${s.endsWith(`
14
14
  `)||s.length===0?"":`
15
15
  `}${i}
16
16
  `,"utf-8")}catch(s){`${i}${o}${s instanceof Error?s.message:String(s)}`}}function ps(t,e,n={}){let r=zd(e),o=Kr(t);og(t,o),Yd(o,{recursive:!0});let i=n.allowExistingBranch===!0,s,a,d=10,l=!1;for(let f=0;f<d;f++){let p=rg(f),k=`${o}/openclaw-worktree-${r}${p}`,m=`agent/${r}${p}`;if(!i&&Pt(t,m))continue;let c=!1;do{c=!1;try{Yd(k,{recursive:!1}),s=k,a=m;break}catch(h){if(tg(h,"EEXIST")){if(i&&f===0&&!l)try{us(k,{recursive:!0,force:!0}),l=!0,c=!0}catch(S){throw new Error(`Failed to recreate existing worktree branch ${m}: could not clear blocked path ${k}: ${S instanceof Error?S.message:String(S)}`)}else if(i&&f===0)throw new Error(`Failed to recreate existing worktree branch ${m}: path ${k} remains blocked after one cleanup attempt`);continue}throw h}}while(c);if(s&&a)break}if(!s||!a)throw new Error(`Failed to create unique worktree directory and branch after ${d} attempts`);let u=Pt(t,a);try{u?Xt("git",["-C",t,"worktree","add",s,a],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):Xt("git",["-C",t,"worktree","add","-b",a,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){try{us(s,{recursive:!0,force:!0})}catch{}throw f}return s}function bt(t){if(!cs(t))return[];try{let e=Xt("git",["-C",t,"status","--porcelain","--untracked-files=all"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e?e.split(`
@@ -18,17 +18,17 @@ A${r+1}: ${o}`}).join(`
18
18
  ${n.map(r=>`⚠️ ${r}`).join(`
19
19
  `)}`}function Qr(t){return t instanceof Error?t.message:String(t)}function Qe(t,e,n){try{let r=ee("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10),s=ee("git",["-C",t,"diff","--shortstat",`${n}...${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),a=0,d=0,l=0,u=s.match(/(\d+)\s+files?\s+changed/);u&&(a=parseInt(u[1],10));let f=s.match(/(\d+)\s+insertions?\(/);f&&(d=parseInt(f[1],10));let p=s.match(/(\d+)\s+deletions?\(/);p&&(l=parseInt(p[1],10));let m=ee("git",["-C",t,"diff","--name-only","--diff-filter=ACMR",`${n}...${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
20
20
  `).map(S=>S.trim()).filter(Boolean),h=ee("git",["-C",t,"log",`${n}..${e}`,"--format=%h|%s|%an","-n","5"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
21
- `).filter(Boolean).map(S=>{let[b,x,T]=S.split("|");return{hash:b||"",message:x||"",author:T||""}});return{commits:o,filesChanged:a,insertions:d,deletions:l,changedFiles:m,commitMessages:h}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function Jr(t,e,n="origin"){try{return ee("git",["-C",t,"push",n,e],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,!1}}function el(t){try{return ee("git",["-C",t,"status","--porcelain"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).split(`
21
+ `).filter(Boolean).map(S=>{let[P,x,C]=S.split("|");return{hash:P||"",message:x||"",author:C||""}});return{commits:o,filesChanged:a,insertions:d,deletions:l,changedFiles:m,commitMessages:h}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function Jr(t,e,n="origin"){try{return ee("git",["-C",t,"push",n,e],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,!1}}function el(t){try{return ee("git",["-C",t,"status","--porcelain"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).split(`
22
22
  `).some(n=>n.length>0&&!n.startsWith("??")&&!n.startsWith("!!"))}catch{return!1}}function Yr(t,e,n,r="merge",o){let i=!1,s,a=[],d=f=>a.length>0?{...f,warnings:[...a]}:f,l=(f,p)=>{a.push(`${f}: ${Qr(p)}`)},u=f=>{if(i)try{ee("git",["-C",f,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(p){l("Failed to pop auto-stash during recovery",p)}};try{if(r==="squash"){if(ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),el(t)){let c;try{c=ee("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(h){return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Qr(h)}. Commit or stash changes manually, then retry.`})}if(!c.includes("No local changes to save")){i=!0;try{s=ee("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(h){l("Failed to determine auto-stash ref",h)}}}ee("git",["-C",t,"merge","--squash",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ee("git",["-C",t,"commit","-m",`Squash merge ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let m=!1;if(i)try{ee("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){m=!0,l("Failed to pop auto-stash after merge",c)}return d({success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:m||void 0})}let f=o&&ig(o),p=f?o:t;if(f||ee("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),el(t)){let m;try{m=ee("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(h){l(`Failed to check out ${n} after auto-stash failure`,h)}return d({success:!1,dirtyError:!0,error:`Auto-stash failed: ${Qr(c)}. Commit or stash changes manually, then retry.`})}if(!m.includes("No local changes to save")){i=!0;try{s=ee("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch(c){l("Failed to determine auto-stash ref",c)}}}try{ee("git",["-C",p,"rebase",n],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{try{ee("git",["-C",p,"rebase","--abort"],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){l("Failed to abort rebase during recovery",m)}try{ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){l(`Failed to check out ${n} during recovery`,m)}return u(t),d({success:!1,rebaseConflict:!0,stashed:i||void 0,stashRef:s,error:[`Rebase of ${e} onto ${n} hit conflicts.`,"To resolve manually:",` cd ${p}`,` git rebase ${n}`," # resolve conflicts in each file, then:"," git add <file>"," git rebase --continue"," # repeat until rebase finishes, then re-run agent_merge."].join(`
23
23
  `)})}ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),ee("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let k=!1;if(i)try{ee("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(m){k=!0,l("Failed to pop auto-stash after merge",m)}return d({success:!0,fastForward:!0,stashed:i||void 0,stashRef:s,stashPopConflict:k||void 0})}catch(f){try{ee("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(p){l(`Failed to check out ${n} during recovery`,p)}return u(t),d({success:!1,error:Qr(f),stashed:i||void 0,stashRef:s})}}var tl=J(()=>{});import{execFileSync as Je}from"child_process";function ol(t){let e=t.toLowerCase();return e==="open"?"open":e==="merged"?"merged":e==="closed"?"closed":"none"}function il(t){if(/\r|\n/.test(t)||!/(?<!\\)\\n\\n/.test(t))return t;let e=t.replace(sg,`
24
24
  `),n=e.split(`
25
- `);return n.some(o=>/^#{1,6}\s+\S/.test(o.trim()))&&n.some(o=>/^(?:[-*+]\s+|\d+\.\s+|```)/.test(o.trim()))?e:t}function ag(t){return t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:""}function nl(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function rl(t,e,n){let r=Re(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 sl(t){try{return Je("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function dg(t,e,n){if(!n)return e;let r=sl(t);return r?`${r}:${e}`:e}function al(t,e,n,r,o,i,s={}){if(!ye())return{success:!1,error:"GitHub CLI (gh) is not available"};let a;try{return a=["pr","create","--base",n],(s.draft??!0)&&a.push("--draft"),i&&a.push("--repo",i),a.push("--head",dg(t,e,i)),r&&o?a.push("--title",r,"--body",il(o)):a.push("--fill-verbose"),{success:!0,prUrl:Je("gh",a,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}}catch(d){let l=d instanceof Error?d.message:String(d);if(nl(l))return rl(t,e,i)??{success:!1,error:l};if((s.draft??!0)&&a&&/draft/i.test(l))try{let u=a.filter(k=>k!=="--draft");return{success:!0,prUrl:Je("gh",u,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),warnings:["Target repo does not support draft PRs; created as regular (non-draft) PR instead."]}}catch(u){let f=u instanceof Error?u.message:String(u);return nl(f)?rl(t,e,i)??{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${f}`}:{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${f}`}}return{success:!1,error:l}}}function Re(t,e,n){if(!ye())return{exists:!1,state:"none"};try{let r=["pr","list","--head",e,"--state","all","--json","url,number,title,state,headRepositoryOwner,headRefName,baseRefName"];n&&r.push("--repo",n);let i=Je("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(!i)return{exists:!1,state:"none"};let s=JSON.parse(i),a=n?sl(t)?.toLowerCase():void 0,d=s.find(f=>f.headRefName===e&&(!a||f.headRepositoryOwner?.login?.toLowerCase()===a));if(!d)return{exists:!1,state:"none"};let u={exists:!0,state:ol(d.state),url:d.url,number:d.number,title:d.title};return d.headRefName!==void 0&&(u.headRefName=d.headRefName),d.baseRefName!==void 0&&(u.baseRefName=d.baseRefName),u}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function Ye(t,e,n){if(!ye())return{exists:!1,state:"none"};try{let r=["pr","view",e,"--json","url,number,title,state,headRefName,baseRefName"];n&&r.push("--repo",n);let o=Je("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim()),s={exists:!0,state:ol(i.state),url:i.url,number:i.number,title:i.title};return i.headRefName!==void 0&&(s.headRefName=i.headRefName),i.baseRefName!==void 0&&(s.baseRefName=i.baseRefName),s}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function dl(t,e,n){if(!ye())return{ok:!1,error:"GitHub CLI (gh) is not available"};try{let r=["pr","view",String(e),"--json","body"];n&&r.push("--repo",n);let o=Je("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim());return{ok:!0,body:typeof i.body=="string"?i.body:void 0}}catch(r){let o=r instanceof Error?r.message:String(r);return`${e}${o}`,{ok:!1,error:o}}}function ll(t,e,n,r){if(!ye())return!1;try{let o=["pr","edit",String(e),"--body",il(n)];return r&&o.push("--repo",r),Je("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 ul(t,e,n,r){if(!ye())return!1;try{let o=["pr","edit",String(e),"--title",n];return r&&o.push("--repo",r),Je("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 cl(t,e,n,r){if(!ye())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),Je("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 At(t){let e=ag(t);return t.kind==="merge"?`✅ Merged: ${t.branch} → ${t.base??"main"}${e}`:t.kind==="pr-updated"?`✅ PR updated: ${t.prUrl??""}${e}`:t.targetRepo?`✅ PR opened against ${t.targetRepo}: ${t.prUrl??""}${e}`:`✅ PR opened: ${t.prUrl??""}${e}`}var sg,fs=J(()=>{Zt();sg=/(?<!\\)\\(?:r\\)?n/g});import{existsSync as gs}from"fs";function pl(){return new Date().toISOString()}function lg(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:pl(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function ug(t){let e=ml(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&gs(e)?Fe(e):void 0)}function ml(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function pt(t,e={}){let n=lg(t),r=pl(),o=new Set,i=ml(t),s=!!(i&&gs(i)),a=!!(t.worktreePath&&gs(t.worktreePath)),d=t.worktreeBranch,l=ug(t),u=!1,f=!1,p=!1,k=!1,m=!1,c,h,S="none",b=t.worktreePrUrl,x=t.worktreePrNumber;if(s||o.add("repo_missing"),d||o.add("branch_missing"),!a&&t.worktreePath&&o.add("worktree_missing"),e.activeSession&&o.add("active_session"),n.state==="pending_decision"&&o.add("pending_decision"),n.state==="merge_conflict_resolving"&&o.add("merge_conflict_resolving"),s&&i&&d&&(u=Pt(i,d),u||o.add("branch_missing")),a&&t.worktreePath&&(f=Rt(t.worktreePath),f&&o.add("dirty_worktree_entries")),s&&i&&u&&d&&l){let R=Jd(i,d,l);c=R?.ahead,h=R?.behind,p=ve(i,d,l),p?o.add("topology_merged"):(k=Hr(i,d,l),k&&o.add("merge_noop_content_already_on_base"),!k&&(c??0)>0&&o.add("unique_content"));let _=Se(i);if(e.includePrSync&&t.worktreePrUrl&&_&&_!==d&&_!==l){let q=Ye(i,t.worktreePrUrl,t.worktreePrTargetRepo??n.targetRepo);m=!!((q.state==="open"||q.state==="merged")&&q.headRefName===_&&q.baseRefName===l&&ve(i,d,_)),m&&(o.delete("unique_content"),o.add(`released_by_branch:${_}`))}}else l||o.add("base_branch_missing");if(e.includePrSync&&s&&i&&d){let R=Re(i,d,t.worktreePrTargetRepo??n.targetRepo);S=R.state,b=R.url??b,x=R.number??x}S==="open"&&o.add("pr_open"),S==="merged"&&!p&&!k&&o.add("pr_merged_not_reflected_locally");let T=e.includePrSync&&n.state==="pr_open"&&S!=="open";T&&o.add("stale_pr_open");let A;p?A="merged":(k||m)&&(A="released");let y=e.activeSession||f,w=n.state;!y&&A?w=A:T?w="pending_decision":!u&&n.state==="pending_decision"&&(w="cleanup_failed");let L=w==="merged"||w==="released",K=e.activeSession||f||!L&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||S==="open"||o.has("pr_merged_not_reflected_locally"),W=!K&&(w==="merged"||w==="released"||n.state==="dismissed"||n.state==="no_change"),I={checkedAt:r,repoExists:s,branchExists:u,worktreeExists:a,activeSession:e.activeSession===!0,dirtyTracked:f,topologyMerged:p,releaseNoopMerge:k,representedByTargetPrBranch:m,branchAheadCount:c,baseAheadCount:h,prState:S,prUrl:b,prNumber:x,reasons:[...o]};return{lifecycle:n,evidence:I,derivedState:w,cleanupSafe:W,preserve:K,reasons:[...o]}}var $n=J(()=>{Zt();fs();ms()});var Ae=J(()=>{Zt();ms();tl();fs();$n()});function ao(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function lo(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:ao(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function Ll(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:ao(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function nn(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:ao(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function Bl(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:ao(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 Wn=J(()=>{});import{existsSync as rh,readFileSync as oh}from"fs";function Fl(t){if(!t)return!1;let e=new Set(t.split(/\r?\n/).map(i=>i.trim().replace(/^[#*_\s]+|[:*_\s]+$/g,"").toLowerCase())),n=["root cause","summary","result"].some(i=>e.has(i)),r=["fix","changes","implementation","implemented"].some(i=>e.has(i)),o=["validation","verification","tests"].some(i=>e.has(i));return n&&r&&o}function rn(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?G(n):r?G(r):void 0,i=n?.getOutput?.().join(`
25
+ `);return n.some(o=>/^#{1,6}\s+\S/.test(o.trim()))&&n.some(o=>/^(?:[-*+]\s+|\d+\.\s+|```)/.test(o.trim()))?e:t}function ag(t){return t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:""}function nl(t){return/pull request already exists/i.test(t)||/createPullRequest/i.test(t)&&/already exists/i.test(t)}function rl(t,e,n){let r=Re(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 sl(t){try{return Je("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/)?.[1]}catch{return}}function dg(t,e,n){if(!n)return e;let r=sl(t);return r?`${r}:${e}`:e}function al(t,e,n,r,o,i,s={}){if(!ye())return{success:!1,error:"GitHub CLI (gh) is not available"};let a;try{return a=["pr","create","--base",n],(s.draft??!0)&&a.push("--draft"),i&&a.push("--repo",i),a.push("--head",dg(t,e,i)),r&&o?a.push("--title",r,"--body",il(o)):a.push("--fill-verbose"),{success:!0,prUrl:Je("gh",a,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}}catch(d){let l=d instanceof Error?d.message:String(d);if(nl(l))return rl(t,e,i)??{success:!1,error:l};if((s.draft??!0)&&a&&/draft/i.test(l))try{let u=a.filter(k=>k!=="--draft");return{success:!0,prUrl:Je("gh",u,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),warnings:["Target repo does not support draft PRs; created as regular (non-draft) PR instead."]}}catch(u){let f=u instanceof Error?u.message:String(u);return nl(f)?rl(t,e,i)??{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${f}`}:{success:!1,error:`Draft PR creation failed (${l}); non-draft retry also failed: ${f}`}}return{success:!1,error:l}}}function Re(t,e,n){if(!ye())return{exists:!1,state:"none"};try{let r=["pr","list","--head",e,"--state","all","--json","url,number,title,state,headRepositoryOwner,headRefName,baseRefName"];n&&r.push("--repo",n);let i=Je("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(!i)return{exists:!1,state:"none"};let s=JSON.parse(i),a=n?sl(t)?.toLowerCase():void 0,d=s.find(f=>f.headRefName===e&&(!a||f.headRepositoryOwner?.login?.toLowerCase()===a));if(!d)return{exists:!1,state:"none"};let u={exists:!0,state:ol(d.state),url:d.url,number:d.number,title:d.title};return d.headRefName!==void 0&&(u.headRefName=d.headRefName),d.baseRefName!==void 0&&(u.baseRefName=d.baseRefName),u}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function Ye(t,e,n){if(!ye())return{exists:!1,state:"none"};try{let r=["pr","view",e,"--json","url,number,title,state,headRefName,baseRefName"];n&&r.push("--repo",n);let o=Je("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim()),s={exists:!0,state:ol(i.state),url:i.url,number:i.number,title:i.title};return i.headRefName!==void 0&&(s.headRefName=i.headRefName),i.baseRefName!==void 0&&(s.baseRefName=i.baseRefName),s}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function dl(t,e,n){if(!ye())return{ok:!1,error:"GitHub CLI (gh) is not available"};try{let r=["pr","view",String(e),"--json","body"];n&&r.push("--repo",n);let o=Je("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),i=JSON.parse(o.trim());return{ok:!0,body:typeof i.body=="string"?i.body:void 0}}catch(r){let o=r instanceof Error?r.message:String(r);return`${e}${o}`,{ok:!1,error:o}}}function ll(t,e,n,r){if(!ye())return!1;try{let o=["pr","edit",String(e),"--body",il(n)];return r&&o.push("--repo",r),Je("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 ul(t,e,n,r){if(!ye())return!1;try{let o=["pr","edit",String(e),"--title",n];return r&&o.push("--repo",r),Je("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 cl(t,e,n,r){if(!ye())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),Je("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 At(t){let e=ag(t);return t.kind==="merge"?`✅ Merged: ${t.branch} → ${t.base??"main"}${e}`:t.kind==="pr-updated"?`✅ PR updated: ${t.prUrl??""}${e}`:t.targetRepo?`✅ PR opened against ${t.targetRepo}: ${t.prUrl??""}${e}`:`✅ PR opened: ${t.prUrl??""}${e}`}var sg,fs=J(()=>{Zt();sg=/(?<!\\)\\(?:r\\)?n/g});import{existsSync as gs}from"fs";function pl(){return new Date().toISOString()}function lg(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:pl(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function ug(t){let e=ml(t);return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(e&&gs(e)?Fe(e):void 0)}function ml(t){return typeof t.workdir=="string"&&t.workdir.length>0?t.workdir:void 0}function pt(t,e={}){let n=lg(t),r=pl(),o=new Set,i=ml(t),s=!!(i&&gs(i)),a=!!(t.worktreePath&&gs(t.worktreePath)),d=t.worktreeBranch,l=ug(t),u=!1,f=!1,p=!1,k=!1,m=!1,c,h,S="none",P=t.worktreePrUrl,x=t.worktreePrNumber;if(s||o.add("repo_missing"),d||o.add("branch_missing"),!a&&t.worktreePath&&o.add("worktree_missing"),e.activeSession&&o.add("active_session"),n.state==="pending_decision"&&o.add("pending_decision"),n.state==="merge_conflict_resolving"&&o.add("merge_conflict_resolving"),s&&i&&d&&(u=Pt(i,d),u||o.add("branch_missing")),a&&t.worktreePath&&(f=Rt(t.worktreePath),f&&o.add("dirty_worktree_entries")),s&&i&&u&&d&&l){let R=Jd(i,d,l);c=R?.ahead,h=R?.behind,p=ve(i,d,l),p?o.add("topology_merged"):(k=Hr(i,d,l),k&&o.add("merge_noop_content_already_on_base"),!k&&(c??0)>0&&o.add("unique_content"));let _=Se(i);if(e.includePrSync&&t.worktreePrUrl&&_&&_!==d&&_!==l){let q=Ye(i,t.worktreePrUrl,t.worktreePrTargetRepo??n.targetRepo);m=!!((q.state==="open"||q.state==="merged")&&q.headRefName===_&&q.baseRefName===l&&ve(i,d,_)),m&&(o.delete("unique_content"),o.add(`released_by_branch:${_}`))}}else l||o.add("base_branch_missing");if(e.includePrSync&&s&&i&&d){let R=Re(i,d,t.worktreePrTargetRepo??n.targetRepo);S=R.state,P=R.url??P,x=R.number??x}S==="open"&&o.add("pr_open"),S==="merged"&&!p&&!k&&o.add("pr_merged_not_reflected_locally");let C=e.includePrSync&&n.state==="pr_open"&&S!=="open";C&&o.add("stale_pr_open");let A;p?A="merged":(k||m)&&(A="released");let y=e.activeSession||f,w=n.state;!y&&A?w=A:C?w="pending_decision":!u&&n.state==="pending_decision"&&(w="cleanup_failed");let L=w==="merged"||w==="released",K=e.activeSession||f||!L&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||S==="open"||o.has("pr_merged_not_reflected_locally"),W=!K&&(w==="merged"||w==="released"||n.state==="dismissed"||n.state==="no_change"),I={checkedAt:r,repoExists:s,branchExists:u,worktreeExists:a,activeSession:e.activeSession===!0,dirtyTracked:f,topologyMerged:p,releaseNoopMerge:k,representedByTargetPrBranch:m,branchAheadCount:c,baseAheadCount:h,prState:S,prUrl:P,prNumber:x,reasons:[...o]};return{lifecycle:n,evidence:I,derivedState:w,cleanupSafe:W,preserve:K,reasons:[...o]}}var $n=J(()=>{Zt();fs();ms()});var Ae=J(()=>{Zt();ms();tl();fs();$n()});function ao(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function lo(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:ao(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function Ll(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:ao(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function nn(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:ao(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function Bl(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:ao(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 Wn=J(()=>{});import{existsSync as rh,readFileSync as oh}from"fs";function Fl(t){if(!t)return!1;let e=new Set(t.split(/\r?\n/).map(i=>i.trim().replace(/^[#*_\s]+|[:*_\s]+$/g,"").toLowerCase())),n=["root cause","summary","result"].some(i=>e.has(i)),r=["fix","changes","implementation","implemented"].some(i=>e.has(i)),o=["validation","verification","tests"].some(i=>e.has(i));return n&&r&&o}function rn(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?G(n):r?G(r):void 0,i=n?.getOutput?.().join(`
26
26
  `).trim(),s;if(r?.outputPath&&rh(r.outputPath))try{s=oh(r.outputPath,"utf-8").trim()}catch{}let a=Fl(i),d=Fl(s),l=a===d?(s?.length??0)>(i?.length??0)?s:i:d?s:i;return{activeSession:n,persistedSession:r,persistedRef:o,sessionName:n?.name??r?.name??e,prompt:n?.prompt??r?.prompt,outputPreview:l?l.slice(-12e3):void 0,worktreePath:n?.worktreePath??r?.worktreePath,originalWorkdir:n?.originalWorkdir??r?.workdir,branchName:n?.worktreeBranch??r?.worktreeBranch,notificationTarget:n??(r?{id:o??e,name:r.name,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,goalTaskId:r.goalTaskId,...r.costUsd!==void 0?{costUsd:r.costUsd}:{},...r.createdAt!==void 0?{createdAt:r.createdAt}:{},...r.completedAt!==void 0?{completedAt:r.completedAt}:{},...r.harness!==void 0?{harnessName:r.harness}:{},...r.model!==void 0?{model:r.model}:{}}:void 0)}}function Ln(t){return[...t.persistedSession?ge(t.persistedSession):[],...t.activeSession?ge(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function ih(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 uo(t,e,n={}){let{activeSession:r,persistedSession:o}=ih(t,e),i=pt({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 co(t){let e=t.list("all").filter(o=>o.worktreePath),n=t.listPersistedSessions().filter(o=>o.worktreePath),r=new Map;for(let o of n){if(!o.worktreePath)continue;let i=O(o),s=o.sessionId??i??o.harnessSessionId;s&&r.set(s,{id:o.sessionId??i??o.harnessSessionId,name:o.name,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,workdir:o.workdir,worktreeMerged:o.worktreeMerged,worktreeMergedAt:o.worktreeMergedAt,worktreePrUrl:o.worktreePrUrl,backendConversationId:i,harnessSessionId:o.harnessSessionId})}for(let o of e)o.worktreePath&&r.set(o.id,{id:o.id,name:o.name,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,workdir:o.originalWorkdir??o.workdir,worktreeMerged:void 0,worktreeMergedAt:void 0,worktreePrUrl:void 0,backendConversationId:O(o),harnessSessionId:o.harnessSessionId});return Array.from(r.values())}function po(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function xt(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 mo(t){switch(t){case"active_session":return"active session";case"pending_decision":return"pending decision";case"merge_conflict_resolving":return"conflict resolving";case"dirty_tracked_changes":case"dirty_worktree_entries":return"dirty worktree";case"unique_content":return"still has unique content";case"topology_merged":return"merged by ancestry";case"merge_noop_content_already_on_base":return"content already on base";case"pr_open":return"PR open";case"pr_merged_not_reflected_locally":return"merged PR not reflected locally";case"stale_pr_open":return"stale PR-open metadata";case"repo_missing":return"repo missing";case"branch_missing":return"branch missing";case"worktree_missing":return"worktree missing";case"base_branch_missing":return"base branch missing";default:return t.startsWith("released_by_branch:")?`represented by ${t.slice(19)}`:t.startsWith("represented_by_branch:")?`represented by ${t.slice(22)}`:t.replaceAll("_"," ")}}var Bn=J(()=>{ne();$n()});function Kl(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
27
27
  `).split(`
28
28
  `).map(r=>r.trim()).reduce((r,o)=>o?(r.push(o),r):(e.preserveBlankLines&&r[r.length-1]!==""&&r.push(o),r),[]).join(e.preserveBlankLines?`
29
- `:" ").replace(/[ \t]+/g," ").trim()||void 0}function Tt(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function qn(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_-]{${Ul},}\\b`,"g"),"[redacted token]")}function Un(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_-]{${Ul},}\\b`).test(t)}function uh(t){let e=Kl(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=qn(n).replace(/\s+/g," ").trim();return r?Tt(r,180):void 0}function Vl(t){return qn(t.trim()).replace(/\s+/g," ").trim()}function ch(t,e){return t?.commitMessages.map(n=>Vl(n.message)).filter(Boolean).slice(0,e)??[]}function _s(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function jl(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function ph(t){let e={summary:[],changes:[],validation:[]},n;for(let r of(t??"").split(/\r?\n/)){let o=r.trim(),i=o.replace(/^[#*_\s]+|[:*_\s]+$/g,"").toLowerCase();if(/^(?:root cause|summary|result)$/.test(i)){n="summary";continue}if(/^(?:fix|changes|implementation|implemented)$/.test(i)){n="changes";continue}if(/^(?:validation|verification|tests)$/.test(i)){n="validation";continue}if(/^[A-Za-z][A-Za-z /_-]{2,30}:$/.test(o)){n=void 0;continue}let s=o.match(/^[-*•]\s+(.+)$/)?.[1]?.trim();if(!n||!s||s.length<8)continue;let a=Tt(Ue(s),n==="validation"?160:180);a&&!Un(a)&&e[n].push(a)}return{summary:e.summary.slice(0,5),changes:e.changes.slice(0,10),validation:e.validation.slice(0,5)}}function mh(t){let e=uh(t.prompt),n=t.diffSummary,r=ph(t.outputPreview);return{sessionName:t.sessionName,branchName:t.branchName,objective:e,stats:n?{commits:n.commits,filesChanged:n.filesChanged,insertions:n.insertions,deletions:n.deletions}:void 0,changedFiles:n?.changedFiles??[],commitSubjects:ch(n,5),sessionSummary:r.summary,sessionChanges:r.changes,validation:r.validation.length>0?r.validation:_s(),notes:jl()}}function ho(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 Gl(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 Fn(t,e,n){let r=t.toLowerCase();return Gl(e,n.objective).some(o=>r.includes(o))}function ql(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function $s(t,e){let n=new Set(e.changedFiles);if([...t.matchAll(/(?:^|[^\w.-])((?:\.?[\w-][\w.-]*\/)+(?:\.?[\w-][\w.-]*))(?![\w.-])/g)].map(p=>p[1]).some(p=>/\.[A-Za-z0-9]+$/.test(p)&&!n.has(p)))return!0;let o=new Set(e.changedFiles.filter(p=>!p.includes("/"))),i=String.raw`\.[a-z0-9][\w.-]*`,s=t.matchAll(new RegExp(`[\\\`"'](${i})[\\\`"']`,"g"));for(let p of s)if(!o.has(p[1]))return!0;let a=t.matchAll(new RegExp(String.raw`\b(?:file|files|path|paths|changed|changes|updated?|updates?|modified?|modifies|touched?|touches|added?|adds?|removed?|removes?|deleted?|deletes?)\s+(?:the\s+)?(${i})(?![\w.-])`,"gi"));for(let p of a)if(!o.has(p[1]))return!0;if(o.size===0)return!1;let d=new Set([...o].map(p=>p.match(/\.([A-Za-z0-9]+)$/)?.[1]?.toLowerCase()).filter(p=>!!p)),l=String.raw`[A-Za-z0-9][\w.-]*\.([A-Za-z0-9]+)`,u=t.matchAll(new RegExp(`[\\\`"'](${l})[\\\`"']`,"g"));for(let p of u){let k=p[1],m=p[2]?.toLowerCase();if(m!==void 0&&d.has(m)&&!o.has(k)&&!ql(k))return!0}return[...t.matchAll(new RegExp(String.raw`\b(?:file|files|path|paths|changed|changes|updated?|updates?|modified?|modifies|touched?|touches|added?|adds?|removed?|removes?|deleted?|deletes?)\s+(?:the\s+)?(${l})\b`,"gi"))].some(p=>{let k=p[1],m=p[2]?.toLowerCase();return m!==void 0&&d.has(m)&&!o.has(k)&&!ql(k)})}function Ue(t){return qn(t).replace(/\s+/g," ").trim()}function fh(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||!ho(r.summary,5,180)||!ho(r.changes,10,160)||!ho(r.validation,5,160)||!ho(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(a=>Un(a)||Fn(a,n,e)))return;let i={title:Ue(r.title),summary:r.summary.map(Ue),changes:r.changes.map(Ue),validation:r.validation.map(Ue),notes:r.notes.map(Ue)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(a=>!a||Un(a)||Fn(a,n,e))&&!s.some(a=>$s(a,e)))return i}function Ms(t,e,n={}){let r=Tt(qn(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),o=t.sessionSummary.length>0||t.sessionChanges.length>0,i=o?t.commitSubjects[0]?.replace(/^(?:feat|fix|chore|refactor|test|docs|build|ci|perf)(?:\([^)]*\))?!?:\s*/i,""):void 0,s=Tt(i||`OpenClaw agent changes: ${r}`,90),a=o?lh:n.reason==="provider-failed"||n.reason==="provider-invalid"?Os:Ds,d=[a,...t.sessionSummary,`Session: ${r}.`,...t.objective?[`Objective: ${t.objective}`]:[],...t.stats?[`Scope: ${t.stats.commits} commits, ${t.stats.filesChanged} files changed (+${t.stats.insertions} / -${t.stats.deletions}).`]:["Scope: Diff summary was unavailable when the PR body was generated."]],l=t.sessionChanges.length>0?t.sessionChanges:t.changedFiles.length>0?t.changedFiles.slice(0,10).map(S=>`\`${S}\``):["Review the pushed worktree branch for the full set of changes."],u=t.sessionChanges.length===0&&t.changedFiles.length>10?[`...and ${t.changedFiles.length-10} more changed files.`]:[],f=["Fallback metadata is conservative; review the diff and CI/checks before marking the draft PR ready.",...t.notes],p={title:s,summary:d,changes:[...l,...u],validation:t.validation,notes:f},k=!1,m=!1,c=S=>{let b=Ue(S);if(Fn(b,e,t)){k=!0;let x=Gl(e,t.objective);for(let T of x){let A=new RegExp(T.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");b=b.replace(A,"[redacted prompt detail]")}b=Ue(b)}return $s(b,t)&&(m=!0,b="[redacted file reference outside change set]"),b=Ue(b),(Fn(b,e,t)||Un(b))&&(k=!0,b="[redacted prompt detail]"),b};if(p={title:c(p.title)||Tt(`OpenClaw agent changes: ${r}`,90),summary:p.summary.map(c).filter(S=>S&&S.length>0),changes:p.changes.map(c).filter(S=>S&&S.length>0),validation:p.validation.map(c).filter(S=>S&&S.length>0),notes:p.notes.map(c).filter(S=>S&&S.length>0)},p.summary.length===0&&(p.summary=[a]),p.changes.length===0&&(p.changes=["Review the pushed worktree branch for the full set of changes."]),p.validation.length===0&&(p.validation=_s()),p.notes.length===0&&(p.notes=jl()),k||m){let S="Some content was stripped from fallback metadata due to safety checks (prompt leak guard or references to files outside the diff).";p.notes.some(b=>b.toLowerCase().includes("stripped")||b.toLowerCase().includes("sanitized"))||(p.notes=[...p.notes,S])}let h=[p.title,...p.summary,...p.changes,...p.validation,...p.notes];if(h.some(S=>!S)||h.some(S=>Un(S)||Fn(S,e,t))||h.some(S=>$s(S,t))){let S=Tt(qn(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);p={title:Tt(`OpenClaw agent changes: ${S}`,90),summary:["Deterministic fallback metadata (sanitized for safety)."],changes:t.changedFiles.length>0?t.changedFiles.slice(0,5).map(b=>`\`${b}\``):["See the worktree branch diff for the full set of changes."],validation:_s(),notes:["Fallback metadata was hardened because prompt-leak or unknown-file checks were triggered after initial construction.","Review the actual diff, session output, and CI before merging."]}}if(t.branchName){let S=Ue(t.branchName);p.notes.some(b=>b.toLowerCase().includes(S.toLowerCase()))||(p.notes=[...p.notes,`Branch: ${S}`])}return p}async function Kn(t){let e=mh({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,outputPreview:t.outputPreview,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:Ms(e,t.prompt,{reason:"no-provider"}),evidence:e,fallbackReason:"no-provider"};try{let n=await t.provider.generatePrMetadata(e),r=fh(yh(n),e,t.prompt);return r?{ok:!0,metadata:r,evidence:e}:{ok:!0,metadata:Ms(e,t.prompt,{reason:"provider-invalid"}),evidence:e,fallbackReason:"provider-invalid"}}catch(n){return`${n instanceof Error?n.message:String(n)}`,{ok:!0,metadata:Ms(e,t.prompt,{reason:"provider-failed"}),evidence:e,fallbackReason:"provider-failed"}}}function yo(){let t=rt(),e=gh(t);if(e)return{async generatePrMetadata(n){if(typeof e.generatePrMetadata=="function")return await e.generatePrMetadata(n);if(typeof e.generatePullRequestMetadata=="function")return await e.generatePullRequestMetadata(n);let r=hh(n);if(typeof e.generateObject=="function")return await e.generateObject({task:"openclaw-code-agent.pr-metadata",prompt:r,input:n});if(typeof e.generateText=="function")return await e.generateText({task:"openclaw-code-agent.pr-metadata",prompt:r});if(typeof e.complete=="function")return await e.complete({prompt:r})}}}function gh(t){return[t?.prMetadata,t?.pullRequestMetadata,t?.llm,t?.ai,t?.model,t?.models].find(n=>!!(n&&typeof n=="object"&&(typeof n.generatePrMetadata=="function"||typeof n.generatePullRequestMetadata=="function"||typeof n.generateObject=="function"||typeof n.generateText=="function"||typeof n.complete=="function")))}function hh(t){return["Generate concise pull request metadata for OpenClaw Code Agent work.",'Return only JSON with shape {"title":"...","summary":["..."],"changes":["..."],"validation":["..."],"notes":["..."]}.',"Use only the supplied evidence. Do not invent files, commands, tests, risks, links, paths, prompts, chat IDs, credentials, tokens, or secrets.","Keep the title under 90 characters. Keep bullets short and reviewable.","","Evidence:",JSON.stringify(t,null,2)].join(`
29
+ `:" ").replace(/[ \t]+/g," ").trim()||void 0}function Tt(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function qn(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_-]{${Ul},}\\b`,"g"),"[redacted token]")}function Un(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_-]{${Ul},}\\b`).test(t)}function uh(t){let e=Kl(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=qn(n).replace(/\s+/g," ").trim();return r?Tt(r,180):void 0}function Vl(t){return qn(t.trim()).replace(/\s+/g," ").trim()}function ch(t,e){return t?.commitMessages.map(n=>Vl(n.message)).filter(Boolean).slice(0,e)??[]}function _s(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function jl(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function ph(t){let e={summary:[],changes:[],validation:[]},n;for(let r of(t??"").split(/\r?\n/)){let o=r.trim(),i=o.replace(/^[#*_\s]+|[:*_\s]+$/g,"").toLowerCase();if(/^(?:root cause|summary|result)$/.test(i)){n="summary";continue}if(/^(?:fix|changes|implementation|implemented)$/.test(i)){n="changes";continue}if(/^(?:validation|verification|tests)$/.test(i)){n="validation";continue}if(/^[A-Za-z][A-Za-z /_-]{2,30}:$/.test(o)){n=void 0;continue}let s=o.match(/^[-*•]\s+(.+)$/)?.[1]?.trim();if(!n||!s||s.length<8)continue;let a=Tt(Ue(s),n==="validation"?160:180);a&&!Un(a)&&e[n].push(a)}return{summary:e.summary.slice(0,5),changes:e.changes.slice(0,10),validation:e.validation.slice(0,5)}}function mh(t){let e=uh(t.prompt),n=t.diffSummary,r=ph(t.outputPreview);return{sessionName:t.sessionName,branchName:t.branchName,objective:e,stats:n?{commits:n.commits,filesChanged:n.filesChanged,insertions:n.insertions,deletions:n.deletions}:void 0,changedFiles:n?.changedFiles??[],commitSubjects:ch(n,5),sessionSummary:r.summary,sessionChanges:r.changes,validation:r.validation.length>0?r.validation:_s(),notes:jl()}}function ho(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 Gl(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 Fn(t,e,n){let r=t.toLowerCase();return Gl(e,n.objective).some(o=>r.includes(o))}function ql(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function $s(t,e){let n=new Set(e.changedFiles);if([...t.matchAll(/(?:^|[^\w.-])((?:\.?[\w-][\w.-]*\/)+(?:\.?[\w-][\w.-]*))(?![\w.-])/g)].map(p=>p[1]).some(p=>/\.[A-Za-z0-9]+$/.test(p)&&!n.has(p)))return!0;let o=new Set(e.changedFiles.filter(p=>!p.includes("/"))),i=String.raw`\.[a-z0-9][\w.-]*`,s=t.matchAll(new RegExp(`[\\\`"'](${i})[\\\`"']`,"g"));for(let p of s)if(!o.has(p[1]))return!0;let a=t.matchAll(new RegExp(String.raw`\b(?:file|files|path|paths|changed|changes|updated?|updates?|modified?|modifies|touched?|touches|added?|adds?|removed?|removes?|deleted?|deletes?)\s+(?:the\s+)?(${i})(?![\w.-])`,"gi"));for(let p of a)if(!o.has(p[1]))return!0;if(o.size===0)return!1;let d=new Set([...o].map(p=>p.match(/\.([A-Za-z0-9]+)$/)?.[1]?.toLowerCase()).filter(p=>!!p)),l=String.raw`[A-Za-z0-9][\w.-]*\.([A-Za-z0-9]+)`,u=t.matchAll(new RegExp(`[\\\`"'](${l})[\\\`"']`,"g"));for(let p of u){let k=p[1],m=p[2]?.toLowerCase();if(m!==void 0&&d.has(m)&&!o.has(k)&&!ql(k))return!0}return[...t.matchAll(new RegExp(String.raw`\b(?:file|files|path|paths|changed|changes|updated?|updates?|modified?|modifies|touched?|touches|added?|adds?|removed?|removes?|deleted?|deletes?)\s+(?:the\s+)?(${l})\b`,"gi"))].some(p=>{let k=p[1],m=p[2]?.toLowerCase();return m!==void 0&&d.has(m)&&!o.has(k)&&!ql(k)})}function Ue(t){return qn(t).replace(/\s+/g," ").trim()}function fh(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||!ho(r.summary,5,180)||!ho(r.changes,10,160)||!ho(r.validation,5,160)||!ho(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(a=>Un(a)||Fn(a,n,e)))return;let i={title:Ue(r.title),summary:r.summary.map(Ue),changes:r.changes.map(Ue),validation:r.validation.map(Ue),notes:r.notes.map(Ue)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(a=>!a||Un(a)||Fn(a,n,e))&&!s.some(a=>$s(a,e)))return i}function Ms(t,e,n={}){let r=Tt(qn(t.sessionName).replace(/[-_]+/g," ").replace(/\s+/g," ").trim()||"agent worktree",80),o=t.sessionSummary.length>0||t.sessionChanges.length>0,i=o?t.commitSubjects[0]?.replace(/^(?:feat|fix|chore|refactor|test|docs|build|ci|perf)(?:\([^)]*\))?!?:\s*/i,""):void 0,s=Tt(i||`OpenClaw agent changes: ${r}`,90),a=o?lh:n.reason==="provider-failed"||n.reason==="provider-invalid"?Os:Ds,d=[a,...t.sessionSummary,`Session: ${r}.`,...t.objective?[`Objective: ${t.objective}`]:[],...t.stats?[`Scope: ${t.stats.commits} commits, ${t.stats.filesChanged} files changed (+${t.stats.insertions} / -${t.stats.deletions}).`]:["Scope: Diff summary was unavailable when the PR body was generated."]],l=t.sessionChanges.length>0?t.sessionChanges:t.changedFiles.length>0?t.changedFiles.slice(0,10).map(S=>`\`${S}\``):["Review the pushed worktree branch for the full set of changes."],u=t.sessionChanges.length===0&&t.changedFiles.length>10?[`...and ${t.changedFiles.length-10} more changed files.`]:[],f=["Fallback metadata is conservative; review the diff and CI/checks before marking the draft PR ready.",...t.notes],p={title:s,summary:d,changes:[...l,...u],validation:t.validation,notes:f},k=!1,m=!1,c=S=>{let P=Ue(S);if(Fn(P,e,t)){k=!0;let x=Gl(e,t.objective);for(let C of x){let A=new RegExp(C.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"gi");P=P.replace(A,"[redacted prompt detail]")}P=Ue(P)}return $s(P,t)&&(m=!0,P="[redacted file reference outside change set]"),P=Ue(P),(Fn(P,e,t)||Un(P))&&(k=!0,P="[redacted prompt detail]"),P};if(p={title:c(p.title)||Tt(`OpenClaw agent changes: ${r}`,90),summary:p.summary.map(c).filter(S=>S&&S.length>0),changes:p.changes.map(c).filter(S=>S&&S.length>0),validation:p.validation.map(c).filter(S=>S&&S.length>0),notes:p.notes.map(c).filter(S=>S&&S.length>0)},p.summary.length===0&&(p.summary=[a]),p.changes.length===0&&(p.changes=["Review the pushed worktree branch for the full set of changes."]),p.validation.length===0&&(p.validation=_s()),p.notes.length===0&&(p.notes=jl()),k||m){let S="Some content was stripped from fallback metadata due to safety checks (prompt leak guard or references to files outside the diff).";p.notes.some(P=>P.toLowerCase().includes("stripped")||P.toLowerCase().includes("sanitized"))||(p.notes=[...p.notes,S])}let h=[p.title,...p.summary,...p.changes,...p.validation,...p.notes];if(h.some(S=>!S)||h.some(S=>Un(S)||Fn(S,e,t))||h.some(S=>$s(S,t))){let S=Tt(qn(t.sessionName).replace(/[-_]+/g," ").trim()||"session",60);p={title:Tt(`OpenClaw agent changes: ${S}`,90),summary:["Deterministic fallback metadata (sanitized for safety)."],changes:t.changedFiles.length>0?t.changedFiles.slice(0,5).map(P=>`\`${P}\``):["See the worktree branch diff for the full set of changes."],validation:_s(),notes:["Fallback metadata was hardened because prompt-leak or unknown-file checks were triggered after initial construction.","Review the actual diff, session output, and CI before merging."]}}if(t.branchName){let S=Ue(t.branchName);p.notes.some(P=>P.toLowerCase().includes(S.toLowerCase()))||(p.notes=[...p.notes,`Branch: ${S}`])}return p}async function Kn(t){let e=mh({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,outputPreview:t.outputPreview,diffSummary:t.diffSummary});if(!t.provider)return{ok:!0,metadata:Ms(e,t.prompt,{reason:"no-provider"}),evidence:e,fallbackReason:"no-provider"};try{let n=await t.provider.generatePrMetadata(e),r=fh(yh(n),e,t.prompt);return r?{ok:!0,metadata:r,evidence:e}:{ok:!0,metadata:Ms(e,t.prompt,{reason:"provider-invalid"}),evidence:e,fallbackReason:"provider-invalid"}}catch(n){return`${n instanceof Error?n.message:String(n)}`,{ok:!0,metadata:Ms(e,t.prompt,{reason:"provider-failed"}),evidence:e,fallbackReason:"provider-failed"}}}function yo(){let t=rt(),e=gh(t);if(e)return{async generatePrMetadata(n){if(typeof e.generatePrMetadata=="function")return await e.generatePrMetadata(n);if(typeof e.generatePullRequestMetadata=="function")return await e.generatePullRequestMetadata(n);let r=hh(n);if(typeof e.generateObject=="function")return await e.generateObject({task:"openclaw-code-agent.pr-metadata",prompt:r,input:n});if(typeof e.generateText=="function")return await e.generateText({task:"openclaw-code-agent.pr-metadata",prompt:r});if(typeof e.complete=="function")return await e.complete({prompt:r})}}}function gh(t){return[t?.prMetadata,t?.pullRequestMetadata,t?.llm,t?.ai,t?.model,t?.models].find(n=>!!(n&&typeof n=="object"&&(typeof n.generatePrMetadata=="function"||typeof n.generatePullRequestMetadata=="function"||typeof n.generateObject=="function"||typeof n.generateText=="function"||typeof n.complete=="function")))}function hh(t){return["Generate concise pull request metadata for OpenClaw Code Agent work.",'Return only JSON with shape {"title":"...","summary":["..."],"changes":["..."],"validation":["..."],"notes":["..."]}.',"Use only the supplied evidence. Do not invent files, commands, tests, risks, links, paths, prompts, chat IDs, credentials, tokens, or secrets.","Keep the title under 90 characters. Keep bullets short and reviewable.","","Evidence:",JSON.stringify(t,null,2)].join(`
30
30
  `)}function yh(t){if(typeof t!="string")return t&&typeof t=="object"&&"object"in t?t.object:t&&typeof t=="object"&&"data"in t?t.data:t;let e=t.trim();if(!e)return;let n=e.replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/,"").trim();try{return JSON.parse(n)}catch{return}}function ko(t){return t?t.includes(Es)||t.includes(Ds)||t.includes(Os):!1}function So(t){return t?t.trim()===Es||t.includes(Ds)||t.includes(Os):!1}function vo(t){return t?/^OpenClaw agent changes:/i.test(t.trim()):!1}function Vn(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} ${Vl(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("---",Es),e.join(`
31
- `)}var Ul,Es,Ds,Os,lh,Ns=J(()=>{yt();Ul=32,Es="Generated with [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)",Ds="Deterministic fallback metadata generated because no LLM PR metadata provider is configured.",Os="Deterministic fallback metadata generated because the LLM PR metadata provider failed or returned unusable output.",lh="PR metadata generated from the coding agent's final session report."});var Xl={};Zc(Xl,{buildPrCompletionWakeOutcomeKey:()=>Fs,buildPrMetadata:()=>Kn,buildPrOutcomeDetailLines:()=>Bs,createRuntimePrMetadataProvider:()=>yo,discoverExistingTargetPr:()=>Jl,formatPrBody:()=>Vn,isOcaFallbackPrBody:()=>So,isOcaGeneratedPrBody:()=>ko,isOcaGeneratedPrTitle:()=>vo,makeAgentPrTool:()=>jn,normalizeForceNewReplacementPrStatus:()=>Ls,refreshOpenPrMetadata:()=>Zl,resolveExistingTargetPrUpdateBranch:()=>Ql,resolveExistingTargetPrUpdateSourceBranch:()=>Yl,shouldIgnoreClosedTargetPrForForceNew:()=>zl});import{execFileSync as wo}from"child_process";import{existsSync as kh}from"fs";function Sh(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function zl(t,e){return t===!0&&e?.exists===!0&&e.state!=="open"}function Ls(t,e,n){return n.forceNewIgnoresClosedTargetPr&&t.exists&&t.state!=="open"&&e?.exists===!0&&(t.url!==void 0&&t.url===e.url||t.number!==void 0&&t.number===e.number)?{exists:!1,state:"none"}:t}function vh(t,e){try{let n=wo("git",["-C",t,"worktree","list","--porcelain"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r;for(let o of n.split(/\r?\n/)){if(o.startsWith("worktree ")){r=o.slice(9);continue}if(o===`branch refs/heads/${e}`)return r;o===""&&(r=void 0)}}catch{return}}function Hl(t,e,n){try{let r=vh(t,e);return r?(wo("git",["-C",r,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1}):(Se(t)===e?wo("git",["-C",t,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):wo("git",["-C",t,"branch","-f",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1})}catch(r){return{success:!1,error:`Failed to fast-forward existing PR branch ${e} from ${n}: ${r instanceof Error?r.message:String(r)}`}}}function Ql(t){let{repoDir:e,sourceBranch:n,targetPrStatus:r}=t;if(!r.exists||r.state!=="open"||!r.headRefName)return{success:!1,error:"Target PR is not an open PR with a resolvable head branch."};let o=r.headRefName,i=Gr(e,o),s=i??o;if(o===n&&!i)return{success:!0,branchName:n,alreadyRepresented:!1};if(!Pt(e,o)&&!i)return{success:!1,error:`Target PR branch ${o} is not available locally. Fetch it before updating the PR.`};if(ve(e,n,s)){if(i&&!ve(e,i,o)&&ve(e,o,i)){let a=Hl(e,o,i);if("error"in a)return a}return{success:!0,branchName:o,alreadyRepresented:!!i}}return Se(e)===o&&ve(e,s,o)&&ve(e,n,o)?{success:!0,branchName:o,alreadyRepresented:!1}:ve(e,s,n)?Hl(e,o,n):{success:!1,error:`Refusing to create a sibling PR: target PR branch ${o} and follow-up branch ${n} have diverged. Reconcile them manually, then run agent_pr again.`}}function Jl(t){let e=Se(t.repoDir);if(!e||e!==t.expectedParentBranch||e===t.worktreeBranch||e===t.baseBranch)return;let n=Re(t.repoDir,e,t.targetRepo);return n.exists&&n.state==="open"&&n.headRefName===e&&(!n.baseRefName||n.baseRefName===t.baseBranch)?n:void 0}function Yl(t){let e=t.targetPrStatus.headRefName;if(!e||e===t.fallbackBranch)return t.fallbackBranch;let n=Se(t.repoDir);return n===e?n:t.fallbackBranch}function Bs(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 Fs(t){let e=t.prNumber!==void 0?`#${t.prNumber}`:t.prUrl??"unknown-pr",n=t.diffSummary?.commitMessages.map(o=>o.hash.trim()).filter(Boolean).join(","),r=t.action==="updated"?n||[`commits:${t.diffSummary?.commits??"unknown"}`,`insertions:${t.diffSummary?.insertions??"unknown"}`,`deletions:${t.diffSummary?.deletions??"unknown"}`].join(","):"created";return["worktree-pr",t.action,t.targetRepo??"default-repo",e,t.branchName,r].join(":")}async function Zl(t){let e=t.prStatus.number??t.prStatus.url;if(!e)return{status:"skipped",reason:"missing-pr-identity"};let n=t.operations?.getBody??dl,r=t.operations?.updateBody??ll,o=t.operations?.updateTitle??ul;if(t.explicitTitle!==void 0||t.explicitBody!==void 0){let m=t.explicitTitle===void 0?!1:o(t.repoDir,e,t.explicitTitle,t.targetRepo);if(t.explicitTitle!==void 0&&!m)return{status:"failed",reason:"failed to update explicit PR title"};let c=t.explicitBody===void 0?!1:r(t.repoDir,e,t.explicitBody,t.targetRepo);return t.explicitBody!==void 0&&!c?{status:"failed",reason:"failed to update explicit PR body"}:{status:"updated",updatedTitle:m,updatedBody:c,reason:"explicit"}}let i=n(t.repoDir,e,t.targetRepo);if(i.ok===!1)return{status:"failed",reason:`failed to read PR body: ${i.error}`};let s=i.body??"";if(s.trim()===""&&!t.forceRefresh)return{status:"skipped",reason:"empty-body"};if(!(t.forceRefresh||ko(s)))return{status:"skipped",reason:"human-edited"};let d=await Kn({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,outputPreview:t.outputPreview,diffSummary:t.diffSummary,provider:t.metadataProvider});if(d.ok===!1)return{status:"failed",reason:d.error};let l=d.evidence.sessionSummary.length>0||d.evidence.sessionChanges.length>0;if(d.fallbackReason!==void 0&&(!l||!So(s)))return{status:"failed",reason:"generated PR metadata was unavailable; preserved existing generated PR metadata"};let u=Vn({sessionName:t.sessionName,metadata:d.metadata,diffSummary:t.diffSummary}),f=t.forceRefresh||vo(t.prStatus.title),p=!1;if(f&&t.prStatus.title?.trim()!==d.metadata.title.trim()&&(p=o(t.repoDir,e,d.metadata.title,t.targetRepo),!p))return{status:"failed",reason:"failed to update generated PR title"};if(u.trim()===s.trim())return p?{status:"updated",updatedTitle:p,updatedBody:!1,reason:t.forceRefresh?"forced":"generated"}:{status:"skipped",reason:"unchanged"};let k=r(t.repoDir,e,u,t.targetRepo);return k?{status:"updated",updatedTitle:p,updatedBody:k,reason:t.forceRefresh?"forced":"generated"}:{status:"failed",reason:"failed to update generated PR body"}}function Ws(t){if(t.status==="updated"){if(t.updatedTitle&&t.updatedBody)return t.reason==="explicit"?"📝 Replaced PR title/body with explicitly provided metadata.":"📝 Refreshed PR title/body from current OpenClaw metadata.";if(t.updatedTitle)return t.reason==="explicit"?"📝 Replaced PR title with the explicitly provided title.":"📝 Refreshed PR title from current OpenClaw metadata.";if(t.updatedBody)return t.reason==="explicit"?"📝 Replaced PR body with the explicitly provided body.":"📝 Refreshed PR body from current OpenClaw metadata."}if(t.status==="failed")return`⚠️ PR metadata refresh failed: ${t.reason}`}function jn(t,e={}){return{name:"agent_pr",description:"Create or update a GitHub PR for a worktree branch. Handles full PR lifecycle: creates new PRs, updates existing open PRs with comments, and handles merged/closed PRs. Pushes the branch, syncs PR state, and persists metadata.",parameters:g.Object({session:g.String({description:"Session name or ID to create/update PR for"}),title:g.Optional(g.String({description:"PR title (default: auto-generated from session name)"})),body:g.Optional(g.String({description:"PR body (default: auto-generated from commit summary). For existing open PRs, passing body explicitly replaces the PR body."})),update_body:g.Optional(g.Boolean({description:"For existing open PRs, refresh generated PR metadata when true. Alias for update_metadata; retained for compatibility."})),update_metadata:g.Optional(g.Boolean({description:"For existing open PRs, refresh title/body when true. Default: only refresh bodies clearly generated by OpenClaw and titles that are fallback-generated, or explicit title/body values."})),base_branch:g.Optional(g.String({description:"Base branch for the PR (default: detected from repo)"})),force_new:g.Optional(g.Boolean({description:"Force creation of a new PR even if one exists (default: false)"})),target_repo:g.Optional(g.String({description:"Target repository for cross-repo PRs (e.g. 'openai/codex'). Auto-detected from 'upstream' remote if not set."}))}),async execute(n,r){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}],meta:{success:!1,state:"error"}};if(!Sh(r))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, title?, body?, update_body?, update_metadata?, base_branch?, force_new? }."}],meta:{success:!1,state:"error"}};if(!ye())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=rn(v,r.session),i=o.activeSession,s=o.persistedSession;if(!i&&!s)return{content:[{type:"text",text:`Error: Session "${r.session}" not found.`}],meta:{success:!1,state:"error"}};let{worktreePath:a,originalWorkdir:d,sessionName:l}=o,{branchName:u}=o;if(!a||!d)return{content:[{type:"text",text:`Error: Session "${r.session}" does not have a worktree.`}],meta:{success:!1,state:"error"}};if(!u)return{content:[{type:"text",text:`Error: Cannot determine branch name for worktree ${a}. The worktree may have been removed and no persisted branch name is available.`}],meta:{success:!1,state:"error"}};kh(a)||`${a}${u}${d}`;let f=r.base_branch??Fe(d),p=e.metadataProvider??yo(),k=R=>{let _=Bl({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??f,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:R.prUrl,prNumber:R.prNumber,baseBranch:f,targetRepo:R.targetRepo,disposition:R.disposition});for(let q of Ln(o))v.updatePersistedSession(q,_)},m=_n(d,r.target_repo??s?.worktreePrTargetRepo),c=s?.worktreePrUrl??i?.worktreePrUrl,h=c?Ye(d,c,m):void 0;if(c&&!h?.exists)return{content:[{type:"text",text:`Error: Session is associated with ${c}, but that PR could not be resolved. Refusing to create a sibling PR from ${u}.`}],meta:{success:!1,state:"error"}};let S=zl(r.force_new,h),b=S?void 0:c,x=!c&&!r.force_new?Jl({repoDir:d,worktreeBranch:u,expectedParentBranch:s?.worktreeParentBranch??i?.worktreeParentBranch,baseBranch:f,targetRepo:m}):void 0,T=S?void 0:h??x,A=b??x?.url,y=!1;if(T?.exists&&T.state==="open"){let R=Yl({repoDir:d,fallbackBranch:u,targetPrStatus:T}),_=Ql({repoDir:d,sourceBranch:R,targetPrStatus:T});if("error"in _)return{content:[{type:"text",text:`Error: ${_.error}`}],meta:{success:!1,state:"error"}};u=_.branchName,y=_.alreadyRepresented}let w=v.resolveRepoPolicy(d),L=Ls(T?.exists?T:Re(d,u,m),h,{forceNewIgnoresClosedTargetPr:S}),K=L.exists&&L.state==="open";if(w?.policy==="never-pr"&&!K)return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${w.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};if(w&&!w.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${w.identity?.repoRoot??d}. Provider: ${w.provider}.`}],meta:{success:!1,state:"error"}};if((!T||T.state==="open")&&!y&&!Jr(d,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let I=Ls(A?Ye(d,A,m):Re(d,u,m),h,{forceNewIgnoresClosedTargetPr:S});if(r.force_new&&I.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${I.state}).
31
+ `)}var Ul,Es,Ds,Os,lh,Ns=J(()=>{yt();Ul=32,Es="Generated with [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)",Ds="Deterministic fallback metadata generated because no LLM PR metadata provider is configured.",Os="Deterministic fallback metadata generated because the LLM PR metadata provider failed or returned unusable output.",lh="PR metadata generated from the coding agent's final session report."});var Xl={};Zc(Xl,{buildPrCompletionWakeOutcomeKey:()=>Fs,buildPrMetadata:()=>Kn,buildPrOutcomeDetailLines:()=>Bs,createRuntimePrMetadataProvider:()=>yo,discoverExistingTargetPr:()=>Jl,formatPrBody:()=>Vn,isOcaFallbackPrBody:()=>So,isOcaGeneratedPrBody:()=>ko,isOcaGeneratedPrTitle:()=>vo,makeAgentPrTool:()=>jn,normalizeForceNewReplacementPrStatus:()=>Ls,refreshOpenPrMetadata:()=>Zl,resolveExistingTargetPrUpdateBranch:()=>Ql,resolveExistingTargetPrUpdateSourceBranch:()=>Yl,shouldIgnoreClosedTargetPrForForceNew:()=>zl});import{execFileSync as wo}from"child_process";import{existsSync as kh}from"fs";function Sh(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function zl(t,e){return t===!0&&e?.exists===!0&&e.state!=="open"}function Ls(t,e,n){return n.forceNewIgnoresClosedTargetPr&&t.exists&&t.state!=="open"&&e?.exists===!0&&(t.url!==void 0&&t.url===e.url||t.number!==void 0&&t.number===e.number)?{exists:!1,state:"none"}:t}function vh(t,e){try{let n=wo("git",["-C",t,"worktree","list","--porcelain"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),r;for(let o of n.split(/\r?\n/)){if(o.startsWith("worktree ")){r=o.slice(9);continue}if(o===`branch refs/heads/${e}`)return r;o===""&&(r=void 0)}}catch{return}}function Hl(t,e,n){try{let r=vh(t,e);return r?(wo("git",["-C",r,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1}):(Se(t)===e?wo("git",["-C",t,"merge","--ff-only",n],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):wo("git",["-C",t,"branch","-f",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),{success:!0,branchName:e,alreadyRepresented:!1})}catch(r){return{success:!1,error:`Failed to fast-forward existing PR branch ${e} from ${n}: ${r instanceof Error?r.message:String(r)}`}}}function Ql(t){let{repoDir:e,sourceBranch:n,targetPrStatus:r}=t;if(!r.exists||r.state!=="open"||!r.headRefName)return{success:!1,error:"Target PR is not an open PR with a resolvable head branch."};let o=r.headRefName,i=Gr(e,o),s=i??o;if(o===n&&!i)return{success:!0,branchName:n,alreadyRepresented:!1};if(!Pt(e,o)&&!i)return{success:!1,error:`Target PR branch ${o} is not available locally. Fetch it before updating the PR.`};if(ve(e,n,s)){if(i&&!ve(e,i,o)&&ve(e,o,i)){let a=Hl(e,o,i);if("error"in a)return a}return{success:!0,branchName:o,alreadyRepresented:!!i}}return Se(e)===o&&ve(e,s,o)&&ve(e,n,o)?{success:!0,branchName:o,alreadyRepresented:!1}:ve(e,s,n)?Hl(e,o,n):{success:!1,error:`Refusing to create a sibling PR: target PR branch ${o} and follow-up branch ${n} have diverged. Reconcile them manually, then run agent_pr again.`}}function Jl(t){let e=Se(t.repoDir);if(!e||e!==t.expectedParentBranch||e===t.worktreeBranch||e===t.baseBranch)return;let n=Re(t.repoDir,e,t.targetRepo);return n.exists&&n.state==="open"&&n.headRefName===e&&(!n.baseRefName||n.baseRefName===t.baseBranch)?n:void 0}function Yl(t){let e=t.targetPrStatus.headRefName;if(!e||e===t.fallbackBranch)return t.fallbackBranch;let n=Se(t.repoDir);return n===e?n:t.fallbackBranch}function Bs(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 Fs(t){let e=t.prNumber!==void 0?`#${t.prNumber}`:t.prUrl??"unknown-pr",n=t.diffSummary?.commitMessages.map(o=>o.hash.trim()).filter(Boolean).join(","),r=t.action==="updated"?n||[`commits:${t.diffSummary?.commits??"unknown"}`,`insertions:${t.diffSummary?.insertions??"unknown"}`,`deletions:${t.diffSummary?.deletions??"unknown"}`].join(","):"created";return["worktree-pr",t.action,t.targetRepo??"default-repo",e,t.branchName,r].join(":")}async function Zl(t){let e=t.prStatus.number??t.prStatus.url;if(!e)return{status:"skipped",reason:"missing-pr-identity"};let n=t.operations?.getBody??dl,r=t.operations?.updateBody??ll,o=t.operations?.updateTitle??ul;if(t.explicitTitle!==void 0||t.explicitBody!==void 0){let m=t.explicitTitle===void 0?!1:o(t.repoDir,e,t.explicitTitle,t.targetRepo);if(t.explicitTitle!==void 0&&!m)return{status:"failed",reason:"failed to update explicit PR title"};let c=t.explicitBody===void 0?!1:r(t.repoDir,e,t.explicitBody,t.targetRepo);return t.explicitBody!==void 0&&!c?{status:"failed",reason:"failed to update explicit PR body"}:{status:"updated",updatedTitle:m,updatedBody:c,reason:"explicit"}}let i=n(t.repoDir,e,t.targetRepo);if(i.ok===!1)return{status:"failed",reason:`failed to read PR body: ${i.error}`};let s=i.body??"";if(s.trim()===""&&!t.forceRefresh)return{status:"skipped",reason:"empty-body"};if(!(t.forceRefresh||ko(s)))return{status:"skipped",reason:"human-edited"};let d=await Kn({sessionName:t.sessionName,branchName:t.branchName,prompt:t.prompt,outputPreview:t.outputPreview,diffSummary:t.diffSummary,provider:t.metadataProvider});if(d.ok===!1)return{status:"failed",reason:d.error};let l=d.evidence.sessionSummary.length>0||d.evidence.sessionChanges.length>0;if(d.fallbackReason!==void 0&&(!l||!So(s)))return{status:"failed",reason:"generated PR metadata was unavailable; preserved existing generated PR metadata"};let u=Vn({sessionName:t.sessionName,metadata:d.metadata,diffSummary:t.diffSummary}),f=t.forceRefresh||vo(t.prStatus.title),p=!1;if(f&&t.prStatus.title?.trim()!==d.metadata.title.trim()&&(p=o(t.repoDir,e,d.metadata.title,t.targetRepo),!p))return{status:"failed",reason:"failed to update generated PR title"};if(u.trim()===s.trim())return p?{status:"updated",updatedTitle:p,updatedBody:!1,reason:t.forceRefresh?"forced":"generated"}:{status:"skipped",reason:"unchanged"};let k=r(t.repoDir,e,u,t.targetRepo);return k?{status:"updated",updatedTitle:p,updatedBody:k,reason:t.forceRefresh?"forced":"generated"}:{status:"failed",reason:"failed to update generated PR body"}}function Ws(t){if(t.status==="updated"){if(t.updatedTitle&&t.updatedBody)return t.reason==="explicit"?"📝 Replaced PR title/body with explicitly provided metadata.":"📝 Refreshed PR title/body from current OpenClaw metadata.";if(t.updatedTitle)return t.reason==="explicit"?"📝 Replaced PR title with the explicitly provided title.":"📝 Refreshed PR title from current OpenClaw metadata.";if(t.updatedBody)return t.reason==="explicit"?"📝 Replaced PR body with the explicitly provided body.":"📝 Refreshed PR body from current OpenClaw metadata."}if(t.status==="failed")return`⚠️ PR metadata refresh failed: ${t.reason}`}function jn(t,e={}){return{name:"agent_pr",description:"Create or update a GitHub PR for a worktree branch. Handles full PR lifecycle: creates new PRs, updates existing open PRs with comments, and handles merged/closed PRs. Pushes the branch, syncs PR state, and persists metadata.",parameters:g.Object({session:g.String({description:"Session name or ID to create/update PR for"}),title:g.Optional(g.String({description:"PR title (default: auto-generated from session name)"})),body:g.Optional(g.String({description:"PR body (default: auto-generated from commit summary). For existing open PRs, passing body explicitly replaces the PR body."})),update_body:g.Optional(g.Boolean({description:"For existing open PRs, refresh generated PR metadata when true. Alias for update_metadata; retained for compatibility."})),update_metadata:g.Optional(g.Boolean({description:"For existing open PRs, refresh title/body when true. Default: only refresh bodies clearly generated by OpenClaw and titles that are fallback-generated, or explicit title/body values."})),base_branch:g.Optional(g.String({description:"Base branch for the PR (default: detected from repo)"})),force_new:g.Optional(g.Boolean({description:"Force creation of a new PR even if one exists (default: false)"})),target_repo:g.Optional(g.String({description:"Target repository for cross-repo PRs (e.g. 'openai/codex'). Auto-detected from 'upstream' remote if not set."}))}),async execute(n,r){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}],meta:{success:!1,state:"error"}};if(!Sh(r))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, title?, body?, update_body?, update_metadata?, base_branch?, force_new? }."}],meta:{success:!1,state:"error"}};if(!ye())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=rn(v,r.session),i=o.activeSession,s=o.persistedSession;if(!i&&!s)return{content:[{type:"text",text:`Error: Session "${r.session}" not found.`}],meta:{success:!1,state:"error"}};let{worktreePath:a,originalWorkdir:d,sessionName:l}=o,{branchName:u}=o;if(!a||!d)return{content:[{type:"text",text:`Error: Session "${r.session}" does not have a worktree.`}],meta:{success:!1,state:"error"}};if(!u)return{content:[{type:"text",text:`Error: Cannot determine branch name for worktree ${a}. The worktree may have been removed and no persisted branch name is available.`}],meta:{success:!1,state:"error"}};kh(a)||`${a}${u}${d}`;let f=r.base_branch??Fe(d),p=e.metadataProvider??yo(),k=R=>{let _=Bl({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??f,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:R.prUrl,prNumber:R.prNumber,baseBranch:f,targetRepo:R.targetRepo,disposition:R.disposition});for(let q of Ln(o))v.updatePersistedSession(q,_)},m=_n(d,r.target_repo??s?.worktreePrTargetRepo),c=s?.worktreePrUrl??i?.worktreePrUrl,h=c?Ye(d,c,m):void 0;if(c&&!h?.exists)return{content:[{type:"text",text:`Error: Session is associated with ${c}, but that PR could not be resolved. Refusing to create a sibling PR from ${u}.`}],meta:{success:!1,state:"error"}};let S=zl(r.force_new,h),P=S?void 0:c,x=!c&&!r.force_new?Jl({repoDir:d,worktreeBranch:u,expectedParentBranch:s?.worktreeParentBranch??i?.worktreeParentBranch,baseBranch:f,targetRepo:m}):void 0,C=S?void 0:h??x,A=P??x?.url,y=!1;if(C?.exists&&C.state==="open"){let R=Yl({repoDir:d,fallbackBranch:u,targetPrStatus:C}),_=Ql({repoDir:d,sourceBranch:R,targetPrStatus:C});if("error"in _)return{content:[{type:"text",text:`Error: ${_.error}`}],meta:{success:!1,state:"error"}};u=_.branchName,y=_.alreadyRepresented}let w=v.resolveRepoPolicy(d),L=Ls(C?.exists?C:Re(d,u,m),h,{forceNewIgnoresClosedTargetPr:S}),K=L.exists&&L.state==="open";if(w?.policy==="never-pr"&&!K)return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${w.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};if(w&&!w.prAvailable)return{content:[{type:"text",text:`Error: PR automation is unavailable for ${w.identity?.repoRoot??d}. Provider: ${w.provider}.`}],meta:{success:!1,state:"error"}};if((!C||C.state==="open")&&!y&&!Jr(d,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let I=Ls(A?Ye(d,A,m):Re(d,u,m),h,{forceNewIgnoresClosedTargetPr:S});if(r.force_new&&I.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${I.state}).
32
32
 
33
33
  Existing PR: ${I.url}
34
34
 
@@ -54,7 +54,7 @@ What would you like to do?
54
54
 
55
55
  (This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{if(w?.policy==="never-pr")return{content:[{type:"text",text:`Error: Repo policy forbids PR creation for ${w.identity?.repoRoot??d}.`}],meta:{success:!1,state:"error"}};let R=!r.title||!r.body?Qe(d,u,f):void 0,_;if(!r.title||!r.body){let Q=await Kn({sessionName:l,branchName:u,prompt:o.prompt,outputPreview:o.outputPreview,diffSummary:R,provider:p});if(Q.ok===!1)return{content:[{type:"text",text:`❌ ${Q.error}`}],meta:{success:!1,state:"error"}};_=Q.metadata}let q=r.title??_.title,N=r.body;N||(N=Vn({sessionName:l,metadata:_,diffSummary:R}));let F=al(d,u,f,q,N,m,{draft:!0});if(F.success&&F.prUrl){let Q=Re(d,u,m);k({prUrl:F.prUrl,prNumber:Q.number,targetRepo:m,disposition:"pr-opened"});let Y=At({kind:"pr-opened",branch:u,targetRepo:m,prUrl:F.prUrl});return v.notifyWorktreeOutcome(o.notificationTarget,Y,{completionWakeOutcomeKey:Fs({action:"opened",branchName:u,prUrl:F.prUrl,prNumber:Q.number,targetRepo:m}),detailLines:Bs({action:"opened",branchName:u,baseBranch:f,prUrl:F.prUrl,prNumber:Q.number,targetRepo:m})}),{content:[{type:"text",text:F.warnings&&F.warnings.length>0?`${Y}
56
56
 
57
- ⚠️ ${F.warnings.join("; ")}`:Y}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${F.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var Po=J(()=>{se();V();Ae();Ns();Wn();Bn();Ns()});import{readdirSync as gv,statSync as hv,rmSync as yv}from"fs";import{execFileSync as kv}from"child_process";import{join as va}from"path";var ba={name:"openclaw-code-agent",version:"4.7.4",type:"module",packageManager:"pnpm@10.30.0",main:"dist/index.js",scripts:{"audit:prod":"pnpm audit --prod",build:"esbuild index.ts --bundle --platform=node --target=node22 --format=esm --outfile=dist/index.js --minify --charset=utf8 --pure:console.log --pure:console.warn --pure:console.info --pure:console.debug --external:@anthropic-ai/claude-agent-sdk --external:openclaw/plugin-sdk/plugin-entry","check-static-guardrails":"node scripts/check-static-guardrails.mjs","check-plugin-security":"node scripts/check-plugin-security.mjs",test:"node scripts/run-tests.mjs","test:integ:crabbox":"node scripts/run-tests.mjs tests/oca-codex-crabbox-integ.test.ts tests/oca-plugin-workflows-integ.test.ts tests/oca-codex-telegram-proof.test.ts tests/oca-codex-proof-app-server.test.ts tests/oca-codex-proof-workflow.test.ts","test:serial":"node scripts/run-tests.mjs","test:file":"node scripts/run-tests.mjs","smoke:backend":"node scripts/run-tests.mjs tests/codex-harness.test.ts tests/plan-mode-e2e.test.ts tests/session-restore-service.test.ts","smoke:backend-parity":"node scripts/run-tests.mjs tests/backend-contract-smoke.test.ts tests/codex-harness.test.ts tests/harness-registry.test.ts","smoke:codex-worktrees":"node scripts/run-tests.mjs tests/codex-harness.test.ts tests/session-bootstrap.test.ts tests/session-restore-service.test.ts","smoke:codex-live":"OPENCLAW_RUN_LIVE_CODEX_SMOKE=1 node scripts/run-tests.mjs tests/live-codex-app-server-smoke.test.ts","proof:codex-doctor":"node --import tsx scripts/e2e/oca-codex-telegram-proof.ts doctor","proof:codex-local":"node --import tsx scripts/e2e/oca-codex-telegram-proof.ts local-smoke","proof:codex-telegram":"node scripts/e2e/run-oca-codex-telegram-proof.mjs","smoke:codex-release":"OPENCLAW_RUN_LIVE_CODEX_RELEASE_SMOKE=1 node scripts/run-tests.mjs tests/live-codex-app-server-smoke.test.ts","smoke:opencode-live":"OPENCLAW_RUN_LIVE_OPENCODE_SMOKE=1 node scripts/run-tests.mjs tests/live-opencode-server-smoke.test.ts",typecheck:"tsc -p tsconfig.typecheck.json --noEmit","validate:release-metadata":"node scripts/validate-release-metadata.mjs",verify:"pnpm check-static-guardrails && pnpm typecheck && pnpm build && pnpm test"},openclaw:{extensions:["./dist/index.js"],install:{npmSpec:"openclaw-code-agent",defaultChoice:"npm",minHostVersion:">=2026.7.1"},compat:{pluginApi:">=2026.7.1",minGatewayVersion:"2026.7.1"},build:{openclawVersion:"2026.7.1",pluginSdkVersion:"2026.7.1"}},files:["dist/","skills/","openclaw.plugin.json","README.md","LICENSE"],dependencies:{"@anthropic-ai/claude-agent-sdk":"^0.3.142"},devDependencies:{"@types/node":"^26.0.1",esbuild:"^0.28.1",nanoid:"^5.1.7",openclaw:"2026.7.1",tsx:"^4.21.0",typescript:"^6.0.2"},keywords:["openclaw","plugin","claude","claude-code","opencode","coding-agent","codex","ai","anthropic","agent","code-generation","automation","cli","background-process","developer-tools"],repository:{type:"git",url:"git+https://github.com/goldmar/openclaw-code-agent.git"},homepage:"https://github.com/goldmar/openclaw-code-agent#readme",bugs:{url:"https://github.com/goldmar/openclaw-code-agent/issues"},license:"MIT",author:"Mark Goldenstein",publishConfig:{access:"public",provenance:!0},description:"An OpenClaw plugin that orchestrates coding agent sessions as managed background processes. Launch, monitor, and control coding agents (Claude Code, Codex, experimental OpenCode, and more) directly from your AI gateway.",peerDependencies:{openclaw:">=2026.7.1"},overrides:{"basic-ftp":"5.3.1","fast-xml-builder@<1.1.7":"1.1.7","ip-address@<10.1.1":"10.1.1"}};import{execFile as Cp}from"node:child_process";import{mkdirSync as Mp,readFileSync as _p,renameSync as $p,writeFileSync as Ep}from"node:fs";import{dirname as Dp,join as Op}from"node:path";import{promisify as Np}from"node:util";import*as Ea from"child_process";import{createHash as ep}from"crypto";var re="code-agent";var tp=new Set(["1","true","yes","on"]);function Ri(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&tp.has(t))}function le(t){if(!(typeof t!="string"||t.length===0))return ep("sha256").update(t).digest("hex").slice(0,12)}function Ra(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function X(t){let e=(t??[]).filter(r=>Array.isArray(r)&&r.length>0),n=e.flat();return{buttonRows:e.length||void 0,buttonCount:n.length||void 0,buttonLabels:n.length>0?n.map(r=>typeof r.label=="string"?r.label:void 0):void 0,callbackByteLengths:n.length>0?n.map(r=>{let o=Ra(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>le(Ra(r))):void 0,buttonStyles:n.length>0?n.map(r=>typeof r.style=="string"?r.style:void 0):void 0}}function nt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Ia(t){let e=nt(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(n)return n.map(r=>nt(r)?.type).filter(r=>typeof r=="string"&&r.length>0)}function xa(t){let e=nt(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(!n)return;let r=n.map(o=>{let i=nt(o);return i?.type!=="buttons"||!Array.isArray(i.buttons)?[]:i.buttons}).filter(o=>o.length>0);return r.length>0?r:void 0}function Ai(t){let e=xa(t);return{presentationBlockTypes:Ia(t),...X(e)}}function Ii(t){let e=nt(t),n=e?.interactive,r=nt(e?.channelData),o=nt(r?.telegram),i=Array.isArray(o?.buttons)?o.buttons:void 0;return{renderedPayloadKeys:e?Object.keys(e).sort():void 0,interactiveBlockTypes:Ia(n),...Aa("interactive",X(xa(n))),...Aa("telegramChannelData",X(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function Ta(t){let e=nt(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 Aa(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(!Ri())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:re,...n})}`}yt();var _a=5e3,Da=64,np={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},rp={execFile:Ea.execFile},ot=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},Nt=class{constructor(e=rp.execFile){this.execFile=e}execFile;async send(e,n,r){B("direct_send_started",{...xe(e),messageTextLength:n.length,...X(r)});try{await this.sendViaRuntime(e,n,r),B("direct_send_succeeded",{...xe(e),deliveryPath:"runtime",...X(r)});return}catch(o){if(!(o instanceof ot))throw B("direct_send_failed",{...xe(e),deliveryPath:"runtime",...X(r),error:Ti(o)}),o;B("direct_send_runtime_capability_missing",{...xe(e),deliveryPath:"runtime",...X(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),B("direct_send_succeeded",{...xe(e),deliveryPath:"cli-fallback",...X(r)})}}async sendViaRuntime(e,n,r){let o=rt(),i=Ma(),s=o?.channel?.outbound?.loadAdapter;if(!o)throw new ot("OpenClaw plugin runtime is unavailable for direct notification delivery");if(i==null)throw new ot("OpenClaw runtime config snapshot is unavailable for direct notification delivery");if(!o.channel)throw new ot(`OpenClaw plugin runtime channel surface is unavailable for direct notification delivery (runtimeVersion=${Ci(o)})`);if(!o.channel.outbound)throw new ot(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${Ci(o)})`);if(!s)throw new ot(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${Ci(o)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let d=rr(r);if(B("runtime_adapter_loaded",{...xe(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...X(r),...d?Ai(d):{}}),d){await this.sendPresentation(a,i,e,n,d);return}if(!a.sendText)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" cannot send text`);await a.sendText({cfg:i,to:e.target,text:n,accountId:e.accountId,threadId:e.threadId})}async sendPresentation(e,n,r,o,i){let s=ip(i),a={text:o,presentation:i,interactive:s};B("presentation_render_started",{...xe(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Ai(i)});let d={cfg:n,to:r.target,text:o,payload:a,accountId:r.accountId,threadId:r.threadId},l=e.renderPresentation?await e.renderPresentation({payload:a,presentation:i,ctx:d}):a,u=ap(l,s,r.channel);if(B("presentation_render_completed",{...xe(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Ii(u)}),!u||typeof u!="object"||!e.sendPayload)throw new Error(`OpenClaw outbound adapter for channel "${r.channel}" cannot preserve interactive presentation`);let f=await e.sendPayload({...d,payload:u});B("presentation_send_payload_completed",{...xe(r),...Ii(u),...Ta(f)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let a=op(e,n,r);B("direct_send_cli_fallback_started",{...xe(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...X(r)}),this.execFile("openclaw",a,{timeout:_a,killSignal:"SIGKILL"},(d,l,u)=>{if(!d){B("direct_send_cli_fallback_completed",{...xe(e),deliveryPath:"cli-fallback",...X(r)}),i();return}let f=u?.trim()?` | stderr: ${u.trim()}`:"";B("direct_send_cli_fallback_failed",{...xe(e),deliveryPath:"cli-fallback",...X(r),error:Ti(d),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${_a}ms timeout: ${Ti(d)}${f}`))})})}};function xe(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function op(t,e,n){let r=rr(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 Ti(t){return t instanceof Error?t.message:String(t)}function Ci(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function rr(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:mp(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function ip(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 sp(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 ap(t,e,n){if(!e)return t;let r=sp(t)?t:dp(t,e);return n!=="telegram"?r:lp(r,e)}function dp(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function lp(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Wt(n.channelData),o=Wt(r?.telegram),i=cp(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=up(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function up(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")<=Da).map(r=>({text:r.label,callback_data:r.value,...Oa(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function cp(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")>Da))&&pp(i))return{...i,...Oa(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function pp(t){return nr(t.callback_data)||nr(t.url)||tr(t.web_app)||tr(t.webApp)||tr(t.login_url)||tr(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||Wt(t.switch_inline_query_chosen_chat)!==void 0||Wt(t.callback_game)!==void 0||t.pay===!0||$a(t.copy_text)||$a(t.copyText)}function nr(t){return typeof t=="string"&&t.trim().length>0}function tr(t){let e=Wt(t);return nr(e?.url)}function $a(t){let e=Wt(t);return nr(e?.text)}function Oa(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=np[e];return n?{style:n}:{}}function Wt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function mp(t){return t.startsWith(`${re}:`)?t:`${re}:${t}`}ae();ke();var Wp=Np(Cp),vn="openclaw-code-agent",Lp=`https://registry.npmjs.org/${encodeURIComponent(vn)}/latest`,Bp="openclaw-code-agent-auto-update.json",ja=1440*60*1e3,Fp=7*ja,qp=1e4,qt="plugin:auto-update";function st(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Li(t){return t instanceof Error?t.message:String(t)}function Ee(t){return t?.trim().replace(/^v/i,"")||void 0}function $e(t,e){let n=t[e];return typeof n=="string"&&n.trim()?n.trim():void 0}function Ua(t){let e=t?.trim().replace(/^npm:/,"");if(!e)return;if(e.startsWith("@")){let r=e.indexOf("@",1);return r===-1?e:e.slice(0,r)}let n=e.indexOf("@");return n===-1?e:e.slice(0,n)}function Bi(t){let e=`${t.stdout}
57
+ ⚠️ ${F.warnings.join("; ")}`:Y}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${F.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var Po=J(()=>{se();V();Ae();Ns();Wn();Bn();Ns()});import{readdirSync as gv,statSync as hv,rmSync as yv}from"fs";import{execFileSync as kv}from"child_process";import{join as va}from"path";var ba={name:"openclaw-code-agent",version:"4.7.5",type:"module",packageManager:"pnpm@11.13.0",main:"dist/index.js",scripts:{"audit:prod":"pnpm audit --prod",build:"esbuild index.ts --bundle --platform=node --target=node22 --format=esm --outfile=dist/index.js --minify --charset=utf8 --pure:console.log --pure:console.warn --pure:console.info --pure:console.debug --external:@anthropic-ai/claude-agent-sdk --external:openclaw/plugin-sdk/plugin-entry","check-static-guardrails":"node scripts/check-static-guardrails.mjs","check-plugin-security":"node scripts/check-plugin-security.mjs",test:"node scripts/run-tests.mjs","test:integ:crabbox":"node scripts/run-tests.mjs tests/oca-codex-crabbox-integ.test.ts tests/oca-plugin-workflows-integ.test.ts tests/oca-codex-telegram-proof.test.ts tests/oca-codex-proof-app-server.test.ts tests/oca-codex-proof-workflow.test.ts","test:serial":"node scripts/run-tests.mjs","test:file":"node scripts/run-tests.mjs","smoke:backend":"node scripts/run-tests.mjs tests/codex-harness.test.ts tests/plan-mode-e2e.test.ts tests/session-restore-service.test.ts","smoke:backend-parity":"node scripts/run-tests.mjs tests/backend-contract-smoke.test.ts tests/codex-harness.test.ts tests/harness-registry.test.ts","smoke:codex-worktrees":"node scripts/run-tests.mjs tests/codex-harness.test.ts tests/session-bootstrap.test.ts tests/session-restore-service.test.ts","smoke:codex-live":"OPENCLAW_RUN_LIVE_CODEX_SMOKE=1 node scripts/run-tests.mjs tests/live-codex-app-server-smoke.test.ts","proof:codex-doctor":"node --import tsx scripts/e2e/oca-codex-telegram-proof.ts doctor","proof:codex-local":"node --import tsx scripts/e2e/oca-codex-telegram-proof.ts local-smoke","proof:codex-telegram":"node scripts/e2e/run-oca-codex-telegram-proof.mjs","smoke:codex-release":"OPENCLAW_RUN_LIVE_CODEX_RELEASE_SMOKE=1 node scripts/run-tests.mjs tests/live-codex-app-server-smoke.test.ts","smoke:opencode-live":"OPENCLAW_RUN_LIVE_OPENCODE_SMOKE=1 node scripts/run-tests.mjs tests/live-opencode-server-smoke.test.ts",typecheck:"tsc -p tsconfig.typecheck.json --noEmit","validate:release-metadata":"node scripts/validate-release-metadata.mjs",verify:"pnpm check-static-guardrails && pnpm typecheck && pnpm build && pnpm test"},openclaw:{extensions:["./dist/index.js"],install:{npmSpec:"openclaw-code-agent",defaultChoice:"npm",minHostVersion:">=2026.7.1"},compat:{pluginApi:">=2026.7.1",minGatewayVersion:"2026.7.1"},build:{openclawVersion:"2026.7.1",pluginSdkVersion:"2026.7.1"}},files:["dist/","skills/","openclaw.plugin.json","README.md","LICENSE"],dependencies:{"@anthropic-ai/claude-agent-sdk":"^0.3.142"},devDependencies:{"@types/node":"^26.0.1",esbuild:"^0.28.1",nanoid:"^5.1.7",openclaw:"2026.7.1",tsx:"^4.21.0",typescript:"^6.0.2"},keywords:["openclaw","plugin","claude","claude-code","opencode","coding-agent","codex","ai","anthropic","agent","code-generation","automation","cli","background-process","developer-tools"],repository:{type:"git",url:"git+https://github.com/goldmar/openclaw-code-agent.git"},homepage:"https://github.com/goldmar/openclaw-code-agent#readme",bugs:{url:"https://github.com/goldmar/openclaw-code-agent/issues"},license:"MIT",author:"Mark Goldenstein",publishConfig:{access:"public",provenance:!0},description:"An OpenClaw plugin that orchestrates coding agent sessions as managed background processes. Launch, monitor, and control coding agents (Claude Code, Codex, experimental OpenCode, and more) directly from your AI gateway.",peerDependencies:{openclaw:">=2026.7.1"},overrides:{"basic-ftp":"5.3.1","fast-xml-builder@<1.1.7":"1.1.7","ip-address@<10.1.1":"10.1.1"}};import{execFile as Cp}from"node:child_process";import{mkdirSync as Mp,readFileSync as _p,renameSync as $p,writeFileSync as Ep}from"node:fs";import{dirname as Dp,join as Op}from"node:path";import{promisify as Np}from"node:util";import*as Ea from"child_process";import{createHash as ep}from"crypto";var re="code-agent";var tp=new Set(["1","true","yes","on"]);function Ri(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&tp.has(t))}function le(t){if(!(typeof t!="string"||t.length===0))return ep("sha256").update(t).digest("hex").slice(0,12)}function Ra(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function X(t){let e=(t??[]).filter(r=>Array.isArray(r)&&r.length>0),n=e.flat();return{buttonRows:e.length||void 0,buttonCount:n.length||void 0,buttonLabels:n.length>0?n.map(r=>typeof r.label=="string"?r.label:void 0):void 0,callbackByteLengths:n.length>0?n.map(r=>{let o=Ra(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>le(Ra(r))):void 0,buttonStyles:n.length>0?n.map(r=>typeof r.style=="string"?r.style:void 0):void 0}}function nt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Ia(t){let e=nt(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(n)return n.map(r=>nt(r)?.type).filter(r=>typeof r=="string"&&r.length>0)}function xa(t){let e=nt(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(!n)return;let r=n.map(o=>{let i=nt(o);return i?.type!=="buttons"||!Array.isArray(i.buttons)?[]:i.buttons}).filter(o=>o.length>0);return r.length>0?r:void 0}function Ai(t){let e=xa(t);return{presentationBlockTypes:Ia(t),...X(e)}}function Ii(t){let e=nt(t),n=e?.interactive,r=nt(e?.channelData),o=nt(r?.telegram),i=Array.isArray(o?.buttons)?o.buttons:void 0;return{renderedPayloadKeys:e?Object.keys(e).sort():void 0,interactiveBlockTypes:Ia(n),...Aa("interactive",X(xa(n))),...Aa("telegramChannelData",X(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function Ta(t){let e=nt(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 Aa(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(!Ri())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:re,...n})}`}yt();var _a=5e3,Da=64,np={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},rp={execFile:Ea.execFile},ot=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},Nt=class{constructor(e=rp.execFile){this.execFile=e}execFile;async send(e,n,r){B("direct_send_started",{...xe(e),messageTextLength:n.length,...X(r)});try{await this.sendViaRuntime(e,n,r),B("direct_send_succeeded",{...xe(e),deliveryPath:"runtime",...X(r)});return}catch(o){if(!(o instanceof ot))throw B("direct_send_failed",{...xe(e),deliveryPath:"runtime",...X(r),error:Ti(o)}),o;B("direct_send_runtime_capability_missing",{...xe(e),deliveryPath:"runtime",...X(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),B("direct_send_succeeded",{...xe(e),deliveryPath:"cli-fallback",...X(r)})}}async sendViaRuntime(e,n,r){let o=rt(),i=Ma(),s=o?.channel?.outbound?.loadAdapter;if(!o)throw new ot("OpenClaw plugin runtime is unavailable for direct notification delivery");if(i==null)throw new ot("OpenClaw runtime config snapshot is unavailable for direct notification delivery");if(!o.channel)throw new ot(`OpenClaw plugin runtime channel surface is unavailable for direct notification delivery (runtimeVersion=${Ci(o)})`);if(!o.channel.outbound)throw new ot(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${Ci(o)})`);if(!s)throw new ot(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${Ci(o)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let d=rr(r);if(B("runtime_adapter_loaded",{...xe(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...X(r),...d?Ai(d):{}}),d){await this.sendPresentation(a,i,e,n,d);return}if(!a.sendText)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" cannot send text`);await a.sendText({cfg:i,to:e.target,text:n,accountId:e.accountId,threadId:e.threadId})}async sendPresentation(e,n,r,o,i){let s=ip(i),a={text:o,presentation:i,interactive:s};B("presentation_render_started",{...xe(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Ai(i)});let d={cfg:n,to:r.target,text:o,payload:a,accountId:r.accountId,threadId:r.threadId},l=e.renderPresentation?await e.renderPresentation({payload:a,presentation:i,ctx:d}):a,u=ap(l,s,r.channel);if(B("presentation_render_completed",{...xe(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Ii(u)}),!u||typeof u!="object"||!e.sendPayload)throw new Error(`OpenClaw outbound adapter for channel "${r.channel}" cannot preserve interactive presentation`);let f=await e.sendPayload({...d,payload:u});B("presentation_send_payload_completed",{...xe(r),...Ii(u),...Ta(f)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let a=op(e,n,r);B("direct_send_cli_fallback_started",{...xe(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...X(r)}),this.execFile("openclaw",a,{timeout:_a,killSignal:"SIGKILL"},(d,l,u)=>{if(!d){B("direct_send_cli_fallback_completed",{...xe(e),deliveryPath:"cli-fallback",...X(r)}),i();return}let f=u?.trim()?` | stderr: ${u.trim()}`:"";B("direct_send_cli_fallback_failed",{...xe(e),deliveryPath:"cli-fallback",...X(r),error:Ti(d),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${_a}ms timeout: ${Ti(d)}${f}`))})})}};function xe(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function op(t,e,n){let r=rr(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 Ti(t){return t instanceof Error?t.message:String(t)}function Ci(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function rr(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:mp(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function ip(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 sp(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 ap(t,e,n){if(!e)return t;let r=sp(t)?t:dp(t,e);return n!=="telegram"?r:lp(r,e)}function dp(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function lp(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Wt(n.channelData),o=Wt(r?.telegram),i=cp(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=up(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function up(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")<=Da).map(r=>({text:r.label,callback_data:r.value,...Oa(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function cp(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")>Da))&&pp(i))return{...i,...Oa(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function pp(t){return nr(t.callback_data)||nr(t.url)||tr(t.web_app)||tr(t.webApp)||tr(t.login_url)||tr(t.loginUrl)||typeof t.switch_inline_query=="string"||typeof t.switch_inline_query_current_chat=="string"||Wt(t.switch_inline_query_chosen_chat)!==void 0||Wt(t.callback_game)!==void 0||t.pay===!0||$a(t.copy_text)||$a(t.copyText)}function nr(t){return typeof t=="string"&&t.trim().length>0}function tr(t){let e=Wt(t);return nr(e?.url)}function $a(t){let e=Wt(t);return nr(e?.text)}function Oa(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=np[e];return n?{style:n}:{}}function Wt(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function mp(t){return t.startsWith(`${re}:`)?t:`${re}:${t}`}ae();ke();var Wp=Np(Cp),vn="openclaw-code-agent",Lp=`https://registry.npmjs.org/${encodeURIComponent(vn)}/latest`,Bp="openclaw-code-agent-auto-update.json",ja=1440*60*1e3,Fp=7*ja,qp=1e4,qt="plugin:auto-update";function st(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function Li(t){return t instanceof Error?t.message:String(t)}function Ee(t){return t?.trim().replace(/^v/i,"")||void 0}function $e(t,e){let n=t[e];return typeof n=="string"&&n.trim()?n.trim():void 0}function Ua(t){let e=t?.trim().replace(/^npm:/,"");if(!e)return;if(e.startsWith("@")){let r=e.indexOf("@",1);return r===-1?e:e.slice(0,r)}let n=e.indexOf("@");return n===-1?e:e.slice(0,n)}function Bi(t){let e=`${t.stdout}
58
58
  ${t.stderr}`;if(/No install record/i.test(e))throw new Error("OpenClaw reported no managed install record for OCA.");let n;try{n=JSON.parse(t.stdout)}catch{throw new Error("OpenClaw returned invalid JSON while inspecting the OCA install.")}if(!st(n)||!st(n.plugin)||!st(n.install))throw new Error("OpenClaw inspection did not include the OCA plugin and managed install record.");let r=$e(n.plugin,"id"),o=Ee($e(n.plugin,"version"));if(r!==vn||!o)throw new Error("OpenClaw inspection returned an unexpected OCA plugin identity or version.");let i=$e(n.install,"source"),s=Ee($e(n.install,"version")),a=Ee($e(n.install,"resolvedVersion"));if(i==="npm"){let d=$e(n.install,"resolvedName")??Ua($e(n.install,"spec"))??Ua($e(n.install,"resolvedSpec"));if(!d)throw new Error("The OCA npm install record does not identify its package.");return{pluginVersion:o,install:{source:i,packageName:d,recordedVersion:s,resolvedVersion:a}}}if(i==="clawhub"){let d=$e(n.install,"clawhubPackage");if(!d)throw new Error("The OCA ClawHub install record does not identify its package.");return{pluginVersion:o,install:{source:i,packageName:d,recordedVersion:s,resolvedVersion:a}}}throw new Error(`OCA self-update does not support managed install source ${i??"unknown"}.`)}function Up(t,e){return["plugins","install",t.source==="npm"?`${t.packageName}@${e}`:`clawhub:${t.packageName}@${e}`,"--force"]}function Kp(t,e,n){if(e.install.source!==t.install.source||e.install.packageName!==t.install.packageName)throw new Error("OCA update verification found that the managed install source or package changed.");if(e.pluginVersion!==n)throw new Error(`OCA update verification found installed plugin version ${e.pluginVersion}, expected ${n}.`);let r=[e.install.recordedVersion,e.install.resolvedVersion].filter(o=>!!o);if(r.length===0||r.some(o=>o!==n))throw new Error(`OCA update verification found managed install version ${r.join("/")||"unknown"}, expected ${n}.`)}function Fi(t){let n=Ee(t)?.match(/^((?:0|[1-9]\d*))\.((?:0|[1-9]\d*))\.((?:0|[1-9]\d*))$/);if(!n?.[1]||!n[2]||!n[3])return;let r=[Number(n[1]),Number(n[2]),Number(n[3])];return r.every(Number.isSafeInteger)?r:void 0}function Vp(t,e){let n=Fi(t),r=Fi(e);if(!n||!r)return!1;for(let o=0;o<3;o+=1){if(n[o]>r[o])return!0;if(n[o]<r[o])return!1}return!1}function jp(t){if(!st(t))return{};let e={};for(let n of["lastCheckedAt","latestVersion","promptedVersion","lastPromptedAt","dismissedVersion","lastDismissedAt","updateInstalledVersion","restartPromptedVersion","lastError"]){let r=t[n];typeof r=="string"&&r.trim()&&(e[n]=r)}return e}function Ka(t){if(!(!t?.provider||!t.target||t.provider==="system"||t.target==="system"))return{channel:t.provider,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function Va(){if(D.fallbackChannel)return _e(D.fallbackChannel)}async function Gp(){let t=await fetch(Lp,{headers:{accept:"application/json"},signal:AbortSignal.timeout(qp)});if(!t.ok)throw new Error(`npm registry returned HTTP ${t.status}`);let e=await t.json(),n=st(e)&&typeof e.version=="string"?Ee(e.version):void 0;return n?{version:n}:void 0}async function Hp(t,e){let n=await t("openclaw",["plugins","search",e,"--limit","100","--json"]),r;try{r=JSON.parse(n.stdout)}catch{throw new Error("OpenClaw returned invalid JSON while checking ClawHub for OCA updates.")}let o=st(r)&&Array.isArray(r.results)?r.results:[];for(let i of o){if(!st(i)||!st(i.package)||$e(i.package,"name")!==e)continue;let s=Ee($e(i.package,"latestVersion"));return s?{version:s}:void 0}}async function zp(t){let e=Bi(await t("openclaw",["plugins","inspect",vn,"--json"]));return e.install.source==="npm"?Gp():Hp(t,e.install.packageName)}async function Qp(t,e){let n=await Wp(t,e,{timeout:12e4,maxBuffer:1048576});return{stdout:n.stdout?.toString()??"",stderr:n.stderr?.toString()??""}}var sr=class{constructor(e){this.options=e;this.statePath=Op(e.stateDir,Bp),this.notifier=e.notifier??new Nt,this.runCommand=e.runCommand??Qp,this.fetchLatestRelease=e.fetchLatestRelease??(()=>zp(this.runCommand)),this.now=e.now??Date.now}options;statePath;notifier;fetchLatestRelease;runCommand;now;checkInFlight;maybeCheckForUpdate(e={}){this.checkInFlight||(this.checkInFlight=this.checkForUpdate(e).catch(n=>{`${Li(n)}`}).finally(()=>{this.checkInFlight=void 0}))}async waitForIdle(){await this.checkInFlight}async installConfirmed(e,n){let r=Ee(e);if(!r||!Fi(r))return"Could not determine which stable OCA version to update to.";let o=Bi(await this.runCommand("openclaw",["plugins","inspect",vn,"--json"])),i=await this.runCommand("openclaw",Up(o.install,r));if(/No install record/i.test(`${i.stdout}
59
59
  ${i.stderr}`))throw new Error("OpenClaw reported no managed install record while updating OCA.");let s=Bi(await this.runCommand("openclaw",["plugins","inspect",vn,"--json"]));Kp(o,s,r);let a=this.readState();this.writeState({...a,updateInstalledVersion:r});let d=Ka(n?.route??Va());if(d)try{return await this.sendRestartPrompt(d,r),`OCA ${r} installation was verified. Restart confirmation was sent.`}catch(l){`${r}${Li(l)}`}return[`OCA ${r} installation was verified.`,"Restart the Gateway explicitly to load it: openclaw gateway restart"].join(`
60
60
  `)}async restartConfirmed(e){let n=Ee(e);return await this.runCommand("openclaw",["gateway","restart"]),n?`Gateway restart requested for OCA ${n}.`:"Gateway restart requested."}dismiss(e){return this.postpone(e,"Dismissed")}remindLater(e){return this.postpone(e,"Will remind later about")}postpone(e,n){let r=Ee(e),o=this.readState();return this.writeState({...o,...r?{dismissedVersion:r,lastDismissedAt:new Date(this.now()).toISOString()}:{}}),r?`${n} OCA ${r} update reminder.`:`${n} OCA update reminder.`}async checkForUpdate(e){let n=this.readState(),r=n.lastCheckedAt?Date.parse(n.lastCheckedAt):Number.NaN;if(Number.isFinite(r)&&this.now()-r<ja){await this.promptFromState(n,e);return}let o=new Date(this.now()).toISOString(),i={...n,lastCheckedAt:o};delete i.lastError,this.writeState(i);try{let s=await this.fetchLatestRelease(),a=Ee(s?.version),d={...this.readState(),latestVersion:a};delete d.lastError,this.writeState(d),await this.promptFromState(d,e)}catch(s){throw this.writeState({...this.readState(),lastError:Li(s)}),s}}async promptFromState(e,n){let r=Ee(e.latestVersion);if(!Vp(r,this.options.currentVersion)||!this.shouldPromptForVersion(e,r))return;let o=Ka(n.route??Va());o&&(await this.sendUpdatePrompt(o,r),this.writeState({...this.readState(),latestVersion:r,promptedVersion:r,lastPromptedAt:new Date(this.now()).toISOString()}))}async sendUpdatePrompt(e,n){await this.notifier.send(e,[`OCA update available: ${this.options.currentVersion} -> ${n}.`,"","Update now will reinstall the exact approved version from OCA's recorded npm or ClawHub source, then verify it.","If the update succeeds, OCA will ask separately before restarting the Gateway."].join(`
@@ -67,25 +67,25 @@ ${i.stderr}`))throw new Error("OpenClaw reported no managed install record while
67
67
  `):"";return{kind:"blocked",text:["Resume-first protection blocked a fresh launch.","",w,L,["If you intentionally want a brand-new independent session here, call:"," agent_launch(prompt='<new task>', force_new_session=true)"].join(`
68
68
  `)].filter(Boolean).join(`
69
69
 
70
- `)}}}let c=t.resume_session_id,h=c?n.resolve?.(c):void 0,S=c?n.getPersistedSession?.(c):void 0;if(c){let y=n.resolveBackendConversationId?.(c)??n.resolveHarnessSessionId?.(c);if(!y)return{kind:"error",text:`Error: Could not resolve resume_session_id "${c}" to a session ID. Use agent_sessions to list available sessions.`};c=y}let{resumeSessionId:b,clearedPersistedCodexResume:x}=Ut({requestedResumeSessionId:c,activeSession:h?{harnessSessionId:h.backendConversationId??h.harnessSessionId}:void 0,persistedSession:S?{harness:S.harness,backendRef:S.backendRef}:void 0}),T=t.permission_mode??D.permissionMode,A=t.plan_approval??D.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:u,permissionMode:T,planApproval:A,originChannel:p,originThreadId:m,originSessionKey:k,route:Ft(e,p,k),resumeSessionId:b,resolvedResumeId:c,clearedPersistedCodexResume:x,reasoningEffort:it(o),fastMode:Bt(o)}}ne();function ut(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function Be(t){if(!Number.isFinite(t))return"0s";let e=Math.floor(t/1e3),n=Math.floor(e/60),r=e%60;return n>0?`${n}m${r}s`:`${r}s`}var yf=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 _d(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!yf.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var Md={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function kf(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 $d(t){let e=Md[t.phase]??Md[t.status]??"❓",n=Be(t.duration),r=t.multiTurn?"multi-turn":"single",o=t.prompt.length>80?t.prompt.slice(0,80)+"...":t.prompt,i=t.costUsd>0?` | $${t.costUsd.toFixed(2)}`:"",s=[`${e} ${t.name} [${t.id}] (${n}${i}) — ${r}`,` 📁 ${t.workdir}`,` 📝 "${o}"`];if(t.worktreePath&&t.worktreeBranch&&s.push(` 🌿 Worktree: ${t.worktreeBranch} ${kf(t)}`),t.phase!==t.status&&s.push(` ⚙️ Phase: ${t.phase}`),t.lifecycle&&t.lifecycle!==t.phase&&s.push(` 🔄 Lifecycle: ${t.lifecycle}`),(t.requestedPermissionMode||t.currentPermissionMode||t.approvalExecutionState)&&s.push(` 🔐 Approval: ${t.approvalExecutionState??"unknown"} (requested=${t.requestedPermissionMode??"unknown"}, effective=${t.currentPermissionMode??"unknown"})`),t.resumable&&s.push(" ↩️ Resumable: yes"),t.recovered&&t.runtimeRecovery){let d=t.runtimeRecovery?.reason?` (${t.runtimeRecovery.reason})`:"";s.push(` ♻️ Recovered: persisted metadata only; no live process to kill${d}`),s.push(` 🩺 Recovery: raw=${t.runtimeRecovery.rawStatus??"unknown"}/${t.runtimeRecovery.rawLifecycle??"unknown"}/${t.runtimeRecovery.rawRuntimeState??"unknown"} → normalized=${t.runtimeRecovery.normalizedStatus}/${t.runtimeRecovery.normalizedLifecycle??"unknown"}/${t.runtimeRecovery.normalizedRuntimeState??"unknown"}`)}else t.recovered&&s.push(" 💾 Persisted: no live runtime process in this Gateway");t.harness?s.push(` 🧰 Harness | model: ${ut({harness:t.harness,model:t.model})}`):t.model&&s.push(` 🧰 Harness | model: ${t.model}`);let a=O(t);return a&&s.push(` 🔗 Backend ID: ${a}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
70
+ `)}}}let c=t.resume_session_id,h=c?n.resolve?.(c):void 0,S=c?n.getPersistedSession?.(c):void 0;if(c){let y=n.resolveBackendConversationId?.(c)??n.resolveHarnessSessionId?.(c);if(!y)return{kind:"error",text:`Error: Could not resolve resume_session_id "${c}" to a session ID. Use agent_sessions to list available sessions.`};c=y}let{resumeSessionId:P,clearedPersistedCodexResume:x}=Ut({requestedResumeSessionId:c,activeSession:h?{harnessSessionId:h.backendConversationId??h.harnessSessionId}:void 0,persistedSession:S?{harness:S.harness,backendRef:S.backendRef}:void 0}),C=t.permission_mode??D.permissionMode,A=t.plan_approval??D.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:u,permissionMode:C,planApproval:A,originChannel:p,originThreadId:m,originSessionKey:k,route:Ft(e,p,k),resumeSessionId:P,resolvedResumeId:c,clearedPersistedCodexResume:x,reasoningEffort:it(o),fastMode:Bt(o)}}ne();function ut(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function Be(t){if(!Number.isFinite(t))return"0s";let e=Math.floor(t/1e3),n=Math.floor(e/60),r=e%60;return n>0?`${n}m${r}s`:`${r}s`}var yf=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 _d(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!yf.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var Md={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function kf(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 $d(t){let e=Md[t.phase]??Md[t.status]??"❓",n=Be(t.duration),r=t.multiTurn?"multi-turn":"single",o=t.prompt.length>80?t.prompt.slice(0,80)+"...":t.prompt,i=t.costUsd>0?` | $${t.costUsd.toFixed(2)}`:"",s=[`${e} ${t.name} [${t.id}] (${n}${i}) — ${r}`,` 📁 ${t.workdir}`,` 📝 "${o}"`];if(t.worktreePath&&t.worktreeBranch&&s.push(` 🌿 Worktree: ${t.worktreeBranch} ${kf(t)}`),t.phase!==t.status&&s.push(` ⚙️ Phase: ${t.phase}`),t.lifecycle&&t.lifecycle!==t.phase&&s.push(` 🔄 Lifecycle: ${t.lifecycle}`),(t.requestedPermissionMode||t.currentPermissionMode||t.approvalExecutionState)&&s.push(` 🔐 Approval: ${t.approvalExecutionState??"unknown"} (requested=${t.requestedPermissionMode??"unknown"}, effective=${t.currentPermissionMode??"unknown"})`),t.resumable&&s.push(" ↩️ Resumable: yes"),t.recovered&&t.runtimeRecovery){let d=t.runtimeRecovery?.reason?` (${t.runtimeRecovery.reason})`:"";s.push(` ♻️ Recovered: persisted metadata only; no live process to kill${d}`),s.push(` 🩺 Recovery: raw=${t.runtimeRecovery.rawStatus??"unknown"}/${t.runtimeRecovery.rawLifecycle??"unknown"}/${t.runtimeRecovery.rawRuntimeState??"unknown"} → normalized=${t.runtimeRecovery.normalizedStatus}/${t.runtimeRecovery.normalizedLifecycle??"unknown"}/${t.runtimeRecovery.normalizedRuntimeState??"unknown"}`)}else t.recovered&&s.push(" 💾 Persisted: no live runtime process in this Gateway");t.harness?s.push(` 🧰 Harness | model: ${ut({harness:t.harness,model:t.model})}`):t.model&&s.push(` 🧰 Harness | model: ${t.model}`);let a=O(t);return a&&s.push(` 🔗 Backend ID: ${a}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
71
71
  `)}function Tr(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?Be(n):"n/a"}`];if(t.mostExpensive){let a=t.mostExpensive;s.push("","🏆 Notable session",` ${a.name} [${a.id}]`,` 📝 "${a.prompt}"`)}return s.join(`
72
72
  `)}function ce(t,e){return e<=0?"":t.length<=e?t:e<=3?".".repeat(e):t.slice(0,e-3)+"..."}function Ed(t,e){let n=t.split(`
73
73
  `),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(`
74
74
  `)}function Dd(t,e){let n=t.split(`
75
75
  `),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(`
76
- `)}yt();var Sf="openclaw-code-agent",vf=160,Cr={create(){},progress(){},finalize(){}};function Mr(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function as(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function wf(t){let e=t.prompt.trim().replace(/\s+/g," ");return ce(e||t.name,vf)}function Od(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 Nd(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 _r(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 Pf(t){return $r(t.lifecycle)}function $r(t){return t==="awaiting_plan_decision"||t==="awaiting_user_input"||t==="awaiting_worktree_decision"||t==="suspended"}function bf(t){if(t.pendingPlanApproval||t.pendingWorktreeDecisionSince)return!0;if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;return e==="suspended"?t.runtimeRecovery.rawResumable===!0||t.resumable===!0:$r(e)}return t.lifecycle==="suspended"?t.resumable===!0:$r(t.lifecycle)}function Rf(t){if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;if($r(e))return e}return t.lifecycle}function ss(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 Af(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 Er(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var ds=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:Sf,goal:wf(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:ss(e,"created",n),createdAt:e.startedAt,updatedAt:r}),e.taskFlowMirror=this.flow,this.lastProgressKey=this.progressKey(e,n)}catch(o){Mr("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=Od(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=ss(e,"progress",n),i=Date.now(),s=Pf(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=Er(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.lastProgressKey=r}catch(o){Mr("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=Nd(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":_r(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...ss(e,"terminal",r),terminalStatus:n,terminalSummary:_r(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:_r(e.status,e.killReason),updatedAt:o,endedAt:o});as("finalize",s),this.flow=Er(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.finalized=!0}catch(o){Mr("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function If(t){return t==="succeeded"||t==="failed"||t==="cancelled"||t==="lost"}function xf(t){if(!t?.trim())return;let e=xi()?.fromToolContext;if(typeof e!="function")return;let n=e({sessionKey:t});if(!n||typeof n!="object")return;let r=n;if(!(typeof r.setWaiting!="function"||typeof r.finish!="function"||typeof r.fail!="function"))return{setWaiting:r.setWaiting,finish:r.finish,fail:r.fail}}function Tf(t){return t.originSessionKey??t.route?.sessionKey}function Cf(t){return t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"Lost after OCA restart without live process":_r(t.status,t.killReason??"unknown")}function Wd(t){let e=t.taskFlowMirror?{...t.taskFlowMirror}:void 0;if(!e||If(e.status))return;let n=xf(Tf(t));if(!n)return;let r=Date.now();if(bf(t)){let l=Od({status:t.status,lifecycle:Rf(t)??"suspended"})??"Waiting",u=n.setWaiting({flowId:e.flowId,expectedRevision:e.revision,currentStep:l,stateJson:{phase:"progress",integration:"phase-1-managed-task-flow",sessionId:t.sessionId,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:l,reconciled:!0},waitJson:{reason:l,sessionId:t.sessionId},blockedSummary:l,updatedAt:r});return as("reconcile-waiting",u),Er(e,u)}let o=Nd({status:t.status,killReason:t.killReason??"unknown"})??"failed",i=Cf(t),s=t.completedAt??r,a={phase:"terminal",integration:"phase-1-managed-task-flow",sessionId:t.sessionId,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:i,terminalStatus:t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"lost":o,terminalSummary:i,reconciled:!0,runtimeRecovery:t.runtimeRecovery},d=o==="succeeded"?n.finish({flowId:e.flowId,expectedRevision:e.revision,stateJson:a,updatedAt:s,endedAt:s}):n.fail({flowId:e.flowId,expectedRevision:e.revision,stateJson:a,blockedSummary:i,updatedAt:s,endedAt:s});return as("reconcile-terminal",d),Er(e,d)}function Dr(t){if(!t.sessionKey?.trim())return Cr;try{let e=xi()?.fromToolContext;if(typeof e!="function")return Cr;let n=e(t);return Af(n)?new ds(n):Cr}catch(e){return Mr("resolve",e),Cr}}function Mf(t){return t instanceof Error?t.message:String(t)}function Ld(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function _f(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function $f(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function Ef(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function Bd(t){return{name:"agent_launch",description:"Launch a coding agent session in background to execute a development task. Sessions are multi-turn — they stay open for follow-up messages via agent_respond. Supports resuming previous sessions. Returns a session ID and name for tracking.",parameters:g.Object({prompt:g.String({description:"The task prompt to execute"}),name:g.Optional(g.String({description:"Short human-readable name for the session (kebab-case, e.g. 'fix-auth'). Auto-generated from prompt if omitted."})),workdir:g.Optional(g.String({description:"Working directory (defaults to cwd)"})),model:g.Optional(g.String({description:"Model name to use"})),system_prompt:g.Optional(g.String({description:"Additional system prompt"})),allowed_tools:g.Optional(g.Array(g.String(),{description:"List of allowed tools"})),resume_session_id:g.Optional(g.String({description:"Session reference to continue or fork from. Prefer the plugin session ID shown by agent_launch or agent_sessions; persisted backend conversation IDs also resolve when available."})),fork_session:g.Optional(g.Boolean({description:"When resuming, fork to a new session instead of continuing the existing one. Use with resume_session_id."})),force_new_session:g.Optional(g.Boolean({description:"Bypass resume-first protection and start a brand-new linked session even when a resumable or active linked session already exists."})),permission_mode:g.Optional(g.Union([g.Literal("default"),g.Literal("plan"),g.Literal("bypassPermissions")],{description:"Permission mode: 'default' (plugin-managed interactive execution), 'plan' (present the plan first and block implementation until approval), 'bypassPermissions' (fully autonomous execution). Defaults to plugin config ('plan' by default)."})),plan_approval:g.Optional(g.Union([g.Literal("ask"),g.Literal("delegate"),g.Literal("approve")],{description:"Plan approval policy for this session: 'ask' (send the full plan to the user with Approve/Revise/Reject buttons), 'delegate' (orchestrator must review the full plan, then either approve directly or escalate back to the user with the same buttons), 'approve' (auto-approve after verification). Overrides the plugin-level planApproval setting."})),harness:g.Optional(g.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode'). Defaults to the plugin defaultHarness."})),worktree_strategy:g.Optional(g.Union([g.Literal("off"),g.Literal("manual"),g.Literal("ask"),g.Literal("delegate"),g.Literal("auto-merge"),g.Literal("auto-pr")],{description:"Worktree strategy: 'off' (no worktree), 'manual' (create worktree but no auto merge-back), 'ask' (prompt user with Merge/Open PR/Later/Discard buttons), 'delegate' (orchestrator decides), 'auto-merge' (merge automatically), 'auto-pr' (open/update a PR automatically). Defaults to the plugin config when unset."})),worktree_base_branch:g.Optional(g.String({description:"Base branch for worktree merge/PR operations (default: auto-detected or 'main')"})),worktree_pr_target_repo:g.Optional(g.String({description:"Target repository for cross-repo PRs (e.g. 'openai/codex' for fork-to-upstream workflow). If not set, auto-detected from 'upstream' remote or defaults to 'origin'."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!_f(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=xr(n,t,v);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};let{workdir:o,harness:i,resolvedModel:s,permissionMode:a,planApproval:d,originChannel:l,originThreadId:u,originSessionKey:f,route:p,resumeSessionId:k,resolvedResumeId:m,clearedPersistedCodexResume:c,reasoningEffort:h,fastMode:S}=r,b=n.resume_session_id?v.resolve(n.resume_session_id)??v.getPersistedSession(n.resume_session_id):void 0,x=!n.fork_session&&b?vt(b):void 0;if(x?.kind==="direct")return{content:[{type:"text",text:`Session ${b.name} [${Ld(b,n.resume_session_id)}] is already running. Use agent_respond(session='${n.resume_session_id}', message='<next instruction>') instead of agent_launch(resume_session_id=...).`}]};if(x?.kind==="unavailable")return{content:[{type:"text",text:`Resume unavailable for session ${b.name} [${Ld(b,n.resume_session_id)}] (${x.reason}). Use agent_launch(prompt='<new task>') for a fresh session or set fork_session=true to fork from prior context.`}]};let T=b&&"resumedFromSessionName"in b?b.resumedFromSessionName:void 0,A=x?.kind==="resume"&&!n.fork_session?T??b?.name:void 0,y=A&&!n.name?A:n.name,w=n.worktree_strategy??D.defaultWorktreeStrategy??"off",L=n.fork_session?void 0:x?.kind==="resume"||x?.kind==="relaunch"?x.stableSessionId:void 0;if(w!=="off"&&Ef(v)&&v.checkRepoPolicyForLaunch(o,n.worktree_strategy).ok===!1)return{content:[{type:"text",text:v.requestRepoPolicyForLaunch({route:p,prompt:n.prompt,workdir:o,name:y,model:s,reasoningEffort:h,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:k,resumedFromSessionName:A,resumeWorktreeFrom:m,sessionIdOverride:L,clearedPersistedCodexResume:c,forkSession:k?n.fork_session:!1,forceNewSession:n.force_new_session,permissionMode:a,planApproval:d,harness:i,worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo,originAgentId:t.agentId||void 0})}]};let K=v.spawn({prompt:n.prompt,sessionIdOverride:L,name:y,workdir:o,model:s,reasoningEffort:h,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:k,resumedFromSessionName:A,resumeWorktreeFrom:m,forkSession:k?n.fork_session:!1,multiTurn:!0,permissionMode:a,planApproval:d,codexApprovalPolicy:i==="codex"?"never":void 0,originChannel:l,originThreadId:u,originAgentId:t.agentId||void 0,originSessionKey:f,route:p,harness:i,taskLifecycle:Dr(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:$f(v)?v.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:d,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,resumeSessionName:A,forkSession:n.fork_session,clearedPersistedCodexResume:c},K):ar({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:d,resumeSessionId:n.resume_session_id,resumeSessionName:A,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:c},{id:K.id,name:K.name,model:K.model,reasoningEffort:K.reasoningEffort??it(i),fastMode:K.fastMode??S,worktreeStrategy:K.worktreeStrategy??n.worktree_strategy??D.defaultWorktreeStrategy??"off",repoIntegrationPolicy:K.repoIntegrationPolicy,repoProvider:K.repoProvider,worktreePath:K.worktreePath,originalWorkdir:K.originalWorkdir})}]}}catch(r){let o=Mf(r),i=o.includes("Max sessions")?"":`
76
+ `)}yt();var Sf="openclaw-code-agent",vf=160,Cr={create(){},progress(){},finalize(){}};function Mr(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function as(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function wf(t){let e=t.prompt.trim().replace(/\s+/g," ");return ce(e||t.name,vf)}function Od(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 Nd(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 _r(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 Pf(t){return $r(t.lifecycle)}function $r(t){return t==="awaiting_plan_decision"||t==="awaiting_user_input"||t==="awaiting_worktree_decision"||t==="suspended"}function bf(t){if(t.pendingPlanApproval||t.pendingWorktreeDecisionSince)return!0;if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;return e==="suspended"?t.runtimeRecovery.rawResumable===!0||t.resumable===!0:$r(e)}return t.lifecycle==="suspended"?t.resumable===!0:$r(t.lifecycle)}function Rf(t){if(t.runtimeRecovery?.reason==="persisted-running-without-runtime"){let e=t.runtimeRecovery.rawLifecycle;if($r(e))return e}return t.lifecycle}function ss(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 Af(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 Er(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var ds=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:Sf,goal:wf(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:ss(e,"created",n),createdAt:e.startedAt,updatedAt:r}),e.taskFlowMirror=this.flow,this.lastProgressKey=this.progressKey(e,n)}catch(o){Mr("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=Od(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=ss(e,"progress",n),i=Date.now(),s=Pf(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=Er(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.lastProgressKey=r}catch(o){Mr("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=Nd(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":_r(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...ss(e,"terminal",r),terminalStatus:n,terminalSummary:_r(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:_r(e.status,e.killReason),updatedAt:o,endedAt:o});as("finalize",s),this.flow=Er(this.flow,s),this.flow&&(e.taskFlowMirror=this.flow),this.finalized=!0}catch(o){Mr("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function If(t){return t==="succeeded"||t==="failed"||t==="cancelled"||t==="lost"}function xf(t){if(!t?.trim())return;let e=xi()?.fromToolContext;if(typeof e!="function")return;let n=e({sessionKey:t});if(!n||typeof n!="object")return;let r=n;if(!(typeof r.setWaiting!="function"||typeof r.finish!="function"||typeof r.fail!="function"))return{setWaiting:r.setWaiting,finish:r.finish,fail:r.fail}}function Tf(t){return t.originSessionKey??t.route?.sessionKey}function Cf(t){return t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"Lost after OCA restart without live process":_r(t.status,t.killReason??"unknown")}function Wd(t){let e=t.taskFlowMirror?{...t.taskFlowMirror}:void 0;if(!e||If(e.status))return;let n=xf(Tf(t));if(!n)return;let r=Date.now();if(bf(t)){let l=Od({status:t.status,lifecycle:Rf(t)??"suspended"})??"Waiting",u=n.setWaiting({flowId:e.flowId,expectedRevision:e.revision,currentStep:l,stateJson:{phase:"progress",integration:"phase-1-managed-task-flow",sessionId:t.sessionId,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:l,reconciled:!0},waitJson:{reason:l,sessionId:t.sessionId},blockedSummary:l,updatedAt:r});return as("reconcile-waiting",u),Er(e,u)}let o=Nd({status:t.status,killReason:t.killReason??"unknown"})??"failed",i=Cf(t),s=t.completedAt??r,a={phase:"terminal",integration:"phase-1-managed-task-flow",sessionId:t.sessionId,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:i,terminalStatus:t.runtimeRecovery?.reason==="persisted-running-without-runtime"?"lost":o,terminalSummary:i,reconciled:!0,runtimeRecovery:t.runtimeRecovery},d=o==="succeeded"?n.finish({flowId:e.flowId,expectedRevision:e.revision,stateJson:a,updatedAt:s,endedAt:s}):n.fail({flowId:e.flowId,expectedRevision:e.revision,stateJson:a,blockedSummary:i,updatedAt:s,endedAt:s});return as("reconcile-terminal",d),Er(e,d)}function Dr(t){if(!t.sessionKey?.trim())return Cr;try{let e=xi()?.fromToolContext;if(typeof e!="function")return Cr;let n=e(t);return Af(n)?new ds(n):Cr}catch(e){return Mr("resolve",e),Cr}}function Mf(t){return t instanceof Error?t.message:String(t)}function Ld(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function _f(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function $f(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function Ef(t){return!!t&&typeof t=="object"&&typeof t.checkRepoPolicyForLaunch=="function"&&typeof t.requestRepoPolicyForLaunch=="function"}function Bd(t){return{name:"agent_launch",description:"Launch a coding agent session in background to execute a development task. Sessions are multi-turn — they stay open for follow-up messages via agent_respond. Supports resuming previous sessions. Returns a session ID and name for tracking.",parameters:g.Object({prompt:g.String({description:"The task prompt to execute"}),name:g.Optional(g.String({description:"Short human-readable name for the session (kebab-case, e.g. 'fix-auth'). Auto-generated from prompt if omitted."})),workdir:g.Optional(g.String({description:"Working directory (defaults to cwd)"})),model:g.Optional(g.String({description:"Model name to use"})),system_prompt:g.Optional(g.String({description:"Additional system prompt"})),allowed_tools:g.Optional(g.Array(g.String(),{description:"List of allowed tools"})),resume_session_id:g.Optional(g.String({description:"Session reference to continue or fork from. Prefer the plugin session ID shown by agent_launch or agent_sessions; persisted backend conversation IDs also resolve when available."})),fork_session:g.Optional(g.Boolean({description:"When resuming, fork to a new session instead of continuing the existing one. Use with resume_session_id."})),force_new_session:g.Optional(g.Boolean({description:"Bypass resume-first protection and start a brand-new linked session even when a resumable or active linked session already exists."})),permission_mode:g.Optional(g.Union([g.Literal("default"),g.Literal("plan"),g.Literal("bypassPermissions")],{description:"Permission mode: 'default' (plugin-managed interactive execution), 'plan' (present the plan first and block implementation until approval), 'bypassPermissions' (fully autonomous execution). Defaults to plugin config ('plan' by default)."})),plan_approval:g.Optional(g.Union([g.Literal("ask"),g.Literal("delegate"),g.Literal("approve")],{description:"Plan approval policy for this session: 'ask' (send the full plan to the user with Approve/Revise/Reject buttons), 'delegate' (orchestrator must review the full plan, then either approve directly or escalate back to the user with the same buttons), 'approve' (auto-approve after verification). Overrides the plugin-level planApproval setting."})),harness:g.Optional(g.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode'). Defaults to the plugin defaultHarness."})),worktree_strategy:g.Optional(g.Union([g.Literal("off"),g.Literal("manual"),g.Literal("ask"),g.Literal("delegate"),g.Literal("auto-merge"),g.Literal("auto-pr")],{description:"Worktree strategy: 'off' (no worktree), 'manual' (create worktree but no auto merge-back), 'ask' (prompt user with Merge/Open PR/Later/Discard buttons), 'delegate' (orchestrator decides), 'auto-merge' (merge automatically), 'auto-pr' (open/update a PR automatically). Defaults to the plugin config when unset."})),worktree_base_branch:g.Optional(g.String({description:"Base branch for worktree merge/PR operations (default: auto-detected or 'main')"})),worktree_pr_target_repo:g.Optional(g.String({description:"Target repository for cross-repo PRs (e.g. 'openai/codex' for fork-to-upstream workflow). If not set, auto-detected from 'upstream' remote or defaults to 'origin'."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!_f(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=xr(n,t,v);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};let{workdir:o,harness:i,resolvedModel:s,permissionMode:a,planApproval:d,originChannel:l,originThreadId:u,originSessionKey:f,route:p,resumeSessionId:k,resolvedResumeId:m,clearedPersistedCodexResume:c,reasoningEffort:h,fastMode:S}=r,P=n.resume_session_id?v.resolve(n.resume_session_id)??v.getPersistedSession(n.resume_session_id):void 0,x=!n.fork_session&&P?vt(P):void 0;if(x?.kind==="direct")return{content:[{type:"text",text:`Session ${P.name} [${Ld(P,n.resume_session_id)}] is already running. Use agent_respond(session='${n.resume_session_id}', message='<next instruction>') instead of agent_launch(resume_session_id=...).`}]};if(x?.kind==="unavailable")return{content:[{type:"text",text:`Resume unavailable for session ${P.name} [${Ld(P,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 C=P&&"resumedFromSessionName"in P?P.resumedFromSessionName:void 0,A=x?.kind==="resume"&&!n.fork_session?C??P?.name:void 0,y=A&&!n.name?A:n.name,w=n.worktree_strategy??D.defaultWorktreeStrategy??"off",L=n.fork_session?void 0:x?.kind==="resume"||x?.kind==="relaunch"?x.stableSessionId:void 0;if(w!=="off"&&Ef(v)&&v.checkRepoPolicyForLaunch(o,n.worktree_strategy).ok===!1)return{content:[{type:"text",text:v.requestRepoPolicyForLaunch({route:p,prompt:n.prompt,workdir:o,name:y,model:s,reasoningEffort:h,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:k,resumedFromSessionName:A,resumeWorktreeFrom:m,sessionIdOverride:L,clearedPersistedCodexResume:c,forkSession:k?n.fork_session:!1,forceNewSession:n.force_new_session,permissionMode:a,planApproval:d,harness:i,worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo,originAgentId:t.agentId||void 0})}]};let K=v.spawn({prompt:n.prompt,sessionIdOverride:L,name:y,workdir:o,model:s,reasoningEffort:h,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:x?.kind==="resume"?x.resumeSessionId:k,resumedFromSessionName:A,resumeWorktreeFrom:m,forkSession:k?n.fork_session:!1,multiTurn:!0,permissionMode:a,planApproval:d,codexApprovalPolicy:i==="codex"?"never":void 0,originChannel:l,originThreadId:u,originAgentId:t.agentId||void 0,originSessionKey:f,route:p,harness:i,taskLifecycle:Dr(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:$f(v)?v.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:d,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,resumeSessionName:A,forkSession:n.fork_session,clearedPersistedCodexResume:c},K):ar({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??D.permissionMode,planApproval:d,resumeSessionId:n.resume_session_id,resumeSessionName:A,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:c},{id:K.id,name:K.name,model:K.model,reasoningEffort:K.reasoningEffort??it(i),fastMode:K.fastMode??S,worktreeStrategy:K.worktreeStrategy??n.worktree_strategy??D.defaultWorktreeStrategy??"off",repoIntegrationPolicy:K.repoIntegrationPolicy,repoProvider:K.repoProvider,worktreePath:K.worktreePath,originalWorkdir:K.originalWorkdir})}]}}catch(r){let o=Mf(r),i=o.includes("Max sessions")?"":`
77
77
 
78
78
  Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}se();V();ae();import{existsSync as ys,readFileSync as hl}from"fs";import{EventEmitter as pg}from"events";import{webcrypto as qd}from"node:crypto";var Fd="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var Df=128,ct,Yt;function Of(t){if(t<0)throw new RangeError("Wrong ID size");try{!ct||ct.length<t?(ct=Buffer.allocUnsafe(t*Df),qd.getRandomValues(ct),Yt=0):Yt+t>ct.length&&(qd.getRandomValues(ct),Yt=0)}catch(e){throw ct=void 0,e}Yt+=t}function Or(t=21){Of(t|=0);let e="";for(let n=Yt-t;n<Yt;n++)e+=Fd[ct[n]&63];return e}rs();ae();ne();var Ud={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function te(t,e){return Object.hasOwn(t,e)}var Kd=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function Nf(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 he(t){return{...t,approvalExecutionState:Nf(t)}}function ls(t,e){switch(e.type){case"initialize":return he({...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"?he({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?he({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):he({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return he({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return he({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return he({...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 he({...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 he({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return he({...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 he({...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 he({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return he({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return he({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":Kd.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return he({...t,deliveryState:e.deliveryState})}}function Vd(t,e){let n={...t,...te(e,"lifecycle")?{lifecycle:e.lifecycle}:{},...te(e,"approvalState")?{approvalState:e.approvalState}:{},...te(e,"approvalExecutionState")?{approvalExecutionState:e.approvalExecutionState}:{},...te(e,"worktreeState")?{worktreeState:e.worktreeState}:{},...te(e,"runtimeState")?{runtimeState:e.runtimeState}:{},...te(e,"deliveryState")?{deliveryState:e.deliveryState}:{},...te(e,"requestedPermissionMode")?{requestedPermissionMode:e.requestedPermissionMode}:{},...te(e,"currentPermissionMode")?{currentPermissionMode:e.currentPermissionMode}:{},...te(e,"pendingPlanApproval")?{pendingPlanApproval:e.pendingPlanApproval}:{},...te(e,"planApprovalContext")?{planApprovalContext:e.planApprovalContext}:{},...te(e,"planDecisionVersion")?{planDecisionVersion:e.planDecisionVersion}:{},...te(e,"actionablePlanDecisionVersion")?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...te(e,"canonicalPlanPromptVersion")?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...te(e,"approvalPromptRequiredVersion")?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...te(e,"approvalPromptVersion")?{approvalPromptVersion:e.approvalPromptVersion}:{},...te(e,"approvalPromptStatus")?{approvalPromptStatus:e.approvalPromptStatus}:{},...te(e,"approvalPromptTransport")?{approvalPromptTransport:e.approvalPromptTransport}:{},...te(e,"approvalPromptMessageKind")?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...te(e,"approvalPromptLastAttemptAt")?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...te(e,"approvalPromptDeliveredAt")?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...te(e,"approvalPromptFailedAt")?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{},...te(e,"planModeApproved")?{planModeApproved:e.planModeApproved}:{}};return e.approvalState==="changes_requested"&&e.pendingPlanApproval===void 0&&(n={...n,pendingPlanApproval:!1}),n.pendingPlanApproval?n={...n,approvalState:"pending",actionablePlanDecisionVersion:n.actionablePlanDecisionVersion??n.planDecisionVersion,lifecycle:"awaiting_plan_decision"}:n.approvalState==="changes_requested"&&(n={...n,actionablePlanDecisionVersion:void 0,lifecycle:"awaiting_user_input"}),te(e,"pendingWorktreeDecisionSince")&&e.pendingWorktreeDecisionSince!==void 0||n.worktreeState==="pending_decision"?n=ls(n,{type:"worktree.decision_requested"}):Kd.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),he(n)}var Nr=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 Wf}from"crypto";import{appendFileSync as Lf}from"fs";import{tmpdir as Bf}from"os";import{join as Ff}from"path";var jd=2e3,qf=/^[A-Za-z0-9_.-]+$/;function Uf(t){return qf.test(t)?t:`hashed+${Wf("sha256").update(t,"utf8").digest("hex")}`}function wt(t){return Ff(Bf(),`openclaw-agent-${Uf(t)}.txt`)}function Kf(t,e){if(!e)return;let n=e.split(`
79
- `),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function Gd(t,e,n){Kf(t,n),t.length>jd&&t.splice(0,t.length-jd);try{Lf(wt(e),n,"utf-8")}catch{}return t}var Wr=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 Lr=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?`
80
- ${e}`:e,this.deps.emitOutput(e)}noteToolCall(e){let{name:n,input:r,currentPermissionMode:o,permissionMode:i,planModeApproved:s}=e;if(n==="Write"){let a=r;typeof a?.file_path=="string"&&a.file_path.includes("/.claude/plans/")&&this.deps.setPlanFilePath(a.file_path)}n==="AskUserQuestion"?(this.lastTurnHadQuestion=!0,this.deps.applyInputRequested(),(o==="plan"||i==="plan")&&!s&&this.deps.markPendingPlanApproval("plan-mode")):(n==="ExitPlanMode"||n==="set_permission_mode")&&!s&&(this.lastTurnHadQuestion=!0,this.deps.markPendingPlanApproval("plan-mode")),this.deps.emitToolUse(n,r)}notePendingInput(){this.lastTurnHadQuestion=!0,this.deps.applyInputRequested(),this.waitingForInputFired||(this.waitingForInputFired=!0,this.deps.emitTurnEnd(!0))}clearResolvedPendingInput(e,n){if(!(!e||n?.requestId===e))return n}notePlanArtifact(e,n){if(this.currentTurnPlanArtifact=e,this.deps.setLatestPlanArtifact(e),!n)return;let r=e.markdown.trim();!r||this.currentTurnText.trim()===r||(this.deps.appendOutput(r),this.currentTurnText=r,this.deps.emitOutput(r))}noteSettingsChanged(e){let{oldMode:n,permissionMode:r,planModeApproved:o}=e;if(r)return r!=="plan"&&n==="plan"&&!o&&(this.deps.markPendingPlanApproval("plan-mode"),this.lastTurnHadQuestion=!0),r}finishSuccessfulTurn(e){let{currentPermissionMode:n,permissionMode:r,pendingPlanApproval:o,planModeApproved:i,pendingInputState:s,hasPendingMessages:a}=e,d=o;(n==="plan"||r==="plan")&&!d&&!i&&(this.deps.markPendingPlanApproval("plan-mode"),d=!0);let l=d||this.lastTurnHadQuestion||!!s;if(this.turnInProgress=a,l&&!this.waitingForInputFired)this.waitingForInputFired=!0,d||this.deps.markAwaitingUserInput(),this.deps.emitTurnEnd(!0);else if(!a&&!l){if(this.deps.queueWorktreeFinalizationPrompt?.()){this.turnInProgress=!0;return}this.deps.completeTurn(),this.deps.emitTurnEnd(!1)}}finishTerminalTurn(){this.turnInProgress=!1}finishInterruptedTurn(e){this.turnInProgress=e,this.waitingForInputFired=!1,this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}resetAfterRun(){this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}};var Br=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}};Ae();var cg=[/\bfailed to authenticate\b/i,/\binvalid bearer token\b/i,/\bapi error:\s*401\b/i,/\b401\s+unauthori[sz]ed\b/i,/\binvalid api key\b/i,/\binvalid authentication\b/i,/\bauthentication failed\b/i,/\bauth(?:orization)? error\b/i];function hs(t){return t?.trim()?cg.some(e=>e.test(t)):!1}function fl(t){if(!t?.trim())return;let e=t.split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return e.find(n=>hs(n))??e.at(-1)}var mg=120*1e3;function Zr(t){return t instanceof Error?t.message:String(t)}function fg(t,e){JSON.stringify({component:"Session",event:t,at:new Date().toISOString(),...e})}function gg(t){return t?{backendRefKind:t.kind,hasBackendConversationId:!!t.conversationId,hasBackendRunId:!!t.runId,hasBackendWorktreeId:!!t.worktreeId,hasBackendWorktreePath:!!t.worktreePath}:{}}var Xr=class extends pg{id;name;harnessSessionId;backendRef;harness;harnessHandle;prompt;workdir;model;reasoningEffort;fastMode;systemPrompt;allowedTools;permissionMode;requestedPermissionMode;planApproval;codexApprovalPolicy;currentPermissionMode;pendingModeSwitch;resumeSessionId;resumedFromSessionName;forkSession;worktreePath;originalWorkdir;worktreeBranch;worktreeParentBranch;worktreeStrategy;repoIntegrationPolicy;repoIntegrationPolicySource;repoProvider;worktreeBaseBranch;worktreePrTargetRepo;autoMergeParentSessionId;autoMergeConflictResolutionAttemptCount;autoMergeResolverSessionId;worktreePushRemote;worktreeDisposition;worktreePrUrl;worktreePrNumber;worktreeMerged;worktreeMergedAt;worktreeLifecycle;worktreeState="none";multiTurn;goalTaskId;messageStream;_status="starting";error;startedAt;completedAt;abortController;outputBuffer=[];result;costUsd=0;originChannel;originThreadId;originAgentId;originSessionKey;route;pendingInputState;pendingPlanApproval=!1;planApprovalContext;planDecisionVersion=0;actionablePlanDecisionVersion;canonicalPlanPromptVersion;approvalPromptRequiredVersion;approvalPromptVersion;approvalPromptStatus="not_sent";approvalPromptTransport="none";approvalPromptMessageKind="none";approvalPromptLastAttemptAt;approvalPromptDeliveredAt;approvalPromptFailedAt;planFilePath;killReason="unknown";planModeApproved=!1;turnRuntime;harnessEvents;worktreeFinalizationPromptIssued=!1;lifecycle="starting";approvalState="not_required";approvalExecutionState="not_plan_gated";approvalRationale;latestPlanArtifact;latestPlanArtifactVersion;runtimeState="live";taskFlowMirror;deliveryState="idle";canUseTool;autoRespondCount=0;timers=new Wr;constructor(e,n){super(),this.id=e.sessionIdOverride??Or(8),this.name=n,this.harness=e.harness?xn(e.harness):Ad(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??Lt(this.harness.name),this.reasoningEffort=e.reasoningEffort??it(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??Bt(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??D.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??D.planApproval,this.codexApprovalPolicy=this.harness.name==="codex"?"never":void 0,this.currentPermissionMode=this.permissionMode,this.originChannel=e.originChannel,this.originThreadId=e.originThreadId,this.originAgentId=e.originAgentId,this.originSessionKey=e.originSessionKey,this.route=e.route?{...e.route}:void 0,this.backendRef=e.backendRef?{...e.backendRef}:void 0,this.resumeSessionId=e.resumeSessionId,this.resumedFromSessionName=e.resumedFromSessionName,this.forkSession=e.forkSession,this.multiTurn=e.multiTurn??!0,this.goalTaskId=e.goalTaskId,this.worktreeStrategy=e.worktreeStrategy,this.repoIntegrationPolicy=e.repoIntegrationPolicy,this.repoIntegrationPolicySource=e.repoIntegrationPolicySource,this.repoProvider=e.repoProvider,this.worktreeBaseBranch=e.worktreeBaseBranch,this.worktreeParentBranch=e.worktreeParentBranch,e.worktreePrTargetRepo&&(this.worktreePrTargetRepo=e.worktreePrTargetRepo),e.autoMergeParentSessionId&&(this.autoMergeParentSessionId=e.autoMergeParentSessionId),e.autoMergeConflictResolutionAttemptCount!==void 0&&(this.autoMergeConflictResolutionAttemptCount=e.autoMergeConflictResolutionAttemptCount),e.autoMergeResolverSessionId&&(this.autoMergeResolverSessionId=e.autoMergeResolverSessionId),this.canUseTool=e.canUseTool,this.startedAt=Date.now(),this.abortController=new AbortController,this.turnRuntime=new Lr({appendOutput:r=>Gd(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 Br({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??=Se(r.worktreePath),this.worktreeStrategy&&this.worktreeStrategy!=="off"&&this.applyControlEvent({type:"worktree.state_set",worktreeState:"provisioned"}))},noteRunStarted:r=>{this.backendRef&&(this.backendRef={...this.backendRef,runId:r})},transitionRunning:()=>{this._status==="starting"&&this.transition("running")},noteTextDelta:(r,o)=>this.turnRuntime.noteTextDelta(r,o),noteToolCall:r=>this.turnRuntime.noteToolCall(r),setPendingInputState:r=>{this.pendingInputState=r},notePendingInput:()=>this.turnRuntime.notePendingInput(),clearResolvedPendingInput:(r,o)=>this.turnRuntime.clearResolvedPendingInput(r,o),notePlanArtifact:r=>this.turnRuntime.notePlanArtifact(r.artifact,r.finalized),noteSettingsChanged:r=>this.turnRuntime.noteSettingsChanged(r),setCurrentPermissionMode:r=>{this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r})},handleRunCompleted:r=>{let o=r.outcome??(r.success?"completed":"failed"),i=r.num_turns===0?[r.result,...this.outputBuffer.slice(-5)].filter(f=>typeof f=="string").join(`
81
- `):"",s=o==="completed"&&hs(i),a=s?"failed":o,d=s?fl(i)??r.result:r.result;this.result={subtype:a==="interrupted"?"interrupted":a==="completed"?"success":"error",duration_ms:r.duration_ms,total_cost_usd:r.total_cost_usd,num_turns:r.num_turns,result:d,is_error:a==="failed",session_id:r.session_id},this.costUsd=r.total_cost_usd;let l=this.multiTurn&&this.messageStream&&a==="interrupted",u=this.multiTurn&&this.messageStream&&a==="completed";l?(this.resetIdleTimer(),this.turnRuntime.finishInterruptedTurn(this.messageStream?.hasPending()===!0)):u?(this.resetIdleTimer(),this.turnRuntime.finishSuccessfulTurn({currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,pendingPlanApproval:this.pendingPlanApproval,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState,hasPendingMessages:this.messageStream?.hasPending()===!0})):(this.turnRuntime.finishTerminalTurn(),this.transitionToTerminal(a==="completed"?"completed":"failed",{...a==="failed"&&d?{error:d}:{}})),this.turnRuntime.resetAfterRun(),this.pendingInputState=void 0}}),this.applyControlEvent({type:"initialize",hasWorktree:!!(this.worktreeStrategy&&this.worktreeStrategy!=="off")}),(e.planModeApproved!==void 0||e.approvalState!==void 0||e.approvalExecutionState!==void 0||e.approvalRationale!==void 0||e.pendingPlanApproval!==void 0||e.planApprovalContext!==void 0||e.planDecisionVersion!==void 0||e.actionablePlanDecisionVersion!==void 0||e.canonicalPlanPromptVersion!==void 0||e.approvalPromptRequiredVersion!==void 0||e.approvalPromptVersion!==void 0||e.approvalPromptStatus!==void 0||e.approvalPromptTransport!==void 0||e.approvalPromptMessageKind!==void 0||e.approvalPromptLastAttemptAt!==void 0||e.approvalPromptDeliveredAt!==void 0||e.approvalPromptFailedAt!==void 0)&&this.applyControlPatch({...e.planModeApproved!==void 0?{planModeApproved:e.planModeApproved}:{},...e.approvalState!==void 0?{approvalState:e.approvalState}:{},...e.approvalExecutionState!==void 0?{approvalExecutionState:e.approvalExecutionState}:{},...e.pendingPlanApproval!==void 0?{pendingPlanApproval:e.pendingPlanApproval}:{},...e.planApprovalContext!==void 0?{planApprovalContext:e.planApprovalContext}:{},...e.planDecisionVersion!==void 0?{planDecisionVersion:e.planDecisionVersion}:{},...e.actionablePlanDecisionVersion!==void 0?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...e.canonicalPlanPromptVersion!==void 0?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...e.approvalPromptRequiredVersion!==void 0?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...e.approvalPromptVersion!==void 0?{approvalPromptVersion:e.approvalPromptVersion}:{},...e.approvalPromptStatus!==void 0?{approvalPromptStatus:e.approvalPromptStatus}:{},...e.approvalPromptTransport!==void 0?{approvalPromptTransport:e.approvalPromptTransport}:{},...e.approvalPromptMessageKind!==void 0?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...e.approvalPromptLastAttemptAt!==void 0?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...e.approvalPromptDeliveredAt!==void 0?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...e.approvalPromptFailedAt!==void 0?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{}}),this.approvalRationale=e.approvalRationale}get status(){return this._status}get harnessName(){return this.harness.name}get backendKind(){return this.harness.backendKind}get backendCapabilities(){return this.harness.capabilities}get backendConversationId(){return O(this)}approvalSnapshot(){return{requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,approvalExecutionState:this.approvalExecutionState,approvalRationale:this.approvalRationale,planModeApproved:this.controlStateSnapshot().planModeApproved,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planApproval:this.planApproval,codexApprovalPolicy:this.codexApprovalPolicy}}worktreeSnapshot(){return{worktreePath:this.worktreePath,worktreeBranch:this.worktreeBranch,worktreeStrategy:this.worktreeStrategy,repoIntegrationPolicy:this.repoIntegrationPolicy,repoIntegrationPolicySource:this.repoIntegrationPolicySource,repoProvider:this.repoProvider,worktreeBaseBranch:this.worktreeBaseBranch,worktreeParentBranch:this.worktreeParentBranch,worktreePrTargetRepo:this.worktreePrTargetRepo,autoMergeParentSessionId:this.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:this.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:this.autoMergeResolverSessionId,worktreeLifecycle:this.worktreeLifecycle}}backendSnapshot(){return{harnessSessionId:this.harnessSessionId,backendRef:this.backendRef,harness:this.harnessName,backendKind:this.backendKind,backendConversationId:this.backendConversationId}}routingSnapshot(){return{route:this.route,originAgentId:this.originAgentId,originChannel:this.originChannel,originThreadId:this.originThreadId,originSessionKey:this.originSessionKey}}get waitingForInputFired(){return this.turnRuntime.waitingForInputFired}set waitingForInputFired(e){this.turnRuntime.waitingForInputFired=e}get turnInProgress(){return this.turnRuntime.turnInProgress}set turnInProgress(e){this.turnRuntime.turnInProgress=e}get currentTurnPlanArtifact(){return this.turnRuntime.currentTurnPlanArtifact}set currentTurnPlanArtifact(e){this.turnRuntime.currentTurnPlanArtifact=e}get duration(){return(this.completedAt??Date.now())-this.startedAt}get phase(){return this.lifecycle}get isExplicitlyResumable(){return this.status!=="running"&&this.status!=="completed"&&this.killReason!=="done"&&!!this.backendConversationId}transition(e){if(!Ud[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=bt(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(i=>`- ${i}`).join(`
79
+ `),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function Gd(t,e,n){Kf(t,n),t.length>jd&&t.splice(0,t.length-jd);try{Lf(wt(e),n,"utf-8")}catch{}return t}var Wr=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 Lr=class{constructor(e){this.deps=e}deps;waitingForInputFired=!1;lastTurnHadQuestion=!1;turnInProgress=!0;currentTurnText="";currentTurnPlanArtifact;pendingInputNotificationIdentity;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?`
80
+ ${e}`:e,this.deps.emitOutput(e)}noteToolCall(e){let{name:n,input:r,currentPermissionMode:o,permissionMode:i,planModeApproved:s}=e;if(n==="Write"){let a=r;typeof a?.file_path=="string"&&a.file_path.includes("/.claude/plans/")&&this.deps.setPlanFilePath(a.file_path)}n==="AskUserQuestion"?(this.lastTurnHadQuestion=!0,this.deps.applyInputRequested(),(o==="plan"||i==="plan")&&!s&&this.deps.markPendingPlanApproval("plan-mode")):(n==="ExitPlanMode"||n==="set_permission_mode")&&!s&&(this.lastTurnHadQuestion=!0,this.deps.markPendingPlanApproval("plan-mode")),this.deps.emitToolUse(n,r)}notePendingInput(e){this.lastTurnHadQuestion=!0,this.deps.applyInputRequested();let n=e?.activeQuestionIndex??0,r=e?.questions?.[n],o=e?.requestId?`${e.requestId}:${r?.id??(e.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:"request")}`:void 0;(!this.waitingForInputFired||o&&o!==this.pendingInputNotificationIdentity)&&(this.waitingForInputFired=!0,this.pendingInputNotificationIdentity=o,this.deps.emitTurnEnd(!0))}clearResolvedPendingInput(e,n){if(!e||n?.requestId===e){this.pendingInputNotificationIdentity=void 0;return}return n}notePlanArtifact(e,n){if(this.currentTurnPlanArtifact=e,this.deps.setLatestPlanArtifact(e),!n)return;let r=e.markdown.trim();!r||this.currentTurnText.trim()===r||(this.deps.appendOutput(r),this.currentTurnText=r,this.deps.emitOutput(r))}noteSettingsChanged(e){let{oldMode:n,permissionMode:r,planModeApproved:o}=e;if(r)return r!=="plan"&&n==="plan"&&!o&&(this.deps.markPendingPlanApproval("plan-mode"),this.lastTurnHadQuestion=!0),r}finishSuccessfulTurn(e){let{currentPermissionMode:n,permissionMode:r,pendingPlanApproval:o,planModeApproved:i,pendingInputState:s,hasPendingMessages:a}=e,d=o;(n==="plan"||r==="plan")&&!d&&!i&&(this.deps.markPendingPlanApproval("plan-mode"),d=!0);let l=d||this.lastTurnHadQuestion||!!s;if(this.turnInProgress=a,l&&!this.waitingForInputFired)this.waitingForInputFired=!0,d||this.deps.markAwaitingUserInput(),this.deps.emitTurnEnd(!0);else if(!a&&!l){if(this.deps.queueWorktreeFinalizationPrompt?.()){this.turnInProgress=!0;return}this.deps.completeTurn(),this.deps.emitTurnEnd(!1)}}finishTerminalTurn(){this.turnInProgress=!1}finishInterruptedTurn(e){this.turnInProgress=e,this.waitingForInputFired=!1,this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}resetAfterRun(){this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}};var Br=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(e.state);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}};Ae();var cg=[/\bfailed to authenticate\b/i,/\binvalid bearer token\b/i,/\bapi error:\s*401\b/i,/\b401\s+unauthori[sz]ed\b/i,/\binvalid api key\b/i,/\binvalid authentication\b/i,/\bauthentication failed\b/i,/\bauth(?:orization)? error\b/i];function hs(t){return t?.trim()?cg.some(e=>e.test(t)):!1}function fl(t){if(!t?.trim())return;let e=t.split(/\r?\n/).map(n=>n.trim()).filter(Boolean);return e.find(n=>hs(n))??e.at(-1)}var mg=120*1e3;function Zr(t){return t instanceof Error?t.message:String(t)}function fg(t,e){JSON.stringify({component:"Session",event:t,at:new Date().toISOString(),...e})}function gg(t){return t?{backendRefKind:t.kind,hasBackendConversationId:!!t.conversationId,hasBackendRunId:!!t.runId,hasBackendWorktreeId:!!t.worktreeId,hasBackendWorktreePath:!!t.worktreePath}:{}}var Xr=class extends pg{id;name;harnessSessionId;backendRef;harness;harnessHandle;prompt;workdir;model;reasoningEffort;fastMode;systemPrompt;allowedTools;permissionMode;requestedPermissionMode;planApproval;codexApprovalPolicy;currentPermissionMode;pendingModeSwitch;resumeSessionId;resumedFromSessionName;forkSession;worktreePath;originalWorkdir;worktreeBranch;worktreeParentBranch;worktreeStrategy;repoIntegrationPolicy;repoIntegrationPolicySource;repoProvider;worktreeBaseBranch;worktreePrTargetRepo;autoMergeParentSessionId;autoMergeConflictResolutionAttemptCount;autoMergeResolverSessionId;worktreePushRemote;worktreeDisposition;worktreePrUrl;worktreePrNumber;worktreeMerged;worktreeMergedAt;worktreeLifecycle;worktreeState="none";multiTurn;goalTaskId;messageStream;_status="starting";error;startedAt;completedAt;abortController;outputBuffer=[];result;costUsd=0;originChannel;originThreadId;originAgentId;originSessionKey;route;pendingInputState;lastPendingInputSubmissionRequiresMore=!1;pendingPlanApproval=!1;planApprovalContext;planDecisionVersion=0;actionablePlanDecisionVersion;canonicalPlanPromptVersion;approvalPromptRequiredVersion;approvalPromptVersion;approvalPromptStatus="not_sent";approvalPromptTransport="none";approvalPromptMessageKind="none";approvalPromptLastAttemptAt;approvalPromptDeliveredAt;approvalPromptFailedAt;planFilePath;killReason="unknown";planModeApproved=!1;turnRuntime;harnessEvents;worktreeFinalizationPromptIssued=!1;lifecycle="starting";approvalState="not_required";approvalExecutionState="not_plan_gated";approvalRationale;latestPlanArtifact;latestPlanArtifactVersion;runtimeState="live";taskFlowMirror;deliveryState="idle";canUseTool;autoRespondCount=0;timers=new Wr;constructor(e,n){super(),this.id=e.sessionIdOverride??Or(8),this.name=n,this.harness=e.harness?xn(e.harness):Ad(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??Lt(this.harness.name),this.reasoningEffort=e.reasoningEffort??it(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??Bt(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??D.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??D.planApproval,this.codexApprovalPolicy=this.harness.name==="codex"?"never":void 0,this.currentPermissionMode=this.permissionMode,this.originChannel=e.originChannel,this.originThreadId=e.originThreadId,this.originAgentId=e.originAgentId,this.originSessionKey=e.originSessionKey,this.route=e.route?{...e.route}:void 0,this.backendRef=e.backendRef?{...e.backendRef}:void 0,this.resumeSessionId=e.resumeSessionId,this.resumedFromSessionName=e.resumedFromSessionName,this.forkSession=e.forkSession,this.multiTurn=e.multiTurn??!0,this.goalTaskId=e.goalTaskId,this.worktreeStrategy=e.worktreeStrategy,this.repoIntegrationPolicy=e.repoIntegrationPolicy,this.repoIntegrationPolicySource=e.repoIntegrationPolicySource,this.repoProvider=e.repoProvider,this.worktreeBaseBranch=e.worktreeBaseBranch,this.worktreeParentBranch=e.worktreeParentBranch,e.worktreePrTargetRepo&&(this.worktreePrTargetRepo=e.worktreePrTargetRepo),e.autoMergeParentSessionId&&(this.autoMergeParentSessionId=e.autoMergeParentSessionId),e.autoMergeConflictResolutionAttemptCount!==void 0&&(this.autoMergeConflictResolutionAttemptCount=e.autoMergeConflictResolutionAttemptCount),e.autoMergeResolverSessionId&&(this.autoMergeResolverSessionId=e.autoMergeResolverSessionId),this.canUseTool=e.canUseTool,this.startedAt=Date.now(),this.abortController=new AbortController,this.turnRuntime=new Lr({appendOutput:r=>Gd(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 Br({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??=Se(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.setPendingInputState(r),notePendingInput:r=>this.turnRuntime.notePendingInput(r),clearResolvedPendingInput:(r,o)=>this.turnRuntime.clearResolvedPendingInput(r,o),notePlanArtifact:r=>this.turnRuntime.notePlanArtifact(r.artifact,r.finalized),noteSettingsChanged:r=>this.turnRuntime.noteSettingsChanged(r),setCurrentPermissionMode:r=>{this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r})},handleRunCompleted:r=>{let o=r.outcome??(r.success?"completed":"failed"),i=r.num_turns===0?[r.result,...this.outputBuffer.slice(-5)].filter(f=>typeof f=="string").join(`
81
+ `):"",s=o==="completed"&&hs(i),a=s?"failed":o,d=s?fl(i)??r.result:r.result;this.result={subtype:a==="interrupted"?"interrupted":a==="completed"?"success":"error",duration_ms:r.duration_ms,total_cost_usd:r.total_cost_usd,num_turns:r.num_turns,result:d,is_error:a==="failed",session_id:r.session_id},this.costUsd=r.total_cost_usd;let l=this.multiTurn&&this.messageStream&&a==="interrupted",u=this.multiTurn&&this.messageStream&&a==="completed";l?(this.resetIdleTimer(),this.turnRuntime.finishInterruptedTurn(this.messageStream?.hasPending()===!0)):u?(this.resetIdleTimer(),this.turnRuntime.finishSuccessfulTurn({currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,pendingPlanApproval:this.pendingPlanApproval,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState,hasPendingMessages:this.messageStream?.hasPending()===!0})):(this.turnRuntime.finishTerminalTurn(),this.transitionToTerminal(a==="completed"?"completed":"failed",{...a==="failed"&&d?{error:d}:{}})),this.turnRuntime.resetAfterRun(),this.setPendingInputState(void 0)}}),this.applyControlEvent({type:"initialize",hasWorktree:!!(this.worktreeStrategy&&this.worktreeStrategy!=="off")}),(e.planModeApproved!==void 0||e.approvalState!==void 0||e.approvalExecutionState!==void 0||e.approvalRationale!==void 0||e.pendingPlanApproval!==void 0||e.planApprovalContext!==void 0||e.planDecisionVersion!==void 0||e.actionablePlanDecisionVersion!==void 0||e.canonicalPlanPromptVersion!==void 0||e.approvalPromptRequiredVersion!==void 0||e.approvalPromptVersion!==void 0||e.approvalPromptStatus!==void 0||e.approvalPromptTransport!==void 0||e.approvalPromptMessageKind!==void 0||e.approvalPromptLastAttemptAt!==void 0||e.approvalPromptDeliveredAt!==void 0||e.approvalPromptFailedAt!==void 0)&&this.applyControlPatch({...e.planModeApproved!==void 0?{planModeApproved:e.planModeApproved}:{},...e.approvalState!==void 0?{approvalState:e.approvalState}:{},...e.approvalExecutionState!==void 0?{approvalExecutionState:e.approvalExecutionState}:{},...e.pendingPlanApproval!==void 0?{pendingPlanApproval:e.pendingPlanApproval}:{},...e.planApprovalContext!==void 0?{planApprovalContext:e.planApprovalContext}:{},...e.planDecisionVersion!==void 0?{planDecisionVersion:e.planDecisionVersion}:{},...e.actionablePlanDecisionVersion!==void 0?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...e.canonicalPlanPromptVersion!==void 0?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...e.approvalPromptRequiredVersion!==void 0?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...e.approvalPromptVersion!==void 0?{approvalPromptVersion:e.approvalPromptVersion}:{},...e.approvalPromptStatus!==void 0?{approvalPromptStatus:e.approvalPromptStatus}:{},...e.approvalPromptTransport!==void 0?{approvalPromptTransport:e.approvalPromptTransport}:{},...e.approvalPromptMessageKind!==void 0?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...e.approvalPromptLastAttemptAt!==void 0?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...e.approvalPromptDeliveredAt!==void 0?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...e.approvalPromptFailedAt!==void 0?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{}}),this.approvalRationale=e.approvalRationale}get status(){return this._status}get harnessName(){return this.harness.name}get backendKind(){return this.harness.backendKind}get backendCapabilities(){return this.harness.capabilities}get backendConversationId(){return O(this)}approvalSnapshot(){return{requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,approvalExecutionState:this.approvalExecutionState,approvalRationale:this.approvalRationale,planModeApproved:this.controlStateSnapshot().planModeApproved,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planApproval:this.planApproval,codexApprovalPolicy:this.codexApprovalPolicy}}worktreeSnapshot(){return{worktreePath:this.worktreePath,worktreeBranch:this.worktreeBranch,worktreeStrategy:this.worktreeStrategy,repoIntegrationPolicy:this.repoIntegrationPolicy,repoIntegrationPolicySource:this.repoIntegrationPolicySource,repoProvider:this.repoProvider,worktreeBaseBranch:this.worktreeBaseBranch,worktreeParentBranch:this.worktreeParentBranch,worktreePrTargetRepo:this.worktreePrTargetRepo,autoMergeParentSessionId:this.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:this.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:this.autoMergeResolverSessionId,worktreeLifecycle:this.worktreeLifecycle}}backendSnapshot(){return{harnessSessionId:this.harnessSessionId,backendRef:this.backendRef,harness:this.harnessName,backendKind:this.backendKind,backendConversationId:this.backendConversationId}}routingSnapshot(){return{route:this.route,originAgentId:this.originAgentId,originChannel:this.originChannel,originThreadId:this.originThreadId,originSessionKey:this.originSessionKey}}get waitingForInputFired(){return this.turnRuntime.waitingForInputFired}set waitingForInputFired(e){this.turnRuntime.waitingForInputFired=e}get turnInProgress(){return this.turnRuntime.turnInProgress}set turnInProgress(e){this.turnRuntime.turnInProgress=e}get currentTurnPlanArtifact(){return this.turnRuntime.currentTurnPlanArtifact}set currentTurnPlanArtifact(e){this.turnRuntime.currentTurnPlanArtifact=e}get duration(){return(this.completedAt??Date.now())-this.startedAt}get phase(){return this.lifecycle}get isExplicitlyResumable(){return this.status!=="running"&&this.status!=="completed"&&this.killReason!=="done"&&!!this.backendConversationId}transition(e){if(!Ud[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=bt(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(i=>`- ${i}`).join(`
82
82
  `),r=e.length>20?`
83
83
  - ...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(`
84
84
  `);return this.messageStream.push(this.harness.buildUserMessage(o,this.backendConversationId??"")),!0}async start(){this.logDiagnostic("harness.launch.start",{model:this.model,hasWorkdir:!!this.workdir,hasResumeSessionId:!!this.resumeSessionId,forkSessionRequested:this.forkSession===!0,hasBackendRef:!!this.backendRef});try{let e;this.multiTurn?(this.messageStream=new Nr,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:La(),canUseTool:this.canUseTool});this.harnessHandle=n,this.logDiagnostic("harness.launch.created",{hasStreamInput:!!n.streamInput,hasInterrupt:!!n.interrupt,hasPermissionModeSwitch:!!n.setPermissionMode}),this.setTimer("startup",mg,()=>{this._status==="starting"&&this.kill("startup-timeout")})}catch(e){let n=e instanceof Error?e.message:String(e);this.logDiagnostic("harness.launch.error",{error:n}),this.transitionToTerminal("failed",{error:n});return}this.consumeMessages(this.harnessHandle.messages).catch(e=>{let n=e instanceof Error?e.message:String(e),r=e instanceof Error?e.stack:void 0;this.logDiagnostic("harness.stream.error",{error:n}),console.error(`[Session ${this.id}] consumeMessages error: ${n}`,r),this.isActive&&this.transitionToTerminal("failed",{error:n})})}async sendMessage(e){if(this._status!=="running")throw new Error(`Session is not running (status: ${this._status})`);this.resetIdleTimer(),this.turnRuntime.beginUserTurn(),this.applyControlEvent({type:"turn.started"});let n=e;if(this.pendingModeSwitch){let r=this.pendingModeSwitch,o=!1,i=!1;if(this.harnessHandle?.setPermissionMode)try{await this.harnessHandle.setPermissionMode(r),this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r}),this.pendingModeSwitch=void 0,i=!0,o=!0}catch(s){throw console.error(`[Session ${this.id}] setPermissionMode(${r}) FAILED: ${Zr(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${Zr(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.]
85
85
 
86
86
  ${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.]
87
87
 
88
- ${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}${Zr(r)}`}if(this.multiTurn&&this.messageStream)this.messageStream.push(this.harness.buildUserMessage(n,this.backendConversationId??""));else if(this.harnessHandle?.streamInput){let r=this.harness.buildUserMessage(n,this.backendConversationId??"");async function*o(){yield r}await this.harnessHandle.streamInput(o())}else throw new Error("Session does not support follow-up messages (launched in single-turn mode).")}async interrupt(){return!this.turnInProgress||!this.harnessHandle?.interrupt?!1:(await this.harnessHandle.interrupt(),!0)}async submitPendingInputOption(e,n){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputOption)return!1;let r=await this.harnessHandle.submitPendingInputOption(e,n);return r&&(this.waitingForInputFired=!1),r}canSubmitPendingInputOption(){return!!(this.pendingInputState&&this.harnessHandle?.submitPendingInputOption)}async submitPendingInputText(e){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputText)return!1;let n=await this.harnessHandle.submitPendingInputText(e);return n&&(this.waitingForInputFired=!1),n}switchPermissionMode(e){this.pendingModeSwitch=e}get isActive(){return this._status==="starting"||this._status==="running"}kill(e){this.transitionToTerminal("killed",{reason:e})}complete(e="done"){this.transitionToTerminal("completed",{reason:e})}incrementAutoRespond(){this.autoRespondCount++}resetAutoRespond(){this.autoRespondCount=0}getOutput(e){return e===void 0?this.outputBuffer.slice():this.outputBuffer.slice(-e)}resetIdleTimer(){if(!this.multiTurn)return;let e=(D.idleTimeoutMinutes??15)*60*1e3;this.setTimer("idle",e,()=>{this._status==="running"&&(this.logDiagnostic("idle_timeout.fire",{idleTimeoutMinutes:D.idleTimeoutMinutes??15}),this.applyControlEvent({type:"terminal.entered",suspended:!0}),this.kill("idle-timeout"))})}teardown(){this.clearAllTimers(),this.completedAt||(this.completedAt=Date.now()),this.messageStream&&this.messageStream.end(),this.harnessHandle?.interrupt&&this.harnessHandle.interrupt().catch(e=>{`${this.id}${Zr(e)}`}),this.abortController.abort(),this.applyControlEvent({type:"terminal.entered",suspended:this.lifecycle==="suspended"})}transitionToTerminal(e,n={}){this.isActive&&(this.logDiagnostic("terminal.transition",{nextStatus:e,reason:n.reason,error:n.error,currentStatus:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState}),this.turnInProgress=!1,n.reason&&(this.killReason=n.reason),n.error!==void 0&&(this.error=n.error),this.completedAt=Date.now(),this.applyControlEvent({type:"terminal.entered",suspended:e==="killed"&&n.reason==="idle-timeout"}),this.transition(e),this.teardown())}async consumeMessages(e){let n=0;for await(let r of e){if(!this.isActive)break;this.resetIdleTimer(),n+=1,this.harnessEvents.applyMessage(r,{pendingPlanApproval:this.pendingPlanApproval,currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState})}this.logDiagnostic("harness.stream.end",{messageCount:n,activeAtEnd:this.isActive,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState})}controlStateSnapshot(){return{status:this._status,lifecycle:this.lifecycle,approvalState:this.approvalState,approvalExecutionState:this.approvalExecutionState,worktreeState:this.worktreeState,runtimeState:this.runtimeState,deliveryState:this.deliveryState,requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planModeApproved:this.planModeApproved}}applyControlEvent(e){let n=ls(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=Vd(this.controlStateSnapshot(),e);this.applyControlState(n)}setControlField(e,n){this.applyControlPatch({[e]:n})}applyControlState(e){let n=this.lifecycle;this.lifecycle=e.lifecycle,this.approvalState=e.approvalState,this.approvalExecutionState=e.approvalExecutionState,this.worktreeState=e.worktreeState,this.runtimeState=e.runtimeState,this.deliveryState=e.deliveryState,this.pendingPlanApproval=e.pendingPlanApproval,this.planApprovalContext=e.planApprovalContext,this.planDecisionVersion=e.planDecisionVersion,this.actionablePlanDecisionVersion=e.actionablePlanDecisionVersion,this.canonicalPlanPromptVersion=e.canonicalPlanPromptVersion,this.approvalPromptRequiredVersion=e.approvalPromptRequiredVersion,this.approvalPromptVersion=e.approvalPromptVersion,this.approvalPromptStatus=e.approvalPromptStatus,this.approvalPromptTransport=e.approvalPromptTransport,this.approvalPromptMessageKind=e.approvalPromptMessageKind,this.approvalPromptLastAttemptAt=e.approvalPromptLastAttemptAt,this.approvalPromptDeliveredAt=e.approvalPromptDeliveredAt,this.approvalPromptFailedAt=e.approvalPromptFailedAt,this.planModeApproved=e.planModeApproved,n!==this.lifecycle&&this.emit("lifecycleChange",this,this.lifecycle,n)}logDiagnostic(e,n={}){let{backendRef:r,harnessSessionId:o,...i}=n;fg(e,{sessionId:this.id,name:this.name,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState,harness:this.harnessName,hasHarnessSessionId:!!this.harnessSessionId,...gg(this.backendRef),...i})}};var hg=50,yg=1,kg=new Set(["starting","running","completed","failed","killed"]),Sg=5,vg=1440*60*1e3,eo=new Set(["merged","released","dismissed","no_change"]);function wg(t){let e=Number(t);return!Number.isFinite(e)||e<yg?hg:Math.floor(e)}function Pg(t){return typeof t=="string"&&kg.has(t)}function bg(t){let e=t.split(`
88
+ ${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}${Zr(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=this.pendingInputState.activeQuestionIndex,o=this.pendingInputState.questions?.length,i=await this.harnessHandle.submitPendingInputOption(e,n);return i&&(this.lastPendingInputSubmissionRequiresMore=r!=null&&o!=null&&r+1<o,this.waitingForInputFired=!1),i}canSubmitPendingInputOption(){return!!(this.pendingInputState&&this.harnessHandle?.submitPendingInputOption)}setPendingInputState(e){this.pendingInputState=e,e||(this.lastPendingInputSubmissionRequiresMore=!1)}pendingInputSubmissionRequiresMore(){return this.lastPendingInputSubmissionRequiresMore}async submitPendingInputText(e){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputText)return!1;let n=this.pendingInputState.activeQuestionIndex,r=this.pendingInputState.questions?.length,o=await this.harnessHandle.submitPendingInputText(e);return o&&(this.lastPendingInputSubmissionRequiresMore=n!=null&&r!=null&&n+1<r,this.waitingForInputFired=!1),o}switchPermissionMode(e){this.pendingModeSwitch=e}get isActive(){return this._status==="starting"||this._status==="running"}kill(e){this.transitionToTerminal("killed",{reason:e})}complete(e="done"){this.transitionToTerminal("completed",{reason:e})}incrementAutoRespond(){this.autoRespondCount++}resetAutoRespond(){this.autoRespondCount=0}getOutput(e){return e===void 0?this.outputBuffer.slice():this.outputBuffer.slice(-e)}resetIdleTimer(){if(!this.multiTurn)return;let e=(D.idleTimeoutMinutes??15)*60*1e3;this.setTimer("idle",e,()=>{this._status==="running"&&(this.logDiagnostic("idle_timeout.fire",{idleTimeoutMinutes:D.idleTimeoutMinutes??15}),this.applyControlEvent({type:"terminal.entered",suspended:!0}),this.kill("idle-timeout"))})}teardown(){this.clearAllTimers(),this.completedAt||(this.completedAt=Date.now()),this.messageStream&&this.messageStream.end(),this.harnessHandle?.interrupt&&this.harnessHandle.interrupt().catch(e=>{`${this.id}${Zr(e)}`}),this.abortController.abort(),this.applyControlEvent({type:"terminal.entered",suspended:this.lifecycle==="suspended"})}transitionToTerminal(e,n={}){this.isActive&&(this.logDiagnostic("terminal.transition",{nextStatus:e,reason:n.reason,error:n.error,currentStatus:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState}),this.turnInProgress=!1,n.reason&&(this.killReason=n.reason),n.error!==void 0&&(this.error=n.error),this.completedAt=Date.now(),this.applyControlEvent({type:"terminal.entered",suspended:e==="killed"&&n.reason==="idle-timeout"}),this.transition(e),this.teardown())}async consumeMessages(e){let n=0;for await(let r of e){if(!this.isActive)break;this.resetIdleTimer(),n+=1,this.harnessEvents.applyMessage(r,{pendingPlanApproval:this.pendingPlanApproval,currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState})}this.logDiagnostic("harness.stream.end",{messageCount:n,activeAtEnd:this.isActive,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState})}controlStateSnapshot(){return{status:this._status,lifecycle:this.lifecycle,approvalState:this.approvalState,approvalExecutionState:this.approvalExecutionState,worktreeState:this.worktreeState,runtimeState:this.runtimeState,deliveryState:this.deliveryState,requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planModeApproved:this.planModeApproved}}applyControlEvent(e){let n=ls(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=Vd(this.controlStateSnapshot(),e);this.applyControlState(n)}setControlField(e,n){this.applyControlPatch({[e]:n})}applyControlState(e){let n=this.lifecycle;this.lifecycle=e.lifecycle,this.approvalState=e.approvalState,this.approvalExecutionState=e.approvalExecutionState,this.worktreeState=e.worktreeState,this.runtimeState=e.runtimeState,this.deliveryState=e.deliveryState,this.pendingPlanApproval=e.pendingPlanApproval,this.planApprovalContext=e.planApprovalContext,this.planDecisionVersion=e.planDecisionVersion,this.actionablePlanDecisionVersion=e.actionablePlanDecisionVersion,this.canonicalPlanPromptVersion=e.canonicalPlanPromptVersion,this.approvalPromptRequiredVersion=e.approvalPromptRequiredVersion,this.approvalPromptVersion=e.approvalPromptVersion,this.approvalPromptStatus=e.approvalPromptStatus,this.approvalPromptTransport=e.approvalPromptTransport,this.approvalPromptMessageKind=e.approvalPromptMessageKind,this.approvalPromptLastAttemptAt=e.approvalPromptLastAttemptAt,this.approvalPromptDeliveredAt=e.approvalPromptDeliveredAt,this.approvalPromptFailedAt=e.approvalPromptFailedAt,this.planModeApproved=e.planModeApproved,n!==this.lifecycle&&this.emit("lifecycleChange",this,this.lifecycle,n)}logDiagnostic(e,n={}){let{backendRef:r,harnessSessionId:o,...i}=n;fg(e,{sessionId:this.id,name:this.name,status:this._status,lifecycle:this.lifecycle,runtimeState:this.runtimeState,harness:this.harnessName,hasHarnessSessionId:!!this.harnessSessionId,...gg(this.backendRef),...i})}};var hg=50,yg=1,kg=new Set(["starting","running","completed","failed","killed"]),Sg=5,vg=1440*60*1e3,eo=new Set(["merged","released","dismissed","no_change"]);function wg(t){let e=Number(t);return!Number.isFinite(e)||e<yg?hg:Math.floor(e)}function Pg(t){return typeof t=="string"&&kg.has(t)}function bg(t){let e=t.split(`
89
89
  `);return e.at(-1)===""&&e.pop(),e}function ks(t){return t.backendRef?.conversationId??t.harnessSessionId}function Rg(t,e){return e&&eo.has(e)&&(!t||!eo.has(t))?e:t??e}function Ag(t,e){return e&&eo.has(e.state)&&(!t||!eo.has(t.state))?e:t??e}function yl(t,e,n){let r=hl(t,"utf-8"),o=bg(r);return e.full?o:o.slice(-n)}function Ig(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=wt(t.id);if(!ys(r))return null;try{return yl(r,e,n)}catch{return null}}function xg(t){let e=Be(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(`
90
90
  `)}function kl(t,e){let n=t.name||t.sessionId||ks(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(`
91
91
  `)}function Tg(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function Cg(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 gl(t,e){let n=kl(t,Cg(t)),r=ks(t),o=r?`
@@ -107,11 +107,11 @@ ${l}`}}catch{}return d}function no(t,e="all",n,r={}){let o=t.listPersistedSessio
107
107
 
108
108
  `)}function _g(t,e){let n=new Map;for(let r of e){if(!Pg(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=ks(r),a=r.sessionId??`persisted:${s??r.harnessSessionId}`;n.set(a,{id:r.sessionId??s??r.harnessSessionId,name:r.name||r.sessionId||s||r.harnessSessionId,status:r.status,startedAt:r.createdAt??0,completedAt:r.completedAt,duration:Math.max(0,o-i),prompt:r.prompt??"",workdir:r.workdir??"(unknown)",costUsd:r.costUsd??0,multiTurn:!0,phase:r.lifecycle??r.status,lifecycle:r.lifecycle,resumable:r.resumable,harness:r.harness,model:r.model,backendRef:r.backendRef,harnessSessionId:r.harnessSessionId,requestedPermissionMode:r.requestedPermissionMode,currentPermissionMode:r.currentPermissionMode,approvalExecutionState:r.approvalExecutionState,originChannel:r.originChannel,originThreadId:r.originThreadId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,worktreeStrategy:r.worktreeStrategy,worktreeState:r.worktreeState,worktreeLifecycle:r.worktreeLifecycle,worktreeMerged:r.worktreeMerged,worktreeMergedAt:r.worktreeMergedAt,worktreePrUrl:r.worktreePrUrl,recovered:!0,runtimeRecovery:r.runtimeRecovery})}for(let r of t){let o=n.get(r.id);n.set(r.id,{id:r.id,name:r.name,status:r.status,startedAt:r.startedAt,completedAt:r.completedAt,duration:r.duration,prompt:r.prompt,workdir:r.originalWorkdir??r.workdir,costUsd:r.costUsd,multiTurn:r.multiTurn,phase:r.phase,lifecycle:r.lifecycle,resumable:r.isExplicitlyResumable,harness:r.harnessName,model:r.model,backendRef:r.backendRef,harnessSessionId:r.harnessSessionId,requestedPermissionMode:r.requestedPermissionMode,currentPermissionMode:r.currentPermissionMode,approvalExecutionState:r.approvalExecutionState,originChannel:r.originChannel,originThreadId:r.originThreadId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,worktreeStrategy:r.worktreeStrategy,worktreeState:Rg(r.worktreeState,o?.worktreeState),worktreeLifecycle:Ag(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 $g(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 Sl(t){return{name:"agent_sessions",description:"List coding agent sessions with their status and progress. By default, shows the 5 most recent sessions; set `full` to show all sessions from the last 24 hours.",parameters:g.Object({status:g.Optional(g.Union([g.Literal("all"),g.Literal("running"),g.Literal("completed"),g.Literal("failed"),g.Literal("killed")],{description:'Filter by status (default "all")'})),full:g.Optional(g.Boolean({description:"Show all sessions from the last 24h instead of just the most recent 5"}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=$g(n),o=t?.workspaceDir?kt(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:no(v,r,o,{full:i})}]}}}}se();V();function ro(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 Eg(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 vl(t){return{name:"agent_kill",description:"Terminate or complete a running coding agent session by name or ID. Use reason='completed' to mark a session as successfully completed instead of killed.",parameters:g.Object({session:g.String({description:"Session name or ID to terminate"}),reason:g.Optional(g.Union([g.Literal("completed"),g.Literal("killed")],{description:"Reason for closing the session. 'completed' marks it as successfully done (sends ✅ notification). 'killed' (default) terminates it."}))}),async execute(e,n){return v?Eg(n)?{content:[{type:"text",text:ro(v,n.session,n.reason)}]}:{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, reason? }."}]}:{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]}}}}se();V();function Dg(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function oo(t){return{name:"agent_output",description:"Show recent output from a coding agent session (by name or ID).",parameters:g.Object({session:g.String({description:"Session name or ID to get output from"}),lines:g.Optional(g.Number({description:"Number of recent lines to show (default 50)"})),full:g.Optional(g.Boolean({description:"Show all available output"}))}),async execute(e,n){return v?Dg(n)?{content:[{type:"text",text:to(v,n.session,{full:n.full,lines:n.lines})}]}:{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, lines?, full? }."}]}:{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]}}}}se();V();ae();ne();var Og=10;function vs(t){return t instanceof Error?t.message:String(t)}function It(t){return G(t)??t.harnessSessionId??"unknown-session"}function Ng(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return Ir(t)??G(t)??O(t)}function wl(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!O(t)}function Wg(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 En(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='${It(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='${It(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='${It(t)}', fork_session=true, prompt='<new task>').`:`Use agent_respond(session='${It(t)}', message='<next instruction>') to continue the running session.`,o=n?` ${n}`:"";return{text:`Resume unavailable for session ${t.name} [${It(t)}] (${e}).${o} ${r}`,isError:!0}}async function Pl(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:Ir(e),workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,worktreeStrategy:e.worktreeStrategy,multiTurn:!0,originChannel:e.originChannel,originThreadId:e.originThreadId,originAgentId:e.originAgentId,originSessionKey:e.originSessionKey,route:e.route,permissionMode:e.currentPermissionMode,requestedPermissionMode:e.requestedPermissionMode??e.currentPermissionMode,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy,harness:"harnessName"in e?e.harnessName:e.harness},o=await t.spawnAndAwaitRunning(r,{notifyLaunch:!1});return t.notifySession(o,`▶️ [${o.name}] Relaunched fresh`,"notification",`agent-respond-relaunched:${o.id}:${o.startedAt}`),{text:`Session ${e.name} was relaunched fresh — it was killed during startup before the harness initialized. New session: ${o.name} [${o.id}].`}}catch(r){return{text:`Error relaunching session ${e.name} [${It(e)}]: ${vs(r)}`,isError:!0}}}var Lg=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
109
109
 
110
- `;function bl(t){let e=t?.replace(/\s+/g," ").trim();if(e)return ce(e,240)}function Ss(t){if(t.approvalState==="changes_requested"&&!io(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 io(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function Bg(t){return Ss(t)?!1:io(t)||t.currentPermissionMode==="plan"}function Fg(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 qg(t){return(t.planDecisionVersion??0)+1}function Rl(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:qg(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 Al(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function ws(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=Rl(o,"rejected");return n?(Al(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 Ps(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),o){let s=Rl(o,"changes_requested");n&&Al(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function Ug(t,e,n,r={}){let o=vt(e);if(!(o.kind==="resume"||wl(e)))return;let s=!!(r.approve&&Bg(e)),a=s?bl(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?Pl(t,e,n):En(e,o.reason);let d={prompt:s?Lg+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:Ng(e),worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,multiTurn:!0,originChannel:e.originChannel,originThreadId:e.originThreadId,originAgentId:e.originAgentId,originSessionKey:e.originSessionKey,route:e.route,permissionMode:s?"bypassPermissions":e.currentPermissionMode,requestedPermissionMode:e.requestedPermissionMode??e.currentPermissionMode,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy,pendingPlanApproval:s?!1:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:s?void 0:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,...s?{approvalState:"approved",approvalExecutionState:"approved_then_implemented",approvalRationale:a,planModeApproved:!0}:{},harness:"harnessName"in e?e.harnessName:e.harness},l=await t.spawnAndAwaitRunning(d,{notifyLaunch:!1});return s?(t.notifySession(l,`👍 [${l.name}] Plan approved (resumed)`,"plan-approved",`agent-respond-plan-approved-resumed:${l.id}:${l.startedAt}:${o.resumeSessionId}:v${e.planDecisionVersion??"unknown"}`),{text:`Plan approved for session ${l.name} [${l.id}]. Session resumed in bypassPermissions mode. Use agent_output to see the response.`}):(t.notifyResumedLaunch(l),{text:`Resume started for session ${l.name} [${l.id}]. Use agent_output to see the response.`})}catch(d){return En(e,"missing_backend_state",`Backend resume failed: ${vs(d)}`)}}async function Ie(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"}:vt(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?Wg(e.message):void 0;if(s==="approve")return Ie(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return Ps(t,n?.id??r?.sessionId??e.session);if(s==="reject")return ws(t,n?.id??r?.sessionId??e.session);if(e.approve){let d=Ss(o);if(d)return{text:d,isError:!0}}if(i.kind==="resume"||wl(o)){let d=await Ug(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(d)return d}else{if(i.kind==="relaunch")return Pl(t,o,e.message);if(i.kind==="unavailable")return En(o,i.reason)}if(!n)return Cn(r)?En(r,"completed"):{text:`Error: Session ${r.name} [${It(r)}] is not running (status: ${r.status}). Cannot send a message to a non-running session.`,isError:!0};if(n.status!=="running")return Cn(n)?En(n,"completed"):{text:`Error: Session ${n.name} [${n.id}] is not running (status: ${n.status}). Cannot send a message to a non-running session.`,isError:!0};let a=D.maxAutoResponds??Og;if(e.userInitiated)n.resetAutoRespond();else if(n.autoRespondCount>=a)return{text:`⚠️ Auto-respond limit reached (${n.autoRespondCount}/${a}). Ask the user to provide the answer for session ${n.name}. Then call agent_respond with their answer and set userInitiated: true to reset the counter.`};try{if(e.approve){let m=Ss(n);if(m)return{text:m,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let c=ce(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${c}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let m=ce(e.message,80);return{text:[`Pending input answered for session ${n.name} [${n.id}].`,` Message: "${m}"`,"Use agent_output to see the response."].join(`
111
- `)}}let l=!1;e.interrupt&&(l=await n.interrupt());let u=!!(e.approve&&io(n)),f=u?bl(e.approvalRationale):void 0,p="";if(e.approve&&io(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=f):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?p=`
112
- ℹ️ approve=true was set but session is already in bypassPermissions mode.`:e.approve?p=`
113
- ⚠️ approve=true was set but session has no pending plan approval.`:(n.pendingPlanApproval||n.approvalState==="changes_requested")&&(p=`
114
- ℹ️ 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&&Fg(t,n),u)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let m=ce(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${m}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let k=ce(e.message,80);return u?{text:`Plan approved for session ${n.name} [${n.id}]. Use agent_output to see the response.`}:{text:[`Message sent to session ${n.name} [${n.id}].`,l?" (redirected active turn first)":e.interrupt?" (no active turn to interrupt)":"",` Message: "${k}"`,p,"Use agent_output to see the response."].filter(Boolean).join(`
110
+ `;function bl(t){let e=t?.replace(/\s+/g," ").trim();if(e)return ce(e,240)}function Ss(t){if(t.approvalState==="changes_requested"&&!io(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 io(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function Bg(t){return Ss(t)?!1:io(t)||t.currentPermissionMode==="plan"}function Fg(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 qg(t){return(t.planDecisionVersion??0)+1}function Rl(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:qg(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 Al(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function ws(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=Rl(o,"rejected");return n?(Al(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 Ps(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),o){let s=Rl(o,"changes_requested");n&&Al(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function Ug(t,e,n,r={}){let o=vt(e);if(!(o.kind==="resume"||wl(e)))return;let s=!!(r.approve&&Bg(e)),a=s?bl(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?Pl(t,e,n):En(e,o.reason);let d={prompt:s?Lg+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:Ng(e),worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,multiTurn:!0,originChannel:e.originChannel,originThreadId:e.originThreadId,originAgentId:e.originAgentId,originSessionKey:e.originSessionKey,route:e.route,permissionMode:s?"bypassPermissions":e.currentPermissionMode,requestedPermissionMode:e.requestedPermissionMode??e.currentPermissionMode,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy,pendingPlanApproval:s?!1:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:s?void 0:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,...s?{approvalState:"approved",approvalExecutionState:"approved_then_implemented",approvalRationale:a,planModeApproved:!0}:{},harness:"harnessName"in e?e.harnessName:e.harness},l=await t.spawnAndAwaitRunning(d,{notifyLaunch:!1});return s?(t.notifySession(l,`👍 [${l.name}] Plan approved (resumed)`,"plan-approved",`agent-respond-plan-approved-resumed:${l.id}:${l.startedAt}:${o.resumeSessionId}:v${e.planDecisionVersion??"unknown"}`),{text:`Plan approved for session ${l.name} [${l.id}]. Session resumed in bypassPermissions mode. Use agent_output to see the response.`}):(t.notifyResumedLaunch(l),{text:`Resume started for session ${l.name} [${l.id}]. Use agent_output to see the response.`})}catch(d){return En(e,"missing_backend_state",`Backend resume failed: ${vs(d)}`)}}async function Ie(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"}:vt(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?Wg(e.message):void 0;if(s==="approve")return Ie(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return Ps(t,n?.id??r?.sessionId??e.session);if(s==="reject")return ws(t,n?.id??r?.sessionId??e.session);if(e.approve){let d=Ss(o);if(d)return{text:d,isError:!0}}if(i.kind==="resume"||wl(o)){let d=await Ug(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(d)return d}else{if(i.kind==="relaunch")return Pl(t,o,e.message);if(i.kind==="unavailable")return En(o,i.reason)}if(!n)return Cn(r)?En(r,"completed"):{text:`Error: Session ${r.name} [${It(r)}] is not running (status: ${r.status}). Cannot send a message to a non-running session.`,isError:!0};if(n.status!=="running")return Cn(n)?En(n,"completed"):{text:`Error: Session ${n.name} [${n.id}] is not running (status: ${n.status}). Cannot send a message to a non-running session.`,isError:!0};let a=D.maxAutoResponds??Og;if(e.userInitiated)n.resetAutoRespond();else if(n.autoRespondCount>=a)return{text:`⚠️ Auto-respond limit reached (${n.autoRespondCount}/${a}). Ask the user to provide the answer for session ${n.name}. Then call agent_respond with their answer and set userInitiated: true to reset the counter.`};try{if(e.approve){let h=Ss(n);if(h)return{text:h,isError:!0}}let d=n.pendingInputState?.activeQuestionIndex,l=n.pendingInputState?.questions?.length;if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let P=ce(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${P}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let h=ce(e.message,80),S=d!=null&&l!=null&&d+1<l;return{text:[S?`Pending input question answered for session ${n.name} [${n.id}]; more input is required.`:`Pending input request submitted for session ${n.name} [${n.id}].`,` Message: "${h}"`,S?"The next question is being delivered to the user.":"Use agent_output to see the response."].join(`
111
+ `)}}let f=!1;e.interrupt&&(f=await n.interrupt());let p=!!(e.approve&&io(n)),k=p?bl(e.approvalRationale):void 0,m="";if(e.approve&&io(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=k):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?m=`
112
+ ℹ️ approve=true was set but session is already in bypassPermissions mode.`:e.approve?m=`
113
+ ⚠️ approve=true was set but session has no pending plan approval.`:(n.pendingPlanApproval||n.approvalState==="changes_requested")&&(m=`
114
+ ℹ️ 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),p&&Fg(t,n),p)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let h=ce(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${h}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let c=ce(e.message,80);return p?{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}].`,f?" (redirected active turn first)":e.interrupt?" (no active turn to interrupt)":"",` Message: "${c}"`,m,"Use agent_output to see the response."].filter(Boolean).join(`
115
115
  `)}}catch(d){return{text:`Error sending message to session ${n.name} [${n.id}]: ${vs(d)}`,isError:!0}}}function Kg(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 Il(t){return{name:"agent_respond",description:"Send a follow-up message to a running coding agent session. The session must be running. All sessions are multi-turn.",parameters:g.Object({session:g.String({description:"Session name or ID to respond to"}),message:g.String({description:"The message to send to the session"}),interrupt:g.Optional(g.Boolean({description:"If true, interrupt the current turn before sending the message. Useful to redirect the session mid-response."})),userInitiated:g.Optional(g.Boolean({description:"Set to true when the message comes from the user (not auto-generated). Resets the auto-respond counter and bypasses the auto-respond limit."})),approve:g.Optional(g.Boolean({description:"Set to true to escalate session permissions to bypassPermissions. Works in two scenarios: (1) approve a pending plan in plan mode, or (2) escalate a default-mode session to skip remaining OpenClaw approval checkpoints. No-op if already in bypassPermissions mode. In plan mode without a pending plan, this flag is ignored."})),approval_rationale:g.Optional(g.String({description:"Optional structured rationale for a direct delegated plan approval. Use this instead of embedding the rationale in message text when approve=true for a pending plan."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Kg(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, message, interrupt?, userInitiated?, approve?, approval_rationale? }."}]};let r=await Ie(v,{session:n.session,message:n.message,interrupt:n.interrupt,userInitiated:n.userInitiated,approve:n.approve,approvalRationale:n.approval_rationale});return{isError:r.isError??!1,content:[{type:"text",text:r.text}]}}}}se();V();function Vg(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function xl(t){return{name:"agent_request_plan_approval",description:"Send a plan-approval decision prompt to the user for a session that is already waiting on plan approval. Reuses the plugin's Approve/Revise/Reject buttons so the user can decide directly from the message.",parameters:g.Object({session:g.String({description:"Session name or ID awaiting plan approval"}),summary:g.String({description:"Concise user-facing summary of scope, risk, and any concerns that should accompany the approval buttons"})}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Vg(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=v.requestPlanApprovalFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}se();V();function jg(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Tl(t){return{name:"agent_request_worktree_decision",description:"Send a worktree Merge/Open PR/Later/Discard decision prompt to the user for a delegated worktree session that is awaiting human choice.",parameters:g.Object({session:g.String({description:"Delegated session name or ID awaiting a worktree decision"}),summary:g.String({description:"Concise user-facing summary of scope, risk, and why human choice is needed"})}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!jg(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=v.requestWorktreeDecisionFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}se();V();ae();var bs=["off","manual","ask","delegate","auto-merge","auto-pr"],so=new Set(bs),Gg=["pr-required","pr-allowed","never-pr","manual"],Cl=new Set(Gg),Hg=["low","medium","high","xhigh","max"],Ml=new Set(Hg);function zg(t){return typeof t=="string"&&so.has(t)}var Qg=g.Union(bs.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 Jg(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||zg(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 Yg(t,e){let n=Ft(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 Zg(t,e){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=Yg(t,e);return!n?.provider||!n.target?{content:[{type:"text",text:"Error: Could not resolve a direct delivery route for the plan offer."}]}:(v.sendPlanOffer({offerId:e.offer_id,route:n,text:e.offer_text,planName:e.plan_name??e.offer_id,planPrompt:e.plan_prompt,planWorkdir:e.plan_workdir,planWorktreeStrategy:e.plan_worktree_strategy}),{content:[{type:"text",text:`Interactive plan offer queued for ${n.provider}|${n.target}${n.threadId?`#${n.threadId}`:""}.`}]})}function _l(t){return{name:"agent_send_plan_offer",description:"Post a user-facing message to the current or explicit chat route with human-gated Start Plan and Dismiss inline buttons. Use this when an external workflow wants the user to open a plan-only code-agent session from the message.",parameters:g.Object({offer_id:g.String({description:"Stable offer identifier, for example 'plugin-readiness-v2026.5.5'."}),offer_text:g.String({description:"Final user-facing text to deliver."}),plan_prompt:g.String({description:"Prompt to seed into the plan-only session when the user clicks Start Plan."}),plan_workdir:g.String({description:"Working directory for the planning session."}),plan_worktree_strategy:g.Optional(Qg),plan_name:g.Optional(g.String({description:"Optional explicit session name for the planning session."})),target_channel:g.Optional(g.String({description:"Optional explicit route like 'telegram|<chat-id>'."})),target_thread_id:g.Optional(g.Union([g.String(),g.Number()],{description:"Optional explicit topic/thread id."})),target_session_key:g.Optional(g.String({description:"Optional explicit session key for wake routing."}))}),async execute(e,n){return Jg(n)?Zg(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}se();V();function $l(t){return{name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics: session counts by status, average duration, and notable sessions.",parameters:g.Object({}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=v.getMetrics(),o=v.list("running").length;return{content:[{type:"text",text:Tr(r,o)}]}}}}se();V();Zt();import{execFileSync as Xg}from"child_process";var As=[{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."}],eh=new Map(As.map(t=>[t.policy,t]));function Dn(t){return t?As:As.filter(e=>e.policy==="never-pr"||e.policy==="manual")}function El(t){return eh.get(t)??{policy:t,label:t,title:t,description:"Custom repo integration policy."}}function tn(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 Is(t){let{policy:e,prAvailable:n}=t;return{merge:e!=="pr-required"&&e!=="manual",pr:e!=="never-pr"&&e!=="manual"&&n}}function Rs(t,e){try{return Xg("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 th(t){return Dl(t)?.startsWith("https://github.com/")?"github":"unsupported"}function On(t){let e=Rs(t,["rev-parse","--show-toplevel"]);if(!e)return;let n=Rs(e,["remote","get-url","origin"])??Rs(e,["remote","get-url","upstream"]),r=Dl(n),o=th(r);return{key:r?`${e}|${r}`:e,repoRoot:e,remoteUrl:r,provider:o}}function Ol(t){if(t?.remoteUrl)return t.remoteUrl==="https://github.com/goldmar/openclaw-code-agent"?"pr-required":void 0}function xs(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 Ts(t){return t.provider==="github"&&ye()}function Nl(t){let e=t.requestedStrategy,n=Is(t);return!e||e==="off"||e==="manual"?{allowedActions:n}:t.policy?t.policy==="manual"?{strategy:e==="delegate"?"delegate":"ask",reason:"Repo policy requires manual follow-through.",allowedActions:{merge:!1,pr:!1}}:t.policy==="pr-required"?e==="auto-merge"?t.prAvailable?{strategy:"auto-pr",reason:"Repo policy requires a PR; auto-merge was downgraded to auto-pr.",allowedActions:n}:{strategy:"ask",blocked:!0,reason:"Repo policy requires a PR, but no supported PR provider is available.",allowedActions:n}:e==="auto-pr"?t.prAvailable?{strategy:"auto-pr",allowedActions:n}:{strategy:"ask",blocked:!0,reason:"Repo policy requires a PR, but no supported PR provider is available.",allowedActions:n}:{strategy:e,allowedActions:n}:t.policy==="never-pr"?e==="auto-pr"?t.existingOpenPr&&t.prAvailable?{strategy:"auto-pr",reason:"Repo policy forbids new PR creation; updating the existing open PR is allowed.",allowedActions:n}:{strategy:"ask",reason:"Repo policy forbids PR creation; auto-pr was downgraded to an explicit worktree decision.",allowedActions:n}:{strategy:e,allowedActions:n}:e==="auto-pr"&&!t.prAvailable?{strategy:"ask",reason:"No supported PR provider is available; auto-pr was downgraded to an explicit worktree decision.",allowedActions:n}:{strategy:e,allowedActions:n}:{strategy:e==="auto-merge"||e==="auto-pr"?"ask":e,blocked:!0,reason:"Repo integration policy is unknown.",allowedActions:{merge:!1,pr:!1}}}function Cs(t,e,n=t.provider==="github"){let r=Dn(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(`
116
116
  `)}function nh(t){return t==="pr-required"||t==="pr-allowed"||t==="never-pr"||t==="manual"}function Nn(t){return t?[`Repo policy: ${t.policy}`,`Repo: ${t.repoRoot}`,`Provider: ${t.provider}`,...t.remoteUrl?[`Remote: ${t.remoteUrl}`]:[],`Updated: ${t.updatedAt}`].join(`
117
117
  `):"No stored repo policy found."}function Wl(t){return{name:"agent_repo_policy",description:"Inspect or set the repository integration policy that governs OCA worktree merge/PR follow-through.",parameters:g.Object({workdir:g.Optional(g.String({description:"Repository workdir. Defaults to the current workspace directory."})),policy:g.Optional(g.Union([g.Literal("pr-required"),g.Literal("pr-allowed"),g.Literal("never-pr"),g.Literal("manual")],{description:"Policy to set for this repo."})),reset:g.Optional(g.Boolean({description:"Remove the stored policy for this repo."})),list:g.Optional(g.Boolean({description:"List all stored repo policies."})),cleanup:g.Optional(g.Boolean({description:"Remove stored repo policies whose repoRoot no longer exists on disk."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=n&&typeof n=="object"?n:{};if(r.cleanup===!0){let a=v.cleanupRepoPolicies();return{content:[{type:"text",text:a.length===0?"No stale repo policies found.":[`Removed ${a.length} stale repo ${a.length===1?"policy":"policies"}.`,...a.map(l=>`${l.policy} | ${l.provider} | ${l.repoRoot}`)].join(`
@@ -121,12 +121,12 @@ ${l}`}}catch{}return d}function no(t,e="all",n,r={}){let o=t.listPersistedSessio
121
121
  `)}]}:d.kind==="ambiguous"?{content:[{type:"text",text:[Nn(a),"",`Repo policy saved, but ${d.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
122
122
  `)}]}:{content:[{type:"text",text:Nn(a)}]}}let i=v.resolveRepoPolicy(o);if(!i.identity)return{content:[{type:"text",text:`No git repository found for ${o}.`}]};let s=i.record;return s?{content:[{type:"text",text:Nn(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(`
123
123
  `)}]}}}}se();ae();V();Ae();Wn();Bn();import{existsSync as fo}from"fs";function sh(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function ah(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 dh(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 go(t){return{name:"agent_merge",description:"Merge a worktree branch back to the base branch. Resolves session (active or persisted), gets worktree path, and performs the merge. On conflict, spawns a conflict-resolver session using the configured default harness.",parameters:g.Object({session:g.String({description:"Session name or ID to merge"}),base_branch:g.Optional(g.String({description:"Base branch to merge into (default: main)"})),strategy:g.Optional(g.Union([g.Literal("merge"),g.Literal("squash")],{description:"Merge strategy: 'merge' (default, fast-forward if possible; merge commit if branches have diverged) or 'squash' (squashes all commits into one)"})),push:g.Optional(g.Boolean({description:"Push the base branch after successful merge (default: false)"})),delete_branch:g.Optional(g.Boolean({description:"Delete the worktree branch after successful merge (default: true)"}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!sh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=rn(v,n.session),o=r.activeSession,i=r.persistedSession;if(!o&&!i)return{content:[{type:"text",text:`Error: Session "${n.session}" not found.`}]};let{worktreePath:s,originalWorkdir:a,branchName:d}=r;if(!s||!a)return{content:[{type:"text",text:`Error: Session "${n.session}" does not have a worktree.`}]};if(!d)return{content:[{type:"text",text:`Error: Cannot determine branch name for worktree at ${s}. The worktree may have been removed and no persisted branch name is available.`}]};fo(s)||`${s}${a}`;let l=a;if(!fo(a))return{content:[{type:"text",text:`Error: originalWorkdir "${a}" does not exist.`}]};let u=n.base_branch??Fe(l),f=u,p=n.strategy??"merge",k=n.push===!0,m=n.delete_branch!==!1,c=v.resolveRepoPolicy(l);if(c?.policy==="pr-required")return{content:[{type:"text",text:`❌ Merge blocked: repo policy requires a pull request for ${c.identity?.repoRoot??l}. Use agent_pr if PR automation is available.`}]};if(i?.worktreeLifecycle?.state==="merged"||i?.worktreeMerged)return{content:[{type:"text",text:`ℹ️ Session "${n.session}" is already merged.`}]};if((fo(s)?Mn(l,d,f):void 0)===0&&Rt(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${d} has no commits ahead of ${f}.`,`Worktree: ${s}`,"Resume or inspect the session, then commit real task changes or clean temporary files before retrying agent_merge."].join(`
124
- `)}]};let S={content:[{type:"text",text:"❌ Merge did not run (internal error)"}]};return await v.enqueueMerge(l,async()=>{let b=v.getPersistedSession(n.session);if(b?.worktreeLifecycle?.state==="merged"||b?.worktreeMerged){S={content:[{type:"text",text:`ℹ️ Session "${n.session}" was already merged while waiting in queue.`}]};return}let x=Qe(l,d,u),T=Yr(l,d,f,p,s),A=en(T);if(T.success){let y=ah({mergeResult:T,repoDir:l,baseBranch:f});if(k&&!Jr(l,f)){let N=`⚠️ Merged ${d} → ${f} locally, but failed to push ${f}`;v.notifyWorktreeOutcome(r.notificationTarget,N,{detailLines:[`Branch ${d} was merged into ${f} in the local repository.`,`Pushing ${f} failed; remote state may not include the merge.`,"Cleanup was skipped so the branch/worktree remains available for follow-up.",...y,...A]}),S={content:[{type:"text",text:qe(N,T)}]};return}let w=!1,L=!1,K=!fo(s);L=K?!0:pe(l,s),zr(l),m&&(w=be(l,d));let W=dh({deleteBranchRequested:m,branchDeleted:w,worktreeCleanedUp:L,worktreeAlreadyAbsent:K});if(b){let N=new Date().toISOString();for(let F of Ln({...r,persistedSession:b}))v.updatePersistedSession(F,{...nn({worktreeBaseBranch:u,worktreePrTargetRepo:b.worktreePrTargetRepo,worktreePushRemote:b.worktreePushRemote},{mergedAt:N,updatedAt:N,resolvedAt:N,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let I=At({kind:"merge",branch:d,base:u,filesChanged:x?.filesChanged,insertions:x?.insertions,deletions:x?.deletions});v.notifyWorktreeOutcome(r.notificationTarget,I,{detailLines:[T.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",k?`Pushed ${f}.`:`Did not push ${f}; push was not requested.`,W.detailLine,...y,...A]});let q=`✅ ${T.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${d} → ${f}.${k?" Pushed.":""}${W.summaryFragment}`;T.stashPopConflict?q+=`
125
- ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${T.stashRef??"stash@{0}"}\` in ${l} to review stashed changes.`:T.stashed&&(q+=`
126
- (Pre-existing changes on ${f} were auto-stashed and restored.)`),q=qe(q,T),S={content:[{type:"text",text:q}]}}else if(T.rebaseConflict)S={content:[{type:"text",text:qe(`⚠️ Rebase conflicts — manual resolution required:
124
+ `)}]};let S={content:[{type:"text",text:"❌ Merge did not run (internal error)"}]};return await v.enqueueMerge(l,async()=>{let P=v.getPersistedSession(n.session);if(P?.worktreeLifecycle?.state==="merged"||P?.worktreeMerged){S={content:[{type:"text",text:`ℹ️ Session "${n.session}" was already merged while waiting in queue.`}]};return}let x=Qe(l,d,u),C=Yr(l,d,f,p,s),A=en(C);if(C.success){let y=ah({mergeResult:C,repoDir:l,baseBranch:f});if(k&&!Jr(l,f)){let N=`⚠️ Merged ${d} → ${f} locally, but failed to push ${f}`;v.notifyWorktreeOutcome(r.notificationTarget,N,{detailLines:[`Branch ${d} was merged into ${f} in the local repository.`,`Pushing ${f} failed; remote state may not include the merge.`,"Cleanup was skipped so the branch/worktree remains available for follow-up.",...y,...A]}),S={content:[{type:"text",text:qe(N,C)}]};return}let w=!1,L=!1,K=!fo(s);L=K?!0:pe(l,s),zr(l),m&&(w=be(l,d));let W=dh({deleteBranchRequested:m,branchDeleted:w,worktreeCleanedUp:L,worktreeAlreadyAbsent:K});if(P){let N=new Date().toISOString();for(let F of Ln({...r,persistedSession:P}))v.updatePersistedSession(F,{...nn({worktreeBaseBranch:u,worktreePrTargetRepo:P.worktreePrTargetRepo,worktreePushRemote:P.worktreePushRemote},{mergedAt:N,updatedAt:N,resolvedAt:N,resolutionSource:"agent_merge"}),worktreeDisposition:"merged"})}let I=At({kind:"merge",branch:d,base:u,filesChanged:x?.filesChanged,insertions:x?.insertions,deletions:x?.deletions});v.notifyWorktreeOutcome(r.notificationTarget,I,{detailLines:[C.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",k?`Pushed ${f}.`:`Did not push ${f}; push was not requested.`,W.detailLine,...y,...A]});let q=`✅ ${C.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${d} → ${f}.${k?" Pushed.":""}${W.summaryFragment}`;C.stashPopConflict?q+=`
125
+ ⚠️ Pre-merge stash pop conflicted — run \`git stash show ${C.stashRef??"stash@{0}"}\` in ${l} to review stashed changes.`:C.stashed&&(q+=`
126
+ (Pre-existing changes on ${f} were auto-stashed and restored.)`),q=qe(q,C),S={content:[{type:"text",text:q}]}}else if(C.rebaseConflict)S={content:[{type:"text",text:qe(`⚠️ Rebase conflicts — manual resolution required:
127
127
 
128
- ${T.error}`,T)}]};else if(T.conflictFiles&&T.conflictFiles.length>0){let y=["Resolve merge conflicts in the following files and commit the resolution:","",...T.conflictFiles.map(w=>`- ${w}`),"",`After resolving, commit with message: "Resolve merge conflicts from ${d}"`].join(`
129
- `);try{let w=v.spawn({prompt:y,workdir:l,name:`${n.session}-conflict-resolver`,harness:fe(),permissionMode:"bypassPermissions",multiTurn:!0,route:o?.route??i?.route,originChannel:o?.originChannel??i?.originChannel,originThreadId:o?.originThreadId??i?.originThreadId,originAgentId:o?.originAgentId??i?.originAgentId,originSessionKey:o?.originSessionKey??i?.originSessionKey});S={content:[{type:"text",text:qe(`⚠️ Merge conflicts in ${T.conflictFiles.length} file(s) — spawned conflict resolver session: ${w.name}`,T)}]}}catch(w){S={content:[{type:"text",text:qe(`❌ Merge conflicts detected, but failed to spawn resolver: ${w instanceof Error?w.message:String(w)}`,T)}]}}}else{let y=T.dirtyError?`❌ Merge blocked: ${T.error}`:`❌ Merge failed: ${T.error??"unknown error"}`;S={content:[{type:"text",text:qe(y,T)}]}}}),S}}}Po();se();V();ne();Ae();Bn();function wh(t){return!!t&&typeof t=="object"}function eu(t){return{name:"agent_worktree_cleanup",description:"Manage worktree cleanup with lifecycle-aware safety rules. Use preview_safe to list what Clean all safe would remove, clean_safe to execute it, or preview_all to see both safe and retained sandboxes with kept reasons.",parameters:g.Object({workdir:g.Optional(g.String({description:"Restrict cleanup to sessions rooted in this repository"})),base_branch:g.Optional(g.String({description:"Override base branch for lifecycle resolution"})),mode:g.Optional(g.Union([g.Literal("preview_safe"),g.Literal("clean_safe"),g.Literal("preview_all")],{description:"Cleanup mode. preview_safe shows what Clean all safe would remove, clean_safe performs that cleanup, preview_all shows both safe and retained worktrees. Defaults to preview_safe when dry_run=true, otherwise clean_safe."})),skip_session_check:g.Optional(g.Boolean({description:"Deprecated. Safe cleanup never removes live sessions."})),force:g.Optional(g.Boolean({description:"Deprecated alias for skip_session_check."})),dry_run:g.Optional(g.Boolean({description:"Show what would be cleaned without deleting anything."})),session:g.Optional(g.String({description:"Session name or ID to clean or dismiss."})),dismiss_session:g.Optional(g.Boolean({description:"When true and session is provided, permanently dismiss the worktree."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!wh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { workdir?, base_branch?, mode?, dry_run?, session?, dismiss_session? }."}]};let r=n.session,o=n.mode??(n.dry_run===!0?"preview_safe":"clean_safe"),i=o!=="clean_safe",s=o==="preview_all"||o==="clean_safe";if(r&&n.dismiss_session===!0)return{content:[{type:"text",text:await v.dismissWorktree(r)}]};let a=co(v);if(r&&(a=a.filter(k=>po(k,r)),a.length===0)){let k=rn(v,r);if(!k.persistedSession&&!k.activeSession)return{content:[{type:"text",text:`Error: Session "${r}" not found.`}]}}if(n.workdir&&(a=a.filter(k=>k.workdir===n.workdir)),a.length===0)return{content:[{type:"text",text:"No managed worktrees matched the requested scope."}]};let d=[],l=[],u=[],f=[];for(let k of a){let{persistedSession:m,activeSession:c,resolvedLifecycle:h}=uo(v,k,{baseBranch:n.base_branch});if(!h.cleanupSafe){if(s){let S=h.reasons.length>0?h.reasons.map(mo).join(", "):xt(h.derivedState);l.push(`${k.name} [kept: ${S}]`)}continue}if(d.push(`${k.name} (${xt(h.derivedState)})`),!i)try{let S=k.workdir;if(!((m??c)&&ue(m??c))&&k.worktreePath&&pe(S,k.worktreePath,{destructive:!1}),k.worktreeBranch&&be(S,k.worktreeBranch),m){let x=h.derivedState==="merged"||h.derivedState==="released"?h.derivedState:h.lifecycle.state,T=new Date().toISOString(),A=x==="merged"?m.worktreeMergedAt:x==="dismissed"?m.worktreeDismissedAt:void 0;v.updatePersistedSession(k.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeMerged:x==="merged"?!0:m.worktreeMerged,worktreeMergedAt:x==="merged"?m.worktreeMergedAt??T:m.worktreeMergedAt,worktreeLifecycle:{...m.worktreeLifecycle??h.lifecycle,state:x,updatedAt:T,resolvedAt:m.worktreeLifecycle?.resolvedAt??A??T,resolutionSource:m.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??h.lifecycle.baseBranch??m.worktreeBaseBranch,targetRepo:m.worktreePrTargetRepo,pushRemote:m.worktreePushRemote,notes:h.reasons}})}u.push(`${k.name} (${xt(h.derivedState)})`)}catch(S){f.push(`${k.name}: ${S instanceof Error?S.message:String(S)}`)}}let p=[o==="clean_safe"?"Clean all safe:":o==="preview_all"?"Worktree lifecycle review:":"Clean all safe preview:"];return p.push(` SAFE ${i?"NOW":"FOUND"} (${d.length}): ${d.join(", ")||"(none)"}`),s&&p.push(` KEPT (${l.length}): ${l.join(", ")||"(none)"}`),i||(p.push(` CLEANED (${u.length}): ${u.join(", ")||"(none)"}`),p.push(` FAILURES (${f.length}): ${f.join(", ")||"(none)"}`)),{content:[{type:"text",text:p.join(`
128
+ ${C.error}`,C)}]};else if(C.conflictFiles&&C.conflictFiles.length>0){let y=["Resolve merge conflicts in the following files and commit the resolution:","",...C.conflictFiles.map(w=>`- ${w}`),"",`After resolving, commit with message: "Resolve merge conflicts from ${d}"`].join(`
129
+ `);try{let w=v.spawn({prompt:y,workdir:l,name:`${n.session}-conflict-resolver`,harness:fe(),permissionMode:"bypassPermissions",multiTurn:!0,route:o?.route??i?.route,originChannel:o?.originChannel??i?.originChannel,originThreadId:o?.originThreadId??i?.originThreadId,originAgentId:o?.originAgentId??i?.originAgentId,originSessionKey:o?.originSessionKey??i?.originSessionKey});S={content:[{type:"text",text:qe(`⚠️ Merge conflicts in ${C.conflictFiles.length} file(s) — spawned conflict resolver session: ${w.name}`,C)}]}}catch(w){S={content:[{type:"text",text:qe(`❌ Merge conflicts detected, but failed to spawn resolver: ${w instanceof Error?w.message:String(w)}`,C)}]}}}else{let y=C.dirtyError?`❌ Merge blocked: ${C.error}`:`❌ Merge failed: ${C.error??"unknown error"}`;S={content:[{type:"text",text:qe(y,C)}]}}}),S}}}Po();se();V();ne();Ae();Bn();function wh(t){return!!t&&typeof t=="object"}function eu(t){return{name:"agent_worktree_cleanup",description:"Manage worktree cleanup with lifecycle-aware safety rules. Use preview_safe to list what Clean all safe would remove, clean_safe to execute it, or preview_all to see both safe and retained sandboxes with kept reasons.",parameters:g.Object({workdir:g.Optional(g.String({description:"Restrict cleanup to sessions rooted in this repository"})),base_branch:g.Optional(g.String({description:"Override base branch for lifecycle resolution"})),mode:g.Optional(g.Union([g.Literal("preview_safe"),g.Literal("clean_safe"),g.Literal("preview_all")],{description:"Cleanup mode. preview_safe shows what Clean all safe would remove, clean_safe performs that cleanup, preview_all shows both safe and retained worktrees. Defaults to preview_safe when dry_run=true, otherwise clean_safe."})),skip_session_check:g.Optional(g.Boolean({description:"Deprecated. Safe cleanup never removes live sessions."})),force:g.Optional(g.Boolean({description:"Deprecated alias for skip_session_check."})),dry_run:g.Optional(g.Boolean({description:"Show what would be cleaned without deleting anything."})),session:g.Optional(g.String({description:"Session name or ID to clean or dismiss."})),dismiss_session:g.Optional(g.Boolean({description:"When true and session is provided, permanently dismiss the worktree."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!wh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { workdir?, base_branch?, mode?, dry_run?, session?, dismiss_session? }."}]};let r=n.session,o=n.mode??(n.dry_run===!0?"preview_safe":"clean_safe"),i=o!=="clean_safe",s=o==="preview_all"||o==="clean_safe";if(r&&n.dismiss_session===!0)return{content:[{type:"text",text:await v.dismissWorktree(r)}]};let a=co(v);if(r&&(a=a.filter(k=>po(k,r)),a.length===0)){let k=rn(v,r);if(!k.persistedSession&&!k.activeSession)return{content:[{type:"text",text:`Error: Session "${r}" not found.`}]}}if(n.workdir&&(a=a.filter(k=>k.workdir===n.workdir)),a.length===0)return{content:[{type:"text",text:"No managed worktrees matched the requested scope."}]};let d=[],l=[],u=[],f=[];for(let k of a){let{persistedSession:m,activeSession:c,resolvedLifecycle:h}=uo(v,k,{baseBranch:n.base_branch});if(!h.cleanupSafe){if(s){let S=h.reasons.length>0?h.reasons.map(mo).join(", "):xt(h.derivedState);l.push(`${k.name} [kept: ${S}]`)}continue}if(d.push(`${k.name} (${xt(h.derivedState)})`),!i)try{let S=k.workdir;if(!((m??c)&&ue(m??c))&&k.worktreePath&&pe(S,k.worktreePath,{destructive:!1}),k.worktreeBranch&&be(S,k.worktreeBranch),m){let x=h.derivedState==="merged"||h.derivedState==="released"?h.derivedState:h.lifecycle.state,C=new Date().toISOString(),A=x==="merged"?m.worktreeMergedAt:x==="dismissed"?m.worktreeDismissedAt:void 0;v.updatePersistedSession(k.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeMerged:x==="merged"?!0:m.worktreeMerged,worktreeMergedAt:x==="merged"?m.worktreeMergedAt??C:m.worktreeMergedAt,worktreeLifecycle:{...m.worktreeLifecycle??h.lifecycle,state:x,updatedAt:C,resolvedAt:m.worktreeLifecycle?.resolvedAt??A??C,resolutionSource:m.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??h.lifecycle.baseBranch??m.worktreeBaseBranch,targetRepo:m.worktreePrTargetRepo,pushRemote:m.worktreePushRemote,notes:h.reasons}})}u.push(`${k.name} (${xt(h.derivedState)})`)}catch(S){f.push(`${k.name}: ${S instanceof Error?S.message:String(S)}`)}}let p=[o==="clean_safe"?"Clean all safe:":o==="preview_all"?"Worktree lifecycle review:":"Clean all safe preview:"];return p.push(` SAFE ${i?"NOW":"FOUND"} (${d.length}): ${d.join(", ")||"(none)"}`),s&&p.push(` KEPT (${l.length}): ${l.join(", ")||"(none)"}`),i||(p.push(` CLEANED (${u.length}): ${u.join(", ")||"(none)"}`),p.push(` FAILURES (${f.length}): ${f.join(", ")||"(none)"}`)),{content:[{type:"text",text:p.join(`
130
130
  `)}]}}}}se();V();Bn();function Ph(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 tu(t){return{name:"agent_worktree_status",description:"Show lifecycle-first worktree status for coding agent sessions. Displays product-facing lifecycle state, released handling, cleanup safety, and retained reasons.",parameters:g.Object({session:g.Optional(g.String({description:"Session name or ID to show status for (optional, shows all if omitted)"}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Ph(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n&&typeof n=="object"?n.session:void 0,o=co(v);if(r&&(o=o.filter(s=>po(s,r)),o.length===0))return{content:[{type:"text",text:`Error: Session "${r}" not found or has no worktree.`}]};if(o.length===0)return{content:[{type:"text",text:"No sessions with worktrees found."}]};let i=[];for(let s of o){let{persistedSession:a,resolvedLifecycle:d}=uo(v,s),l=d.cleanupSafe?"safe now":d.preserve?"preserve":"blocked";i.push(`Session: ${s.name} [${s.id}]`),i.push(` Branch: ${s.worktreeBranch??"(unknown)"} → ${d.lifecycle.baseBranch??a?.worktreeBaseBranch??"main"}`),i.push(` Repo: ${s.workdir}`),i.push(` Lifecycle:${xt(d.lifecycle.state)}`),d.derivedState!==d.lifecycle.state&&i.push(` Derived: ${xt(d.derivedState)}`),i.push(` Cleanup: ${l}`),d.evidence.prUrl&&i.push(` PR: ${d.evidence.prUrl} (${d.evidence.prState??"unknown"})`),(d.evidence.branchAheadCount!=null||d.evidence.baseAheadCount!=null)&&i.push(` Ahead: ${d.evidence.branchAheadCount??0} ahead / ${d.evidence.baseAheadCount??0} behind`),i.push(` Reasons: ${d.reasons.length>0?d.reasons.map(mo).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
131
131
  `).trim()}]}}}}se();V();ae();Sr();import{existsSync as bh}from"fs";function Rh(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function bo(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(!bh(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=Rh(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??fe(),a=t.model??Lt(s),d=He(s,a),l=or(s);if(!d&&(s!=="opencode"||l&&l.length>0))return{kind:"error",text:`Error: No default model configured for harness "${s}". Set plugins.entries["openclaw-code-agent"].config.harnesses.${s}.defaultModel or pass model explicitly.`};if(d&&!zt(s,d))return{kind:"error",text:`Error: Model "${a}" is not supported for harness "${s}". Use a bare Codex model id such as "gpt-5.6-sol".`};if(d&&!yr(s,d,l))return{kind:"error",text:`Error: Model "${a}" is not allowed. Permitted models: ${l?.join(", ")}`};let u=kr(s,d,l),f=e.sessionKey||void 0,p=ir(e),k=Sn(e,p||kt(r)),m=Ft(e,k,f);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:u,reasoningEffort:it(s),fastMode:Bt(s),systemPrompt:t.systemPrompt,allowedTools:t.allowedTools,maxIterations:t.maxIterations,permissionMode:t.permissionMode??"bypassPermissions",harness:s,loopMode:i,completionPromise:t.completionPromise,originChannel:k,originThreadId:m?.threadId,originAgentId:e.agentId||void 0,originSessionKey:f,route:m,verifierCommands:o}}function Ro(t,e){return["Goal task launched.",` Name: ${t.name}`,` ID: ${t.id}`,` Dir: ${t.workdir}`,` Session: ${t.sessionName} [${t.sessionId}]`,` Harness: ${e.harness}`,` Model: ${e.model??"default"}`,...e.fastMode?[" Fast mode: enabled"]:[],` Loop mode: ${t.loopMode}`,` Max controller iterations: ${t.maxIterations}`,` Goal: "${e.goal.length>100?`${e.goal.slice(0,100)}...`:e.goal}"`,...t.loopMode==="ralph"?[` Completion promise: ${t.completionPromise}`]:[" Verifiers:",...e.verifierCommands.map(r=>` - ${r.command}`)],"","Controller iteration progress advances only when the goal controller starts another agent turn; internal agent review passes are reported in the completion summary.","","Use /agent_goal_status to follow progress or /agent_goal_stop to terminate the task in chat."].join(`
132
132
  `)}function Ah(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function nu(t){return{name:"agent_goal_launch",description:"Launch an explicit goal loop. Use this only when the user specifically asks for a goal task, Ralph-style autonomous loop, iterative loop, autonomous repair loop, or keep-going-until-checks-pass workflow. This is not the default session path.",parameters:g.Object({goal:g.String({description:"End goal for the autonomous task"}),verifier_commands:g.Optional(g.Array(g.String({description:"Shell command that must pass for the goal to be considered complete"}),{minItems:1,description:"Verifier commands run after each coding turn"})),name:g.Optional(g.String({description:"Short task name (kebab-case preferred)"})),workdir:g.Optional(g.String({description:"Working directory (defaults to cwd / configured workspace)"})),model:g.Optional(g.String({description:"Model name to use"})),system_prompt:g.Optional(g.String({description:"Additional system prompt"})),allowed_tools:g.Optional(g.Array(g.String(),{description:"Allowed tools for the underlying agent session"})),max_iterations:g.Optional(g.Number({description:"Maximum verifier-driven repair iterations",minimum:1})),goal_mode:g.Optional(g.Union([g.Literal("ralph"),g.Literal("verifier")],{description:"Loop strategy. 'ralph' repeats until a completion promise appears. 'verifier' repeats until verifier commands pass. Defaults to 'ralph' when no verifiers are provided, otherwise 'verifier'."})),completion_promise:g.Optional(g.String({description:"Exact completion promise for Ralph-mode loops. Defaults to 'DONE'."})),permission_mode:g.Optional(g.Union([g.Literal("default"),g.Literal("plan"),g.Literal("bypassPermissions")],{description:"Permission mode for the underlying agent session. Defaults to bypassPermissions for autonomous goal loops."})),harness:g.Optional(g.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode')."}))}),async execute(e,n){if(!Z)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!Ah(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=bo({goal:n.goal,verifierCommands:n.verifier_commands,name:n.name,workdir:n.workdir,model:n.model,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,maxIterations:n.max_iterations,permissionMode:n.permission_mode,harness:n.harness,goalMode:n.goal_mode,completionPromise:n.completion_promise},t);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};try{let o=await Z.launchTask({goal:r.goal,name:r.name,workdir:r.workdir,model:r.model,reasoningEffort:r.reasoningEffort,fastMode:r.fastMode,systemPrompt:r.systemPrompt,allowedTools:r.allowedTools,maxIterations:r.maxIterations,permissionMode:r.permissionMode,loopMode:r.loopMode,completionPromise:r.completionPromise,originChannel:r.originChannel,originThreadId:r.originThreadId,originAgentId:r.originAgentId,originSessionKey:r.originSessionKey,route:r.route,harness:r.harness,verifierCommands:r.verifierCommands});return{content:[{type:"text",text:Ro(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}se();function qs(t,e){return t.split(`
@@ -138,7 +138,7 @@ ${T.error}`,T)}]};else if(T.conflictFiles&&T.conflictFiles.length>0){let y=["Res
138
138
  `)}function xo(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 To(t,e){switch(t.action){case"updated":return`Task "${t.task.name}" (${t.task.id}) goal updated.`;case"not_found":return`Error: Goal task "${e}" not found.`;case"invalid_goal":return"Error: replacement goal must not be empty.";case"not_editable":return t.task.status!=="waiting_for_user"?`Task is already ${t.task.status}.`:`Error: Goal task "${t.task.name}" is ${t.task.status} and cannot be edited.`}}V();function ou(t){return{name:"agent_goal_status",description:"Show status for explicit goal tasks managed by the goal controller. Use this to inspect one goal task or list all goal tasks.",parameters:g.Object({task:g.Optional(g.String({description:"Task name or ID. Omit to list all tasks."}))}),async execute(e,n){if(!Z)return{content:[{type:"text",text:Me}]};let r=n&&typeof n=="object"&&typeof n.task=="string"?n.task:void 0;return{content:[{type:"text",text:Io(Z,o=>v?.resolve(o),r)}]}}}}se();V();function Ch(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function iu(t){return{name:"agent_goal_stop",description:"Stop an explicit goal task and kill its underlying agent session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"})}),async execute(e,n){if(!Z)return{content:[{type:"text",text:Me}]};if(!Ch(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=Z.stopTask(n.task);return{content:[{type:"text",text:xo(r,n.task)}]}}}}se();V();function Mh(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function su(t){return{name:"agent_goal_edit",description:"Edit the goal text for an active goal task without stopping or relaunching its session.",parameters:g.Object({task:g.String({description:"Goal task name or ID"}),goal:g.String({description:"Replacement goal text"})}),async execute(e,n){if(!Z)return{content:[{type:"text",text:Me}]};if(!Mh(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=Z.editTask(n.task,n.goal);return{content:[{type:"text",text:To(r,n.task)}]}}}}V();Po();var Vs=new Set,au="⚠️ Could not submit that answer. The question prompt is still active; try again or reply with the answer.",Gn=new Map;function _h(t){return`${t.sessionId}:${t.pendingInputRequestId??t.id}`}function $h(t){return!!(t&&t.status!=="running"&&vt(t).kind==="resume")}function Eh(t){return t.label?.trim()?["[SYSTEM: The gateway restarted while a user question was pending. Treat the user's selection below as the answer to that interrupted question and continue without asking it again.]","",t.pendingInputQuestionId?`Question ID: ${t.pendingInputQuestionId}`:"Question: the interrupted pending question",`Selected answer: ${t.label.trim()}`].join(`
139
139
  `):void 0}async function cu(t){try{await t}catch(e){let n=e instanceof Error?e.message:String(e);`${n}`}}async function du(t,e,n){if(!t)return n();for(;;){let o=Gn.get(t)?.operation;if(!o)break;await cu(o)}let r=Promise.resolve().then(n);Gn.set(t,{operation:r,tokenId:e});try{return await r}finally{Gn.get(t)?.operation===r&&Gn.delete(t)}}function Dh(t){let e=t.trim().replace(new RegExp(`^${re}:`),"");return e||null}function Oh(t){return t.trim().startsWith(`${re}:`)}async function Co(t,e=!1){if(t.channel==="telegram")try{return(await z(t,{alreadyAcknowledged:e,forceTelegramMarkupEdit:!0})).textDelivered}catch(r){let o=r instanceof Error?r.message:String(r);return`${o}`,!1}let n=t.respond;if(typeof n.clearComponents=="function")try{return await n.clearComponents(),!1}catch(r){if(Mt(r))return!1;let o=r instanceof Error?r.message:String(r);`${o}`}if(typeof n.clearButtons=="function")try{await n.clearButtons()}catch(r){let o=r instanceof Error?r.message:String(r);`${o}`}else!e&&typeof n.acknowledge=="function"&&await n.acknowledge();return!1}async function Ze(t,e=!1){await z(t,{alreadyAcknowledged:e,forceTelegramMarkupEdit:t.channel==="telegram"})}function _o(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 lu(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return Hs(_o(t))}function Hs(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function $o(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function Nh(t){if($o(t.kind))return`${t.sessionId}:v${t.planDecisionVersion??"unknown"}`}function Wh(t){return t?t.approvalState==="approved"||!t.pendingPlanApproval:!1}function Lh(...t){let e;for(let n of t)n!=null&&(e=e==null?n:Math.max(e,n));return e}function Bh(t){if(t.actionablePlanDecisionVersion!=null)return t.actionablePlanDecisionVersion;let e=Lh(t.approvalPromptRequiredVersion,t.approvalPromptVersion);return e??t.canonicalPlanPromptVersion??t.planDecisionVersion}function js(t,e){if(!$o(t.kind))return;if(!e)return"This plan decision is stale because the session is no longer available.";let n=Bh(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 pu(t,...e){return e.find(n=>typeof n=="string"&&t(n))}function Mo(...t){return pu(e=>e.trim().length>0,...t)}function uu(...t){return pu(Oh,...t)}function Fh(t){let e="callback"in t?uu(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0;if(e)return e;let n="interaction"in t?t.interaction:void 0,r=uu(n?.data,n?.callback_data,n?.callbackData);if(r)return r;let o="callback"in t?Mo(t.callback?.payload):void 0;if(o)return o;let i=Mo(n?.payload);return i||(("callback"in t?Mo(t.callback?.data,t.callback?.callback_data,t.callback?.callbackData):void 0)??Mo(n?.data,n?.callback_data,n?.callbackData)??"")}function Hn(t,e=new Set){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean"||typeof t=="bigint")return String(t);if(t instanceof Error)return[t.name,t.message,Hn(t.cause,e)].filter(Boolean).join(" ");if(typeof t!="object")return String(t);if(e.has(t))return"";e.add(t);let n=t;return[n.message,n.description,n.error,n.error_description,Hn(n.cause,e),Hn(n.response,e),Hn(n.payload,e)].filter(Boolean).join(" ")}function Mt(t){return/message is not modified/i.test(Hn(t))}function qh(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function Ct(t){if(typeof t.clearButtons=="function")try{await t.clearButtons()}catch(e){if(Mt(e))return;throw e}}async function z(t,e={}){let n=t.respond,{alreadyAcknowledged:r=!1,forceTelegramMarkupEdit:o=!1,text:i}=e;if(t.channel==="telegram"){if(typeof i=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:i,buttons:[]}),await Ct(n),{textDelivered:!0}}catch(a){if(Mt(a))return await Ct(n),{textDelivered:!0};let d=a instanceof Error?a.message:String(a);`${d}`}if(o&&typeof n.editButtons=="function")try{return await n.editButtons({buttons:[]}),await Ct(n),{textDelivered:!1}}catch(a){if(Mt(a))return await Ct(n),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}let s="callback"in t&&typeof t.callback?.messageText=="string"?t.callback.messageText:void 0;if(o&&typeof s=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:s,buttons:[]}),await Ct(n),{textDelivered:!1}}catch(a){if(Mt(a))return await Ct(n),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}return await Ct(n),{textDelivered:!1}}if(typeof n.clearComponents=="function")try{return await n.clearComponents(typeof i=="string"?{text:i}:void 0),{textDelivered:typeof i=="string"}}catch(s){if(Mt(s))return{textDelivered:typeof i=="string"};if(qh(s)){if(typeof i!="string"&&r)return{textDelivered:!1};if(typeof i!="string"&&typeof n.acknowledge=="function")return await n.acknowledge(),{textDelivered:!1};typeof i!="string"&&n.acknowledge}else{if(typeof i!="string")throw s;{let a=s instanceof Error?s.message:String(s);`${a}`}}}if(typeof i=="string"&&typeof n.editMessage=="function"){try{await n.editMessage({text:i})}catch(s){if(Mt(s))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0};let a=s instanceof Error?s.message:String(s);return`${a}`,typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0}}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}async function Uh(t){let e=t.respond;if(typeof e.acknowledge!="function")return!1;try{return await e.acknowledge(),!0}catch(n){let r=n instanceof Error?n.message:String(n);return`${r}`,!1}}async function $(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}var Gs=["plan-approve","plan-request-changes","plan-reject"];function Kh(t){switch(t){case"plan-approve":return"Approve";case"plan-request-changes":return"Revise";case"plan-reject":return"Reject";default:return"Continue"}}function Vh(t){switch(t){case"plan-approve":return"primary";case"plan-reject":return"danger";default:return"secondary"}}function jh(t,e){let n=t,o=(typeof n?.listActiveActionTokens=="function"?Gs.flatMap(a=>n.listActiveActionTokens?.(a)??[]):[e]).filter(a=>$o(a.kind)&&a.sessionId===e.sessionId&&(e.planDecisionVersion==null||a.planDecisionVersion==null||a.planDecisionVersion===e.planDecisionVersion)).sort((a,d)=>Gs.indexOf(a.kind)-Gs.indexOf(d.kind)),i=new Set,s=o.filter(a=>i.has(a.kind)?!1:(i.add(a.kind),!0)).map(a=>({label:typeof a.label=="string"&&a.label.trim()?a.label:Kh(a.kind),callbackData:`${re}:${a.id}`,style:Vh(a.kind)}));return s.length>0?[s]:void 0}async function Gh(t,e,n,r){if(t.channel!=="telegram"){await $(t,e);return}let o=jh(n,r);await t.respond.reply({text:o?`${e}
140
140
 
141
- Approval is still pending. Try again below.`:e,...o?{buttons:o}:{}})}function mu(t="telegram",e={}){let n=e.makeAgentMergeTool??go,r=e.makeAgentPrTool??jn;return B("callback_handler_registered",{channel:t,namespace:re}),{channel:t,namespace:re,handler:async o=>{let i=await Uh(o);if(!o.auth.isAuthorizedSender)return await $(o,"⛔ Unauthorized."),{handled:!0};let s=Fh(o),a=Dh(s);if(B("callback_received",{channel:o.channel,namespace:re,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:le(a),isAuthorizedSender:o.auth.isAuthorizedSender}),!a)return await $(o,"⚠️ Unrecognized callback payload."),{handled:!0};if(!v)return await $(o,"⚠️ Code agent service not running."),{handled:!0};let d=v.getActionToken(a);if(B("callback_token_lookup_completed",{channel:o.channel,namespace:re,tokenHash:le(a),tokenFound:!!d,actionKind:d?.kind,sessionId:d?.sessionId,planDecisionVersion:d?.planDecisionVersion}),!d)return await z(o,{alreadyAcknowledged:i}),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(d.kind==="question-answer"&&d.consumedAt!=null)return await z(o,{alreadyAcknowledged:i}),await $(o,"⚠️ That question button is no longer active. Use the latest question prompt."),{handled:!0};let l=d.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l,p=js(d,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:le(a),actionKind:d.kind,sessionId:l,sessionName:f,planDecisionVersion:d.planDecisionVersion,valid:!p}),p)return $o(d.kind)?await Ze(o,i):await z(o,{alreadyAcknowledged:i}),await $(o,`⚠️ ${p}`),{handled:!0};if(d.kind==="question-answer"){if(d.optionIndex==null)return await z(o,{alreadyAcknowledged:i}),await $(o,"⚠️ Invalid question-answer action."),{handled:!0};let c=_h(d);if(Vs.has(c))return await $(o,"⚠️ That answer is already being submitted. If the question remains active, try again."),{handled:!0};Vs.add(c);let h=!1,S=!1;try{if(h=await v.resolvePendingInputOption(l,d.optionIndex,{requestId:d.pendingInputRequestId,questionId:d.pendingInputQuestionId}),!h&&!(v.canSubmitPendingInputOption?.(l)??!1)){let T=v.getPersistedSession?.(l),A=Eh(d);A&&$h(T)&&(h=!(await Ie(v,{session:l,message:A,userInitiated:!0})).isError,S=h)}}catch(T){let A=T instanceof Error?T.message:String(T);return`${A}`,await $(o,au),{handled:!0}}finally{Vs.delete(c)}if(!h)return await $(o,au),{handled:!0};let x=(d.pendingInputRequestId?v.consumeQuestionAnswerTokens(l,d.pendingInputRequestId):[]).find(T=>T.id===a)??v.consumeActionToken(a);return B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!x,actionKind:x?.kind,sessionId:x?.sessionId,planDecisionVersion:x?.planDecisionVersion}),x?(await z(o,{alreadyAcknowledged:i}),await $(o,S?"✅ Answer forwarded to the resumed session.":"✅ Answer submitted."),{handled:!0}):(await z(o,{alreadyAcknowledged:i}),await $(o,S?"✅ Answer forwarded to the resumed session.":"✅ Answer submitted."),{handled:!0})}let k=Nh(d);if(k)for(;;){let c=Gn.get(k);if(!c)break;if(c.tokenId===a)return await Ze(o,i),await $(o,"⚠️ This plan decision is already being processed."),{handled:!0};await cu(c.operation);let h=v.getActionToken(a);if(!h)return await Ze(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(l=h.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l,p=js(h,u),B("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:le(a),actionKind:h.kind,sessionId:l,sessionName:f,planDecisionVersion:h.planDecisionVersion,valid:!p,afterPlanDecisionLock:!0}),p)return await Ze(o,i),await $(o,`⚠️ ${p}`),{handled:!0};d=h}if(d.kind==="plan-approve"){let c=d,h=!1,S=async(T=!1)=>{h||!T&&o.channel!=="telegram"||(await Ze(o,i),h=!0)},b=await du(k,a,async()=>(await S(),Ie(v,{session:c.sessionId,message:"Approved. Go ahead.",approve:!0,userInitiated:!0})));if(b.isError){let T=v.resolve?.(c.sessionId)??v.getPersistedSession?.(c.sessionId),A=Wh(T);if(A){let y=v.consumeActionToken(a);B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!y,actionKind:y?.kind,sessionId:y?.sessionId??c.sessionId,planDecisionVersion:y?.planDecisionVersion,approvalAppliedAfterError:!0}),await S(!0)}return A?await $(o,`⚠️ ${b.text}`):await Gh(o,`⚠️ ${b.text}`,v,c),{handled:!0}}let x=v.consumeActionToken(a);return B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!x,actionKind:x?.kind,sessionId:x?.sessionId??c.sessionId,planDecisionVersion:x?.planDecisionVersion}),x?(await S(!0),{handled:!0}):(await S(!0),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0})}if(d.kind==="plan-reject"||d.kind==="plan-request-changes")return await du(k,a,async()=>{let c=v.getActionToken(a);if(!c)return await Ze(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};l=c.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l;let h=js(c,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:le(a),actionKind:c.kind,sessionId:l,sessionName:f,planDecisionVersion:c.planDecisionVersion,valid:!h,afterPlanDecisionLock:!0}),h)return await Ze(o,i),await $(o,`⚠️ ${h}`),{handled:!0};let S=v.consumeActionToken(a);if(B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!S,actionKind:S?.kind,sessionId:S?.sessionId,planDecisionVersion:S?.planDecisionVersion}),!S)return await Ze(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(await Ze(o,i),S.kind==="plan-reject"){let b=ws(v,l);await $(o,`❌ ${b.text}`)}else{let b=Ps(v,l);await $(o,`✏️ ${b.text}`)}return{handled:!0}});let m=v.consumeActionToken(a);if(B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!m,actionKind:m?.kind,sessionId:m?.sessionId,planDecisionVersion:m?.planDecisionVersion}),!m)return await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:d.kind==="plan-offer-start"||d.kind==="plan-offer-dismiss"}),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};switch(m.kind){case"plugin-update-install":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),B("callback_update_action_started",{channel:o.channel,tokenHash:le(a),actionKind:m.kind,approvedVersion:m.pluginUpdateVersion}),!We){B("callback_update_action_failed",{channel:o.channel,tokenHash:le(a),reason:"service_unavailable"}),await $(o,"⚠️ OCA update service is not running.");break}let c;try{c=await We.installConfirmed(m.pluginUpdateVersion,{route:m.route})}catch(h){B("callback_update_action_failed",{channel:o.channel,tokenHash:le(a),reason:"install_failed"}),await $(o,`⚠️ OCA update failed: ${h instanceof Error?h.message:String(h)}`);break}B("callback_update_action_completed",{channel:o.channel,tokenHash:le(a),approvedVersion:m.pluginUpdateVersion});try{await $(o,`✅ ${c}`)}catch(h){B("callback_update_confirmation_failed",{channel:o.channel,tokenHash:le(a),reason:"reply_failed"}),`${h instanceof Error?h.message:String(h)}`}break}case"plugin-update-restart":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),!We){await $(o,"⚠️ OCA update service is not running.");break}try{let c=await We.restartConfirmed(m.pluginUpdateVersion);await $(o,`▶️ ${c}`)}catch(c){await $(o,`⚠️ Gateway restart failed: ${c instanceof Error?c.message:String(c)}`)}break}case"plugin-update-dismiss":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0});let c=We?We.dismiss(m.pluginUpdateVersion):"Dismissed OCA update reminder.";await $(o,`✅ ${c}`);break}case"plugin-update-remind-later":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0});let c=We?We.remindLater(m.pluginUpdateVersion):"Will remind later about OCA update reminder.";await $(o,`✅ ${c}`);break}case"worktree-merge":{let c=await n().execute("callback",{session:l}),h=_o(c);if(lu(c)){await Co(o,i);break}await $(o,h);break}case"worktree-decide-later":{let c=v.snoozeWorktreeDecision(l,{notifyUser:!1});if(Hs(c)){let S=`⏭️ Snoozed 24h for [${f}]`;await Co(o,i),await $(o,S)}else await $(o,c);break}case"worktree-dismiss":{let c=await v.dismissWorktree(l),h=Hs(c);h&&await Co(o,i),await $(o,h?"✅ Discarded":c);break}case"worktree-create-pr":case"worktree-update-pr":{let c=await r().execute("callback",{session:l}),h=_o(c);if(lu(c)){await Co(o,i);break}await $(o,h);break}case"worktree-view-pr":{await z(o,{alreadyAcknowledged:i});let c=v.getPersistedSession?.(l),h=d.targetUrl??c?.worktreePrUrl;await $(o,h?`PR: ${h}`:"⚠️ PR URL is no longer available.");break}case"plan-offer-start":{if(!m.launchPrompt||!m.launchWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the plan launch context.");break}let c;try{c=v.launchPlanOffer({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,worktreeStrategy:m.launchWorktreeStrategy})}catch(h){let S=h instanceof Error?h.message:String(h);await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Failed to start planning session: ${S}`);break}await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`▶️ Planning session started: ${c.name} [${c.id}]`);break}case"plan-offer-dismiss":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!m.repoPolicy||!m.repoPolicyWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the repo policy context.");break}if(!m.launchPrompt||!m.launchWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the launch context.");break}if(typeof v.resolveRepoPolicy=="function"){let S=v.resolveRepoPolicy(m.repoPolicyWorkdir);if(S.identity){let b=tn(m.repoPolicy,S.prAvailable);if(b){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ ${b}`);break}}}let c=v.setRepoPolicy(m.repoPolicyWorkdir,m.repoPolicy);if(!c){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Could not resolve a git repository for ${m.repoPolicyWorkdir}.`);break}v.clearRepoPolicyChoiceTokens(m.sessionId);let h;try{h=v.launchAfterRepoPolicyChoice({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,model:m.launchModel,reasoningEffort:m.launchReasoningEffort,fastMode:m.launchFastMode,systemPrompt:m.launchSystemPrompt,allowedTools:m.launchAllowedTools,resumeSessionId:m.launchResumeSessionId,resumedFromSessionName:m.launchResumedFromSessionName,resumeWorktreeFrom:m.launchResumeWorktreeFrom,sessionIdOverride:m.launchSessionIdOverride,clearedPersistedCodexResume:m.launchClearedPersistedCodexResume,forkSession:m.launchForkSession,forceNewSession:m.launchForceNewSession,permissionMode:m.launchPermissionMode,planApproval:m.launchPlanApproval,harness:m.launchHarness,worktreeStrategy:m.launchWorktreeStrategy,worktreeBaseBranch:m.launchWorktreeBaseBranch,worktreePrTargetRepo:m.launchWorktreePrTargetRepo,originAgentId:m.launchOriginAgentId}).text}catch(S){let b=S instanceof Error?S.message:String(S);await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Repo policy saved, but launch failed: ${b}`);break}await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,[`✅ Repo policy saved: ${El(c.policy).title}.`,"",h].join(`
141
+ Approval is still pending. Try again below.`:e,...o?{buttons:o}:{}})}function mu(t="telegram",e={}){let n=e.makeAgentMergeTool??go,r=e.makeAgentPrTool??jn;return B("callback_handler_registered",{channel:t,namespace:re}),{channel:t,namespace:re,handler:async o=>{let i=await Uh(o);if(!o.auth.isAuthorizedSender)return await $(o,"⛔ Unauthorized."),{handled:!0};let s=Fh(o),a=Dh(s);if(B("callback_received",{channel:o.channel,namespace:re,payloadByteLength:Buffer.byteLength(s,"utf8"),tokenHash:le(a),isAuthorizedSender:o.auth.isAuthorizedSender}),!a)return await $(o,"⚠️ Unrecognized callback payload."),{handled:!0};if(!v)return await $(o,"⚠️ Code agent service not running."),{handled:!0};let d=v.getActionToken(a);if(B("callback_token_lookup_completed",{channel:o.channel,namespace:re,tokenHash:le(a),tokenFound:!!d,actionKind:d?.kind,sessionId:d?.sessionId,planDecisionVersion:d?.planDecisionVersion}),!d)return await z(o,{alreadyAcknowledged:i}),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(d.kind==="question-answer"&&d.consumedAt!=null)return await z(o,{alreadyAcknowledged:i}),await $(o,"⚠️ That question button is no longer active. Use the latest question prompt."),{handled:!0};let l=d.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l,p=js(d,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:le(a),actionKind:d.kind,sessionId:l,sessionName:f,planDecisionVersion:d.planDecisionVersion,valid:!p}),p)return $o(d.kind)?await Ze(o,i):await z(o,{alreadyAcknowledged:i}),await $(o,`⚠️ ${p}`),{handled:!0};if(d.kind==="question-answer"){if(d.optionIndex==null)return await z(o,{alreadyAcknowledged:i}),await $(o,"⚠️ Invalid question-answer action."),{handled:!0};let c=_h(d);if(Vs.has(c))return await $(o,"⚠️ That answer is already being submitted. If the question remains active, try again."),{handled:!0};Vs.add(c);let h=!1,S=!1;try{if(h=await v.resolvePendingInputOption(l,d.optionIndex,{requestId:d.pendingInputRequestId,questionId:d.pendingInputQuestionId}),!h&&!(v.canSubmitPendingInputOption?.(l)??!1)){let A=v.getPersistedSession?.(l),y=Eh(d);y&&$h(A)&&(h=!(await Ie(v,{session:l,message:y,userInitiated:!0})).isError,S=h)}}catch(A){let y=A instanceof Error?A.message:String(A);return`${y}`,await $(o,au),{handled:!0}}finally{Vs.delete(c)}if(!h)return await $(o,au),{handled:!0};let x=(d.pendingInputRequestId?v.consumeQuestionAnswerTokens(l,d.pendingInputRequestId,d.pendingInputQuestionId):[]).find(A=>A.id===a)??v.consumeActionToken(a);if(B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!x,actionKind:x?.kind,sessionId:x?.sessionId,planDecisionVersion:x?.planDecisionVersion}),!x){await z(o,{alreadyAcknowledged:i});let A=!S&&(v.pendingInputSubmissionRequiresMore?.(l)??!1);return await $(o,S?"✅ Answer forwarded to the resumed session.":A?"✅ Question step answered; more input is required.":"✅ Pending input request submitted."),{handled:!0}}await z(o,{alreadyAcknowledged:i});let C=!S&&(v.pendingInputSubmissionRequiresMore?.(l)??!1);return await $(o,S?"✅ Answer forwarded to the resumed session.":C?"✅ Question step answered; more input is required.":"✅ Pending input request submitted."),{handled:!0}}let k=Nh(d);if(k)for(;;){let c=Gn.get(k);if(!c)break;if(c.tokenId===a)return await Ze(o,i),await $(o,"⚠️ This plan decision is already being processed."),{handled:!0};await cu(c.operation);let h=v.getActionToken(a);if(!h)return await Ze(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(l=h.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l,p=js(h,u),B("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:le(a),actionKind:h.kind,sessionId:l,sessionName:f,planDecisionVersion:h.planDecisionVersion,valid:!p,afterPlanDecisionLock:!0}),p)return await Ze(o,i),await $(o,`⚠️ ${p}`),{handled:!0};d=h}if(d.kind==="plan-approve"){let c=d,h=!1,S=async(C=!1)=>{h||!C&&o.channel!=="telegram"||(await Ze(o,i),h=!0)},P=await du(k,a,async()=>(await S(),Ie(v,{session:c.sessionId,message:"Approved. Go ahead.",approve:!0,userInitiated:!0})));if(P.isError){let C=v.resolve?.(c.sessionId)??v.getPersistedSession?.(c.sessionId),A=Wh(C);if(A){let y=v.consumeActionToken(a);B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!y,actionKind:y?.kind,sessionId:y?.sessionId??c.sessionId,planDecisionVersion:y?.planDecisionVersion,approvalAppliedAfterError:!0}),await S(!0)}return A?await $(o,`⚠️ ${P.text}`):await Gh(o,`⚠️ ${P.text}`,v,c),{handled:!0}}let x=v.consumeActionToken(a);return B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!x,actionKind:x?.kind,sessionId:x?.sessionId??c.sessionId,planDecisionVersion:x?.planDecisionVersion}),x?(await S(!0),{handled:!0}):(await S(!0),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0})}if(d.kind==="plan-reject"||d.kind==="plan-request-changes")return await du(k,a,async()=>{let c=v.getActionToken(a);if(!c)return await Ze(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};l=c.sessionId,u=v.resolve?.(l)??v.getPersistedSession?.(l),f=u?.name??l;let h=js(c,u);if(B("callback_plan_validation_completed",{channel:o.channel,namespace:re,tokenHash:le(a),actionKind:c.kind,sessionId:l,sessionName:f,planDecisionVersion:c.planDecisionVersion,valid:!h,afterPlanDecisionLock:!0}),h)return await Ze(o,i),await $(o,`⚠️ ${h}`),{handled:!0};let S=v.consumeActionToken(a);if(B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!S,actionKind:S?.kind,sessionId:S?.sessionId,planDecisionVersion:S?.planDecisionVersion}),!S)return await Ze(o,i),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};if(await Ze(o,i),S.kind==="plan-reject"){let P=ws(v,l);await $(o,`❌ ${P.text}`)}else{let P=Ps(v,l);await $(o,`✏️ ${P.text}`)}return{handled:!0}});let m=v.consumeActionToken(a);if(B("callback_token_consume_completed",{channel:o.channel,namespace:re,tokenHash:le(a),consumed:!!m,actionKind:m?.kind,sessionId:m?.sessionId,planDecisionVersion:m?.planDecisionVersion}),!m)return await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:d.kind==="plan-offer-start"||d.kind==="plan-offer-dismiss"}),o.channel!=="telegram"&&await $(o,"⚠️ This action is stale or has already been used."),{handled:!0};switch(m.kind){case"plugin-update-install":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),B("callback_update_action_started",{channel:o.channel,tokenHash:le(a),actionKind:m.kind,approvedVersion:m.pluginUpdateVersion}),!We){B("callback_update_action_failed",{channel:o.channel,tokenHash:le(a),reason:"service_unavailable"}),await $(o,"⚠️ OCA update service is not running.");break}let c;try{c=await We.installConfirmed(m.pluginUpdateVersion,{route:m.route})}catch(h){B("callback_update_action_failed",{channel:o.channel,tokenHash:le(a),reason:"install_failed"}),await $(o,`⚠️ OCA update failed: ${h instanceof Error?h.message:String(h)}`);break}B("callback_update_action_completed",{channel:o.channel,tokenHash:le(a),approvedVersion:m.pluginUpdateVersion});try{await $(o,`✅ ${c}`)}catch(h){B("callback_update_confirmation_failed",{channel:o.channel,tokenHash:le(a),reason:"reply_failed"}),`${h instanceof Error?h.message:String(h)}`}break}case"plugin-update-restart":{if(await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),!We){await $(o,"⚠️ OCA update service is not running.");break}try{let c=await We.restartConfirmed(m.pluginUpdateVersion);await $(o,`▶️ ${c}`)}catch(c){await $(o,`⚠️ Gateway restart failed: ${c instanceof Error?c.message:String(c)}`)}break}case"plugin-update-dismiss":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0});let c=We?We.dismiss(m.pluginUpdateVersion):"Dismissed OCA update reminder.";await $(o,`✅ ${c}`);break}case"plugin-update-remind-later":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0});let c=We?We.remindLater(m.pluginUpdateVersion):"Will remind later about OCA update reminder.";await $(o,`✅ ${c}`);break}case"worktree-merge":{let c=await n().execute("callback",{session:l}),h=_o(c);if(lu(c)){await Co(o,i);break}await $(o,h);break}case"worktree-decide-later":{let c=v.snoozeWorktreeDecision(l,{notifyUser:!1});if(Hs(c)){let S=`⏭️ Snoozed 24h for [${f}]`;await Co(o,i),await $(o,S)}else await $(o,c);break}case"worktree-dismiss":{let c=await v.dismissWorktree(l),h=Hs(c);h&&await Co(o,i),await $(o,h?"✅ Discarded":c);break}case"worktree-create-pr":case"worktree-update-pr":{let c=await r().execute("callback",{session:l}),h=_o(c);if(lu(c)){await Co(o,i);break}await $(o,h);break}case"worktree-view-pr":{await z(o,{alreadyAcknowledged:i});let c=v.getPersistedSession?.(l),h=d.targetUrl??c?.worktreePrUrl;await $(o,h?`PR: ${h}`:"⚠️ PR URL is no longer available.");break}case"plan-offer-start":{if(!m.launchPrompt||!m.launchWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the plan launch context.");break}let c;try{c=v.launchPlanOffer({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,worktreeStrategy:m.launchWorktreeStrategy})}catch(h){let S=h instanceof Error?h.message:String(h);await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Failed to start planning session: ${S}`);break}await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`▶️ Planning session started: ${c.name} [${c.id}]`);break}case"plan-offer-dismiss":{await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"✅ Dismissed.");break}case"repo-policy-set":{if(!m.repoPolicy||!m.repoPolicyWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the repo policy context.");break}if(!m.launchPrompt||!m.launchWorkdir){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,"⚠️ This action is missing the launch context.");break}if(typeof v.resolveRepoPolicy=="function"){let S=v.resolveRepoPolicy(m.repoPolicyWorkdir);if(S.identity){let P=tn(m.repoPolicy,S.prAvailable);if(P){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ ${P}`);break}}}let c=v.setRepoPolicy(m.repoPolicyWorkdir,m.repoPolicy);if(!c){await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Could not resolve a git repository for ${m.repoPolicyWorkdir}.`);break}v.clearRepoPolicyChoiceTokens(m.sessionId);let h;try{h=v.launchAfterRepoPolicyChoice({route:m.route,prompt:m.launchPrompt,workdir:m.launchWorkdir,name:m.launchName,model:m.launchModel,reasoningEffort:m.launchReasoningEffort,fastMode:m.launchFastMode,systemPrompt:m.launchSystemPrompt,allowedTools:m.launchAllowedTools,resumeSessionId:m.launchResumeSessionId,resumedFromSessionName:m.launchResumedFromSessionName,resumeWorktreeFrom:m.launchResumeWorktreeFrom,sessionIdOverride:m.launchSessionIdOverride,clearedPersistedCodexResume:m.launchClearedPersistedCodexResume,forkSession:m.launchForkSession,forceNewSession:m.launchForceNewSession,permissionMode:m.launchPermissionMode,planApproval:m.launchPlanApproval,harness:m.launchHarness,worktreeStrategy:m.launchWorktreeStrategy,worktreeBaseBranch:m.launchWorktreeBaseBranch,worktreePrTargetRepo:m.launchWorktreePrTargetRepo,originAgentId:m.launchOriginAgentId}).text}catch(S){let P=S instanceof Error?S.message:String(S);await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,`⚠️ Repo policy saved, but launch failed: ${P}`);break}await z(o,{alreadyAcknowledged:i,forceTelegramMarkupEdit:!0}),await $(o,[`✅ Repo policy saved: ${El(c.policy).title}.`,"",h].join(`
142
142
  `));break}case"session-restart":case"session-resume":{await z(o,{alreadyAcknowledged:i});let c=await Ie(v,{session:l,message:"Continue where you left off.",userInitiated:!0});await $(o,c.isError?`⚠️ ${c.text}`:`▶️ ${c.text}`);break}case"view-output":{await z(o,{alreadyAcknowledged:i});let c=await oo().execute("callback",{session:l,lines:50});await $(o,_o(c));break}default:{await z(o,{alreadyAcknowledged:i}),await $(o,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}V();ae();function on(t){return fu(t).map(e=>e.value)}function fu(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:Hh(n),raw:n,start:r,end:r+n.length}})}function _t(t){let[e]=fu(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function Hh(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function zh(t){return t instanceof Error?t.message:String(t)}function Qh(t){let e=on(t),n,r=e;return e[0]==="--name"&&e[1]&&(n=e[1],r=e.slice(2)),{name:n,prompt:r.join(" ").trim()}}function gu(t){t.registerCommand({name:"agent",description:"Launch a coding agent session. Usage: /agent [--name <name>] <prompt>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent [--name <name>] <prompt>"};let{name:r,prompt:o}=Qh(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=xr({prompt:o,name:r},e,v);if(i.kind!=="resolved")return{text:i.text};let s=v.spawn({prompt:o,name:r,workdir:i.workdir,model:i.resolvedModel,reasoningEffort:i.reasoningEffort,fastMode:i.fastMode,codexApprovalPolicy:i.harness==="codex"?"never":void 0,originChannel:i.originChannel,originThreadId:i.originThreadId,originAgentId:e.agentId||void 0,originSessionKey:i.originSessionKey,route:i.route,harness:i.harness,permissionMode:i.permissionMode,planApproval:i.planApproval,taskLifecycle:Dr(e)});return{text:v.formatLaunchResult({prompt:o,workdir:i.workdir,harness:i.harness,permissionMode:i.permissionMode??D.permissionMode,planApproval:i.planApproval},s)}}catch(i){let s=zh(i),a=s.includes("Max sessions")?"":`
143
143
 
144
144
  Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${a}`}}}})}V();function hu(t){t.registerCommand({name:"agent_sessions",description:"List coding agent sessions. Usage: /agent_sessions [--full]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").split(/\s+/).includes("--full");return{text:no(v,"all",void 0,{full:n})}}})}V();function yu(t){t.registerCommand({name:"agent_kill",description:"Kill a coding agent session by name or ID",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=e.args?.trim();return n?{text:ro(v,n,"killed")}:{text:"Usage: /agent_kill <name-or-id>"}}})}V();function ku(t){t.registerCommand({name:"agent_respond",description:"Send a follow-up message to a running coding agent session. Usage: /agent_respond <id-or-name> <message>",acceptsArgs:!0,requireAuth:!0,handler:async e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:`Usage: /agent_respond <id-or-name> <message>
@@ -148,7 +148,7 @@ Use /agent_sessions to see active sessions.`;return{text:`Error launching sessio
148
148
  `)};if(l.kind==="ambiguous")return{text:[d,"",`Repo policy saved, but ${l.count} pending launches match this policy. Run the intended launch again to avoid starting the wrong session.`].join(`
149
149
  `)}}catch(l){let u=l instanceof Error?l.message:String(l);return{text:[d,"",`Repo policy saved, but the deferred launch failed: ${u}`,"The pending launch context was kept so you can retry the same /agent_policy command or run the intended launch again."].join(`
150
150
  `)}}return{text:d}}let i=v.resolveRepoPolicy(o);if(!i.identity)return{text:`No git repository found for ${o}.`};let s=Dn(i.prAvailable).map(a=>a.policy).join(", ");return{text:[`Repo policy: ${i.policy??"unknown"}`,`Repo: ${i.identity.repoRoot}`,`Provider: ${i.provider}${i.prAvailable?"":" (PR automation unavailable)"}`,...i.identity.remoteUrl?[`Remote: ${i.identity.remoteUrl}`]:[],"",`Set with /agent_policy ${s}.`].join(`
151
- `)}}})}V();var Yh=50;function wu(t){t.registerCommand({name:"agent_output",description:"Show recent output from a coding agent session. Usage: /agent_output <id-or-name> [--full] [--lines N]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"};let r=on(n),o="",i=!1,s=Yh;for(let d=0;d<r.length;d++)if(r[d]==="--full")i=!0;else if(r[d]==="--lines"&&d+1<r.length){let l=parseInt(r[d+1],10);!isNaN(l)&&l>0&&(s=l),d++}else o||(o=r[d]);return o?{text:to(v,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}V();var Pu="Usage: /agent_goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function bu(t){t.registerCommand({name:"agent_goal",description:"Launch an explicit goal task (Ralph-style completion loop or verifier-driven loop)",acceptsArgs:!0,requireAuth:!0,handler:async e=>{if(!Z)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:Pu};let r=on(n),o,i,s,a,d="bypassPermissions",l,u,f,p=[],k=[];for(let h=0;h<r.length;h++){let S=r[h];if(S==="--name"&&h+1<r.length)o=r[++h];else if(S==="--workdir"&&h+1<r.length)i=r[++h];else if(S==="--model"&&h+1<r.length)s=r[++h];else if(S==="--max-iterations"&&h+1<r.length){let b=parseInt(r[++h],10);!Number.isNaN(b)&&b>0&&(a=b)}else if(S==="--permission-mode"&&h+1<r.length){let b=r[++h];if(b==="default"||b==="plan"||b==="bypassPermissions")d=b;else return{text:`Error: Invalid permission mode "${b}".`}}else if(S==="--harness"&&h+1<r.length)l=r[++h];else if(S==="--mode"&&h+1<r.length){let b=r[++h];if(b==="ralph"||b==="verifier")u=b;else return{text:`Error: Invalid goal mode "${b}". Use ralph or verifier.`}}else if(S==="--completion-promise"&&h+1<r.length)f=r[++h];else if(S==="--verify"&&h+1<r.length){let b=r[++h].trim();if(!b)return{text:"Error: --verify commands must not be empty."};p.push(b)}else k.push(S)}let m=k.join(" ").trim();if(!m)return{text:Pu};let c=bo({goal:m,verifierCommands:p,name:o,workdir:i,model:s,maxIterations:a,permissionMode:d,harness:l,goalMode:u,completionPromise:f},e);if(c.kind!=="resolved")return{text:c.text};try{let h=await Z.launchTask({goal:c.goal,name:c.name,workdir:c.workdir,model:c.model,reasoningEffort:c.reasoningEffort,fastMode:c.fastMode,maxIterations:c.maxIterations,permissionMode:c.permissionMode,harness:c.harness,loopMode:c.loopMode,completionPromise:c.completionPromise,originChannel:c.originChannel,originThreadId:c.originThreadId,originAgentId:c.originAgentId,originSessionKey:c.originSessionKey,route:c.route,verifierCommands:c.verifierCommands});return{text:Ro(h,c)}}catch(h){return{text:`Error launching goal task: ${h instanceof Error?h.message:String(h)}`}}}})}V();function Ru(t){t.registerCommand({name:"agent_goal_status",description:"Show one goal task or list all explicit goal tasks. Usage: /agent_goal_status [<task-id-or-name>]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!Z)return{text:Me};let n=(e.args??"").trim();return{text:Io(Z,r=>v?.resolve(r),n)}}})}V();function Au(t){t.registerCommand({name:"agent_goal_stop",description:"Stop a goal task. Usage: /agent_goal_stop <task-id-or-name>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!Z)return{text:Me};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent_goal_stop <task-id-or-name>"};let r=Z.stopTask(n);return{text:xo(r,n)}}})}V();var Iu="Usage: /agent_goal_edit <task-id-or-name> <replacement-goal>";function xu(t){t.registerCommand({name:"agent_goal_edit",description:"Edit a running goal task. Usage: /agent_goal_edit <task-id-or-name> <replacement-goal>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!Z)return{text:Me};let n=(e.args??"").trim();if(!n)return{text:Iu};let r=_t(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:Iu};let s=Z.editTask(o,i);return{text:To(s,o)}}})}import{execFile as cy}from"child_process";import{createHash as Uu}from"crypto";import{existsSync as zn,mkdirSync as Zh,readFileSync as Xh,renameSync as Mu,writeFileSync as ey}from"fs";import{homedir as ty}from"os";import{dirname as ny,join as _u}from"path";var ry=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function oy(t){let e=t.OPENCLAW_HOME?.trim();return e||_u(ty(),".openclaw")}function iy(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||_u(oy(t),"code-agent-goal-tasks.json")}function $u(t){return t instanceof Error?t.message:String(t)}function Eu(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var sy=100;function Tu(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function ay(t){if(!zn(t))return;let e=Date.now(),n=Tu(t,e);if(!zn(n))return n;for(let r=1;r<=sy;r+=1){let o=Tu(t,e,r);if(!zn(o))return o}}function Cu(t,e){try{let n=ay(t);return n?(Mu(t,n),`${e}${n}`,!0):(zn(t),!1)}catch(n){return`${$u(n)}`,!1}}function dy(t){if(!Eu(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 ly(t){if(!Eu(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"||!ry.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:dy(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 uy(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=ly(n);if(!r)return;e.push(r)}return e}var Eo=class{path;tasks=new Map;constructor(e=process.env){this.path=iy(e),this.load()}load(){try{if(!zn(this.path))return;let e=Xh(this.path,"utf8"),n=JSON.parse(e),r=uy(n);if(!r){Cu(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;Cu(this.path,"corrupt or unreadable")&&this.save()}}save(){try{Zh(ny(this.path),{recursive:!0});let e=`${this.path}.tmp`;ey(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),Mu(e,this.path)}catch(e){`${this.path}${$u(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)}};ke();var py=8,Ku=600*1e3,my=4e3,zs=1200,fy="DONE",gy=["BASH_ENV","ENV"];function hy(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"goal-task"}function sn(t,e){return t.length<=e?t:`${t.slice(0,e-3)}...`}function mt(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(`
151
+ `)}}})}V();var Yh=50;function wu(t){t.registerCommand({name:"agent_output",description:"Show recent output from a coding agent session. Usage: /agent_output <id-or-name> [--full] [--lines N]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"};let r=on(n),o="",i=!1,s=Yh;for(let d=0;d<r.length;d++)if(r[d]==="--full")i=!0;else if(r[d]==="--lines"&&d+1<r.length){let l=parseInt(r[d+1],10);!isNaN(l)&&l>0&&(s=l),d++}else o||(o=r[d]);return o?{text:to(v,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}V();var Pu="Usage: /agent_goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function bu(t){t.registerCommand({name:"agent_goal",description:"Launch an explicit goal task (Ralph-style completion loop or verifier-driven loop)",acceptsArgs:!0,requireAuth:!0,handler:async e=>{if(!Z)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:Pu};let r=on(n),o,i,s,a,d="bypassPermissions",l,u,f,p=[],k=[];for(let h=0;h<r.length;h++){let S=r[h];if(S==="--name"&&h+1<r.length)o=r[++h];else if(S==="--workdir"&&h+1<r.length)i=r[++h];else if(S==="--model"&&h+1<r.length)s=r[++h];else if(S==="--max-iterations"&&h+1<r.length){let P=parseInt(r[++h],10);!Number.isNaN(P)&&P>0&&(a=P)}else if(S==="--permission-mode"&&h+1<r.length){let P=r[++h];if(P==="default"||P==="plan"||P==="bypassPermissions")d=P;else return{text:`Error: Invalid permission mode "${P}".`}}else if(S==="--harness"&&h+1<r.length)l=r[++h];else if(S==="--mode"&&h+1<r.length){let P=r[++h];if(P==="ralph"||P==="verifier")u=P;else return{text:`Error: Invalid goal mode "${P}". Use ralph or verifier.`}}else if(S==="--completion-promise"&&h+1<r.length)f=r[++h];else if(S==="--verify"&&h+1<r.length){let P=r[++h].trim();if(!P)return{text:"Error: --verify commands must not be empty."};p.push(P)}else k.push(S)}let m=k.join(" ").trim();if(!m)return{text:Pu};let c=bo({goal:m,verifierCommands:p,name:o,workdir:i,model:s,maxIterations:a,permissionMode:d,harness:l,goalMode:u,completionPromise:f},e);if(c.kind!=="resolved")return{text:c.text};try{let h=await Z.launchTask({goal:c.goal,name:c.name,workdir:c.workdir,model:c.model,reasoningEffort:c.reasoningEffort,fastMode:c.fastMode,maxIterations:c.maxIterations,permissionMode:c.permissionMode,harness:c.harness,loopMode:c.loopMode,completionPromise:c.completionPromise,originChannel:c.originChannel,originThreadId:c.originThreadId,originAgentId:c.originAgentId,originSessionKey:c.originSessionKey,route:c.route,verifierCommands:c.verifierCommands});return{text:Ro(h,c)}}catch(h){return{text:`Error launching goal task: ${h instanceof Error?h.message:String(h)}`}}}})}V();function Ru(t){t.registerCommand({name:"agent_goal_status",description:"Show one goal task or list all explicit goal tasks. Usage: /agent_goal_status [<task-id-or-name>]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!Z)return{text:Me};let n=(e.args??"").trim();return{text:Io(Z,r=>v?.resolve(r),n)}}})}V();function Au(t){t.registerCommand({name:"agent_goal_stop",description:"Stop a goal task. Usage: /agent_goal_stop <task-id-or-name>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!Z)return{text:Me};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent_goal_stop <task-id-or-name>"};let r=Z.stopTask(n);return{text:xo(r,n)}}})}V();var Iu="Usage: /agent_goal_edit <task-id-or-name> <replacement-goal>";function xu(t){t.registerCommand({name:"agent_goal_edit",description:"Edit a running goal task. Usage: /agent_goal_edit <task-id-or-name> <replacement-goal>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!Z)return{text:Me};let n=(e.args??"").trim();if(!n)return{text:Iu};let r=_t(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:Iu};let s=Z.editTask(o,i);return{text:To(s,o)}}})}import{execFile as cy}from"child_process";import{createHash as Uu}from"crypto";import{existsSync as zn,mkdirSync as Zh,readFileSync as Xh,renameSync as Mu,writeFileSync as ey}from"fs";import{homedir as ty}from"os";import{dirname as ny,join as _u}from"path";var ry=new Set(["running","waiting_for_session","waiting_for_user","succeeded","failed","stopped"]);function oy(t){let e=t.OPENCLAW_HOME?.trim();return e||_u(ty(),".openclaw")}function iy(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||_u(oy(t),"code-agent-goal-tasks.json")}function $u(t){return t instanceof Error?t.message:String(t)}function Eu(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}var sy=100;function Tu(t,e,n){let r=n==null?"":`-${n}`;return`${t}.invalid-${e}${r}.json`}function ay(t){if(!zn(t))return;let e=Date.now(),n=Tu(t,e);if(!zn(n))return n;for(let r=1;r<=sy;r+=1){let o=Tu(t,e,r);if(!zn(o))return o}}function Cu(t,e){try{let n=ay(t);return n?(Mu(t,n),`${e}${n}`,!0):(zn(t),!1)}catch(n){return`${$u(n)}`,!1}}function dy(t){if(!Eu(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 ly(t){if(!Eu(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"||!ry.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:dy(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 uy(t){if(!Array.isArray(t))return;let e=[];for(let n of t){let r=ly(n);if(!r)return;e.push(r)}return e}var Eo=class{path;tasks=new Map;constructor(e=process.env){this.path=iy(e),this.load()}load(){try{if(!zn(this.path))return;let e=Xh(this.path,"utf8"),n=JSON.parse(e),r=uy(n);if(!r){Cu(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;Cu(this.path,"corrupt or unreadable")&&this.save()}}save(){try{Zh(ny(this.path),{recursive:!0});let e=`${this.path}.tmp`;ey(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),Mu(e,this.path)}catch(e){`${this.path}${$u(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)}};ke();var py=8,Ku=600*1e3,my=4e3,zs=1200,fy="DONE",gy=["BASH_ENV","ENV"];function hy(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"goal-task"}function sn(t,e){return t.length<=e?t:`${t.slice(0,e-3)}...`}function mt(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(`
152
152
  `):n.slice(-e).join(`
153
153
  `)}function yy(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(`
154
154
  `):void 0}function Du(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ou(t){let e=t?.trim();return e&&e.length>0?e:fy}function ky(t){return t.route??_e(t.originChannel,t.originThreadId,t.originSessionKey)}function Qs(t){return t.map((e,n)=>({label:e.label.trim()||`check-${n+1}`,command:e.command.trim(),timeoutMs:e.timeoutMs??Ku})).filter(e=>e.command.length>0)}function Sy(t){return t.loopMode==="verifier"}function vy(t){return Qs(t.verifierCommands).length>0}function Nu(t){return Sy(t)&&!vy(t)}function Do(){return"Verifier-mode goal tasks require at least one verifier command."}function Wu(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${mt(n.output,12)}`).join(`
@@ -193,7 +193,7 @@ ${e.failureReason}`,"goal-task-stopped")}async handleRunningSession(e,n){if(n.pe
193
193
  `));return}e.iteration+=1;let k=Ay(e,p),m=Ao({output:s,verifierSummary:p.summary,completionPromise:a,completionDetected:!0});try{let c=await this.resumeTaskSession(e,k,n);this.setTaskRunningWithSession(e,c),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,m),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",c.id)}catch(c){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${$t(c)}`)}return}let l=wy(s);if(e.lastVerifierFingerprint===l?e.repeatedFailureCount+=1:e.repeatedFailureCount=1,e.lastVerifierFingerprint=l,e.iteration+1>=e.maxIterations){this.markTaskFailed(e,[`Completion promise "${a}" was not emitted before hitting the iteration budget (${e.maxIterations}).`,"Latest output:",mt(s,20)||"(no output)"].join(`
194
194
  `));return}e.iteration+=1;let u=Ry(e,s),f=Ao({output:s,completionPromise:a,completionDetected:!1});try{let p=await this.resumeTaskSession(e,u,n);this.setTaskRunningWithSession(e,p),this.notifyIterationStatus(e,`🔁 [${e.name}] Continued`,void 0,f),this.scheduleTaskEvaluation(e.id,"ralph-continue",p.id)}catch(p){this.markTaskFailed(e,`Failed to continue the Ralph goal task: ${$t(p)}`)}return}let r=await this.runVerifiers(e);if(e.lastVerifierSummary=r.summary,e.updatedAt=Date.now(),r.status==="pass"){this.markTaskSucceeded(e,r.summary);return}if(e.lastVerifierFingerprint===r.fingerprint?e.repeatedFailureCount+=1:e.repeatedFailureCount=1,e.lastVerifierFingerprint=r.fingerprint,e.iteration+1>=e.maxIterations){this.markTaskFailed(e,[`Verifier did not pass before hitting the iteration budget (${e.maxIterations}).`,r.summary].join(`
195
195
  `));return}e.iteration+=1;let o=by(e,r),i=Ao({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: ${$t(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(Nu(e)){this.markTaskFailed(e,Do());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 Gc}from"crypto";ae();import{existsSync as My,realpathSync as _y}from"fs";import{resolve as $y}from"path";function Vu(t){if(!t)return;let e=$y(t);try{if(My(e))return _y.native(e)}catch{}return e}function No(t,e){return!t||!e?!1:Vu(t)===Vu(e)}ne();ae();import{existsSync as Ey}from"fs";ke();ne();Ae();function Dy(t){if(!(!t.provider||!t.target))return t.accountId?`${t.provider}|${t.accountId}|${t.target}`:`${t.provider}|${t.target}`}function Oy(t){return gn(Ne({route:t.route,originChannel:t.originChannel,originThreadId:t.originThreadId,originSessionKey:t.originSessionKey}))}function Ny(t,e){if(Oy(t))return;let n=[t.resumeSessionId,t.resumeWorktreeFrom].filter(r=>!!r?.trim());for(let r of n){let o=e(r);if(!o)continue;let i=Ne({route:o.route,originChannel:o.originChannel,originThreadId:o.originThreadId,originSessionKey:o.originSessionKey});if(gn(i)){t.route={...i},t.originChannel=o.originChannel??Dy(i),t.originThreadId=o.originThreadId??i.threadId,t.originSessionKey=o.originSessionKey??i.sessionKey,t.originAgentId??=o.originAgentId;return}}}function ju(t){return t instanceof Error?t.message:String(t)}function Wy(t){let e=t.worktreeStrategy??D.defaultWorktreeStrategy;return!!e&&e!=="off"&&is(Tn({harnessName:t.harness??fe(),backendRef:t.backendRef}))}function Ly(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(`
196
- `);return(t??"")+o}function By(t,e){let n=t.resumeWorktreeFrom??t.resumeSessionId;if(!n)return{};let r=e(n);if(!r)return{};let o=!!r.harness||!!r.backendRef,i=(()=>{if(r.workdir&&r.workdir!==r.worktreePath)return r.workdir;if(r.worktreePath){let a=Vr(r.worktreePath);return r.workdir&&a&&No(r.workdir,a)?r.workdir:a??r.workdir}return r.workdir})();if(t.worktreeStrategy||(r.worktreeLifecycle?.state==="pr_open"||r.worktreePrUrl?t.worktreeStrategy="auto-pr":r.worktreeStrategy&&(t.worktreeStrategy=r.worktreeStrategy)),!t.planApproval&&r.planApproval&&(t.planApproval=r.planApproval),!r.worktreePath){let a=o&&Ar(Tn({persistedHarness:r.harness,backendRef:r.backendRef}));return{originalWorkdir:i,canCreateManagedWorktreeForResumeWithoutPersistedPath:a}}if(!r.worktreeBranch)throw new Error(`Cannot resume session "${n}": persisted worktree metadata is missing worktreeBranch.`);let s=Ar(Tn({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(Ey(r.worktreePath))return`${r.worktreePath}`,{actualWorkdir:r.worktreePath,originalWorkdir:i??r.worktreePath,worktreePath:r.worktreePath,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch};if(!i)return`${r.worktreePath}`,{clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom};if(s)return`${r.worktreePath}`,{actualWorkdir:i,originalWorkdir:i,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,restoredMissingNativeBackendWorktree:!0};try{zr(i);let a=ps(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:i,worktreePath:a,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch}}catch(a){return`${ju(a)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function Gu(t,e,n){Ny(t,n);let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,worktreeParentBranch:a,clearedResumeSessionId:d,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:u,canCreateManagedWorktreeForResumeWithoutPersistedPath:f,failedResumeWorktreeRestore:p}=By(t,n);d&&(t.resumeSessionId=void 0),l&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,o??=t.workdir;let k=!!(t.resumeSessionId??t.resumeWorktreeFrom),m=t.worktreeStrategy??D.defaultWorktreeStrategy;m&&(t.worktreeStrategy=m),!k&&m&&m!=="off"&&jr(o)&&(a??=Se(o));let c=Wy(t),S=(!k||!!f)&&!u&&!i&&m&&m!=="off"&&!c;if(p&&m&&m!=="off")throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);if(c&&!jr(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" requires a git worktree, but "${o}" is not a git repository.`);if(S&&jr(o)){if(!Qd(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=ps(o,e),r=i,s=Se(i),!s)throw new Error(`created worktree at ${i} but failed to resolve branch name`);`${i}`}catch(b){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${ju(b)}`)}}else if(S)throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" requires a git worktree, but "${o}" is not a git repository.`);if(k&&i&&(r=i),m&&m!=="off"&&!i)throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);return{actualWorkdir:r,originalWorkdir:o,effectiveSystemPrompt:i&&s?Ly(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,worktreeParentBranch:a,clearedResumeSessionId:d,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:u,failedResumeWorktreeRestore:p}}var Wo=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return Gu(e,n,this.getPersistedSession)}hydrateSpawnedSession(e,n,r){r.worktreeStrategy&&r.worktreeStrategy!=="off"&&(e.originalWorkdir=n.originalWorkdir),e.worktreeParentBranch=n.worktreeParentBranch,n.worktreePath&&(e.worktreePath=n.worktreePath,e.worktreeBranch=n.worktreeBranchName,e.worktreeState="provisioned"),r.worktreePrTargetRepo&&(e.worktreePrTargetRepo=r.worktreePrTargetRepo)}};ne();var Lo=class{constructor(e){this.deps=e}deps;applySessionPatch(e,n){let r=this.normalizeCompletionWakePatch(n),o=this.deps.store.getPersistedSession(e);o&&(Object.assign(o,r),this.deps.store.assertPersistedEntry(o));let i=this.findActiveSessionForRef(e,o);return i&&this.applyPatchToActiveSession(i,r),!o&&!i?!1:(o&&this.deps.store.saveIndex(),!0)}normalizeCompletionWakePatch(e){return"completionWakeSucceededAt"in e&&e.completionWakeSucceededAt||"completionWakeSkippedAt"in e&&e.completionWakeSkippedAt?{...e,completionWakeSummaryRequired:void 0}:e}matchesExistingSession(e,n){if(!n)return!1;let r=O(e),o=O(n);return!!(n.sessionId&&e.id===n.sessionId||o&&o===r||n?.harnessSessionId&&e.harnessSessionId===n.harnessSessionId||n?.name&&e.name===n.name)}findActiveSessionForRef(e,n){let r=this.deps.resolveSession(e);if(r)return r;for(let o of this.deps.sessions.values())if(G(o)===e||O(o)===e||o.harnessSessionId===e||this.matchesExistingSession(o,n))return o}applyPatchToActiveSession(e,n){this.applyControlStatePatch(e,n),this.applySessionMetadataPatch(e,n),this.applyWorktreeMetadataPatch(e,n)}applyControlStatePatch(e,n){let r={};if(this.copyControlPatchField(r,n,"lifecycle"),this.copyControlPatchField(r,n,"approvalState"),this.copyControlPatchField(r,n,"approvalExecutionState"),this.copyControlPatchField(r,n,"worktreeState"),this.copyControlPatchField(r,n,"runtimeState"),this.copyControlPatchField(r,n,"deliveryState"),this.copyControlPatchField(r,n,"requestedPermissionMode"),this.copyControlPatchField(r,n,"currentPermissionMode"),this.copyControlPatchField(r,n,"pendingPlanApproval"),this.copyControlPatchField(r,n,"planApprovalContext"),this.copyControlPatchField(r,n,"planDecisionVersion"),this.copyControlPatchField(r,n,"actionablePlanDecisionVersion"),this.copyControlPatchField(r,n,"canonicalPlanPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptRequiredVersion"),this.copyControlPatchField(r,n,"approvalPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptStatus"),this.copyControlPatchField(r,n,"approvalPromptTransport"),this.copyControlPatchField(r,n,"approvalPromptMessageKind"),this.copyControlPatchField(r,n,"approvalPromptLastAttemptAt"),this.copyControlPatchField(r,n,"approvalPromptDeliveredAt"),this.copyControlPatchField(r,n,"approvalPromptFailedAt"),this.copyControlPatchField(r,n,"planModeApproved"),this.copyControlPatchField(r,n,"pendingWorktreeDecisionSince"),typeof e.applyControlPatch=="function"){e.applyControlPatch(r);return}this.assignIfPresent(e,"lifecycle",n,"lifecycle"),this.assignIfPresent(e,"approvalState",n,"approvalState"),this.assignIfPresent(e,"approvalExecutionState",n,"approvalExecutionState"),this.assignIfPresent(e,"worktreeState",n,"worktreeState"),this.assignIfPresent(e,"runtimeState",n,"runtimeState"),this.assignIfPresent(e,"deliveryState",n,"deliveryState"),this.assignIfPresent(e,"requestedPermissionMode",n,"requestedPermissionMode"),this.assignIfPresent(e,"currentPermissionMode",n,"currentPermissionMode"),this.assignIfPresent(e,"pendingPlanApproval",n,"pendingPlanApproval"),this.assignIfPresent(e,"planApprovalContext",n,"planApprovalContext"),this.assignIfPresent(e,"planDecisionVersion",n,"planDecisionVersion"),this.assignIfPresent(e,"actionablePlanDecisionVersion",n,"actionablePlanDecisionVersion"),this.assignIfPresent(e,"canonicalPlanPromptVersion",n,"canonicalPlanPromptVersion"),this.assignIfPresent(e,"approvalPromptRequiredVersion",n,"approvalPromptRequiredVersion"),this.assignIfPresent(e,"approvalPromptVersion",n,"approvalPromptVersion"),this.assignIfPresent(e,"approvalPromptStatus",n,"approvalPromptStatus"),this.assignIfPresent(e,"approvalPromptTransport",n,"approvalPromptTransport"),this.assignIfPresent(e,"approvalPromptMessageKind",n,"approvalPromptMessageKind"),this.assignIfPresent(e,"approvalPromptLastAttemptAt",n,"approvalPromptLastAttemptAt"),this.assignIfPresent(e,"approvalPromptDeliveredAt",n,"approvalPromptDeliveredAt"),this.assignIfPresent(e,"approvalPromptFailedAt",n,"approvalPromptFailedAt"),this.setControlFieldIfPresent(e,"planModeApproved",n)}applySessionMetadataPatch(e,n){this.assignIfDefined(e,"approvalRationale",n.approvalRationale),this.assignIfDefined(e,"taskFlowMirror",n.taskFlowMirror)}applyWorktreeMetadataPatch(e,n){this.assignIfDefined(e,"worktreePath",n.worktreePath),this.assignIfDefined(e,"worktreeBranch",n.worktreeBranch),this.assignIfDefined(e,"worktreePrUrl",n.worktreePrUrl),this.assignIfDefined(e,"worktreePrNumber",n.worktreePrNumber),this.assignIfDefined(e,"worktreeMerged",n.worktreeMerged),this.assignIfDefined(e,"worktreeMergedAt",n.worktreeMergedAt),this.assignIfDefined(e,"worktreeDisposition",n.worktreeDisposition),this.assignIfDefined(e,"worktreePrTargetRepo",n.worktreePrTargetRepo),this.assignIfDefined(e,"worktreePushRemote",n.worktreePushRemote),this.assignIfDefined(e,"worktreeLifecycle",n.worktreeLifecycle),"autoMergeParentSessionId"in n&&(e.autoMergeParentSessionId=n.autoMergeParentSessionId),"autoMergeConflictResolutionAttemptCount"in n&&(e.autoMergeConflictResolutionAttemptCount=n.autoMergeConflictResolutionAttemptCount),"autoMergeResolverSessionId"in n&&(e.autoMergeResolverSessionId=n.autoMergeResolverSessionId)}assignIfDefined(e,n,r){r!==void 0&&(e[n]=r)}assignIfPresent(e,n,r,o){Object.hasOwn(r,o)&&(e[n]=r[o])}copyControlPatchField(e,n,r){Object.hasOwn(n,r)&&(e[r]=n[r])}setControlFieldIfPresent(e,n,r){Object.hasOwn(r,n)&&e.setControlField?.(n,r[n])}};ne();var Fy=new Set(["starting","running"]),Bo=class{constructor(e,n){this.sessions=e;this.store=n}sessions;store;resolveActive(e){let n=this.sessions.get(e);return n||(this.findPreferredMatch(e,r=>r.name===e)??this.findPreferredMatch(e,r=>O(r)===e)??this.findPreferredMatch(e,r=>r.harnessSessionId===e))}getPersistedSession(e){return this.store.getPersistedSession(e)}resolveBackendConversationId(e){let n=this.resolveActive(e);return this.store.resolveBackendConversationId(e,n?O(n)??n.harnessSessionId:void 0)}findPreferredMatch(e,n){let r,o;for(let i of this.sessions.values())n(i,e)&&((!o||i.startedAt>o.startedAt)&&(o=i),Fy.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};ne();ne();Ae();import{existsSync as qy}from"fs";var Hu=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),Fo=class{constructor(e){this.deps=e}deps;async plan(e){let n=G(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=Hu.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&Hu.has(e.worktreeLifecycle.state)?e.worktreeLifecycle.state:void 0;if(r&&!(r==="pr_open"&&e.worktreeStrategy==="auto-pr"))return`${e.name}${e.worktreeLifecycle?.state??e.worktreeState}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};if(e.status!=="completed")return{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};if(!this.deps.shouldRunWorktreeStrategy(e))return`${e.name}${e.phase}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let o=e.worktreeStrategy;if(!o||o==="off"||o==="manual")return{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let i=e.worktreePath,s=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,i),a=e.worktreeBranch;if(!s)return{kind:"notify",label:"worktree-missing-repo-dir",message:`⚠️ [${e.name}] Cannot determine the original repo for worktree ${i}. Manual inspection is required.`};if(!a)return{kind:"notify",label:"worktree-no-branch-name",message:`⚠️ [${e.name}] Cannot determine branch name for worktree ${i}. The worktree may have been removed or is in detached HEAD state. Manual cleanup may be needed.`};let d=ue(e);if(d&&!qy(i))return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};let l=e.worktreeBaseBranch??Fe(s),u=this.deps.getWorktreeCompletionState(s,i,a,l);if(u==="no-change")return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};if(u==="merged")return{kind:"merged",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};if(u==="released")return{kind:"released",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d,reasons:["merge_noop_content_already_on_base"]};if(u==="base-advanced")return{kind:"notify",label:"worktree-no-commits-ahead",message:`⚠️ [${e.name}] Auto-merge: branch '${a}' has no commits ahead of '${l}', but '${l}' has new commits — commits likely landed outside the worktree branch. Verify that commits were not made directly to '${l}' instead of the worktree branch. Worktree: ${i}`};if(u==="dirty-uncommitted")return{kind:"dirty-uncommitted",worktreePath:i,branchName:a,baseBranch:l};let f=Qe(s,a,l);if(!f)return`${a}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let p=e.repoIntegrationPolicy?void 0:this.deps.resolveRepoPolicy?.(s),k=e.repoIntegrationPolicy??p?.policy,m=e.repoIntegrationPolicy?this.deps.isPrAvailable(s):p?.prAvailable??this.deps.isPrAvailable(s),c=Nl({requestedStrategy:o,policy:k,prAvailable:m,existingOpenPr:!1});return c.strategy?{kind:"decision",strategy:c.strategy,policy:k,policyReason:c.reason,policyBlocked:c.blocked,allowedActions:c.allowedActions,repoDir:s,worktreePath:i,branchName:a,baseBranch:l,diffSummary:f,sessionRef:n??void 0}:{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}}}};Wn();function ft(t){let e=[];typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)&&e.push(`$${t.costUsd.toFixed(2)}`);let n=Uy(t);n!==void 0&&e.push(Be(n));let r=ut({harness:t.harnessName??t.harness,model:t.model});return r&&e.push(...r.split(" | ")),e.length>0?` | ${e.join(" | ")}`:""}function Uy(t){if(typeof t.duration=="number"&&Number.isFinite(t.duration)&&t.duration>=0)return t.duration;if(typeof t.createdAt=="number"&&Number.isFinite(t.createdAt)&&typeof t.completedAt=="number"&&Number.isFinite(t.completedAt)&&t.completedAt>=t.createdAt)return t.completedAt-t.createdAt}function Ky(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 Vy(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function jy(){return/https?:\/\/\S+/gi}function qo(t){let e=Ky(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function Js(t){switch(t){case"user":return"Stopped by user";case"shutdown":return"Stopped by shutdown";case"startup-timeout":return"Stopped by startup timeout";case"unknown":case void 0:return"Stopped unexpectedly";default:return"Stopped"}}function Gy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function Hy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function zy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function Ys(t){let{sessionId:e,canonicalStatusDetail:n,canonicalStatusDelivered:r=!0,hasOriginRouteBlock:o=!1}=t,i=o?["7. Before sending that follow-up, honor the Session origin route block above. If originRoute differs from the current chat, do NOT use a plain final assistant reply; use a routed send path that preserves provider/target/threadId."]:[],s=o?8:7,a=o?9:8;return["[ACTION REQUIRED] Follow your autonomy rules for session completion:",`1. Use agent_output(session='${e}', full=true) to read the full result.`,"2. If this is part of a multi-phase pipeline, launch the next phase NOW — do not wait for user input.",`3. ${n??(r?"The plugin already sent the canonical completion status to the user.":"The plugin did not confirm delivery of the canonical completion status to the user.")}`,"4. Treat the completed session output as source material, not visible delivery. A meaningful final summary inside agent_output is not enough to skip, because the user may only have seen the plugin's terse status line.","5. If the visible result is only the plugin's terse status line, use the full output to send the user one short factual completion summary for this completed session. Do this even when agent_output already contains a good final summary.","6. This requirement applies to ordinary terminal/manual completions too, not just delegated worktree decisions.",...i,`${s}. That follow-up belongs to you alone; keep it brief, concrete, and grounded in reliable result data. Send at most one orchestrator-owned human summary for this terminal/worktree outcome.`,...r?[`${a}. Do NOT repeat the plugin's status line, and do NOT rely on the plugin to summarize the completed work for you.`]:[`${a}. Because canonical status delivery was not confirmed, account for that gap yourself when you follow up; do NOT assume the plugin already reached the user.`],`${a+1}. Send a normal concise final response after any routed follow-up is visibly sent. Do not use marker text, do not answer NO_REPLY, and do not ask the user whether they want the summary.`]}function Qy(t){let{contract:e,canonicalStatusDelivered:n}=t;return["Completion diagnostics:",`- Canonical completion status delivered to user: ${n?"yes":"no"}`,`- Plugin requested short factual follow-up summary: ${e.requiresShortFactualSummary?"yes":"no"}`,`- Contract applies to ordinary terminal/manual completions: ${e.appliesToOrdinaryTerminalCompletions?"yes":"no"}`]}function Zs(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=Gy(),s=a=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...qo(e),"","Output preview:",r,"",...Qy({contract:i,canonicalStatusDelivered:a}),"",...Ys({sessionId:e.id,canonicalStatusDelivered:a,hasOriginRouteBlock:o})].join(`
196
+ `);return(t??"")+o}function By(t,e){let n=t.resumeWorktreeFrom??t.resumeSessionId;if(!n)return{};let r=e(n);if(!r)return{};let o=!!r.harness||!!r.backendRef,i=(()=>{if(r.workdir&&r.workdir!==r.worktreePath)return r.workdir;if(r.worktreePath){let a=Vr(r.worktreePath);return r.workdir&&a&&No(r.workdir,a)?r.workdir:a??r.workdir}return r.workdir})();if(t.worktreeStrategy||(r.worktreeLifecycle?.state==="pr_open"||r.worktreePrUrl?t.worktreeStrategy="auto-pr":r.worktreeStrategy&&(t.worktreeStrategy=r.worktreeStrategy)),!t.planApproval&&r.planApproval&&(t.planApproval=r.planApproval),!r.worktreePath){let a=o&&Ar(Tn({persistedHarness:r.harness,backendRef:r.backendRef}));return{originalWorkdir:i,canCreateManagedWorktreeForResumeWithoutPersistedPath:a}}if(!r.worktreeBranch)throw new Error(`Cannot resume session "${n}": persisted worktree metadata is missing worktreeBranch.`);let s=Ar(Tn({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(Ey(r.worktreePath))return`${r.worktreePath}`,{actualWorkdir:r.worktreePath,originalWorkdir:i??r.worktreePath,worktreePath:r.worktreePath,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch};if(!i)return`${r.worktreePath}`,{clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom};if(s)return`${r.worktreePath}`,{actualWorkdir:i,originalWorkdir:i,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,restoredMissingNativeBackendWorktree:!0};try{zr(i);let a=ps(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:i,worktreePath:a,worktreeBranchName:r.worktreeBranch,worktreeParentBranch:r.worktreeParentBranch}}catch(a){return`${ju(a)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function Gu(t,e,n){Ny(t,n);let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,worktreeParentBranch:a,clearedResumeSessionId:d,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:u,canCreateManagedWorktreeForResumeWithoutPersistedPath:f,failedResumeWorktreeRestore:p}=By(t,n);d&&(t.resumeSessionId=void 0),l&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,o??=t.workdir;let k=!!(t.resumeSessionId??t.resumeWorktreeFrom),m=t.worktreeStrategy??D.defaultWorktreeStrategy;m&&(t.worktreeStrategy=m),!k&&m&&m!=="off"&&jr(o)&&(a??=Se(o));let c=Wy(t),S=(!k||!!f)&&!u&&!i&&m&&m!=="off"&&!c;if(p&&m&&m!=="off")throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);if(c&&!jr(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" requires a git worktree, but "${o}" is not a git repository.`);if(S&&jr(o)){if(!Qd(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=ps(o,e),r=i,s=Se(i),!s)throw new Error(`created worktree at ${i} but failed to resolve branch name`);`${i}`}catch(P){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${ju(P)}`)}}else if(S)throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" requires a git worktree, but "${o}" is not a git repository.`);if(k&&i&&(r=i),m&&m!=="off"&&!i)throw new Error(`Cannot launch session "${e}": worktree strategy "${m}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);return{actualWorkdir:r,originalWorkdir:o,effectiveSystemPrompt:i&&s?Ly(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,worktreeParentBranch:a,clearedResumeSessionId:d,clearedResumeWorktreeFrom:l,restoredMissingNativeBackendWorktree:u,failedResumeWorktreeRestore:p}}var Wo=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return Gu(e,n,this.getPersistedSession)}hydrateSpawnedSession(e,n,r){r.worktreeStrategy&&r.worktreeStrategy!=="off"&&(e.originalWorkdir=n.originalWorkdir),e.worktreeParentBranch=n.worktreeParentBranch,n.worktreePath&&(e.worktreePath=n.worktreePath,e.worktreeBranch=n.worktreeBranchName,e.worktreeState="provisioned"),r.worktreePrTargetRepo&&(e.worktreePrTargetRepo=r.worktreePrTargetRepo)}};ne();var Lo=class{constructor(e){this.deps=e}deps;applySessionPatch(e,n){let r=this.normalizeCompletionWakePatch(n),o=this.deps.store.getPersistedSession(e);o&&(Object.assign(o,r),this.deps.store.assertPersistedEntry(o));let i=this.findActiveSessionForRef(e,o);return i&&this.applyPatchToActiveSession(i,r),!o&&!i?!1:(o&&this.deps.store.saveIndex(),!0)}normalizeCompletionWakePatch(e){return"completionWakeSucceededAt"in e&&e.completionWakeSucceededAt||"completionWakeSkippedAt"in e&&e.completionWakeSkippedAt?{...e,completionWakeSummaryRequired:void 0}:e}matchesExistingSession(e,n){if(!n)return!1;let r=O(e),o=O(n);return!!(n.sessionId&&e.id===n.sessionId||o&&o===r||n?.harnessSessionId&&e.harnessSessionId===n.harnessSessionId||n?.name&&e.name===n.name)}findActiveSessionForRef(e,n){let r=this.deps.resolveSession(e);if(r)return r;for(let o of this.deps.sessions.values())if(G(o)===e||O(o)===e||o.harnessSessionId===e||this.matchesExistingSession(o,n))return o}applyPatchToActiveSession(e,n){this.applyControlStatePatch(e,n),this.applySessionMetadataPatch(e,n),this.applyWorktreeMetadataPatch(e,n)}applyControlStatePatch(e,n){let r={};if(this.copyControlPatchField(r,n,"lifecycle"),this.copyControlPatchField(r,n,"approvalState"),this.copyControlPatchField(r,n,"approvalExecutionState"),this.copyControlPatchField(r,n,"worktreeState"),this.copyControlPatchField(r,n,"runtimeState"),this.copyControlPatchField(r,n,"deliveryState"),this.copyControlPatchField(r,n,"requestedPermissionMode"),this.copyControlPatchField(r,n,"currentPermissionMode"),this.copyControlPatchField(r,n,"pendingPlanApproval"),this.copyControlPatchField(r,n,"planApprovalContext"),this.copyControlPatchField(r,n,"planDecisionVersion"),this.copyControlPatchField(r,n,"actionablePlanDecisionVersion"),this.copyControlPatchField(r,n,"canonicalPlanPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptRequiredVersion"),this.copyControlPatchField(r,n,"approvalPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptStatus"),this.copyControlPatchField(r,n,"approvalPromptTransport"),this.copyControlPatchField(r,n,"approvalPromptMessageKind"),this.copyControlPatchField(r,n,"approvalPromptLastAttemptAt"),this.copyControlPatchField(r,n,"approvalPromptDeliveredAt"),this.copyControlPatchField(r,n,"approvalPromptFailedAt"),this.copyControlPatchField(r,n,"planModeApproved"),this.copyControlPatchField(r,n,"pendingWorktreeDecisionSince"),typeof e.applyControlPatch=="function"){e.applyControlPatch(r);return}this.assignIfPresent(e,"lifecycle",n,"lifecycle"),this.assignIfPresent(e,"approvalState",n,"approvalState"),this.assignIfPresent(e,"approvalExecutionState",n,"approvalExecutionState"),this.assignIfPresent(e,"worktreeState",n,"worktreeState"),this.assignIfPresent(e,"runtimeState",n,"runtimeState"),this.assignIfPresent(e,"deliveryState",n,"deliveryState"),this.assignIfPresent(e,"requestedPermissionMode",n,"requestedPermissionMode"),this.assignIfPresent(e,"currentPermissionMode",n,"currentPermissionMode"),this.assignIfPresent(e,"pendingPlanApproval",n,"pendingPlanApproval"),this.assignIfPresent(e,"planApprovalContext",n,"planApprovalContext"),this.assignIfPresent(e,"planDecisionVersion",n,"planDecisionVersion"),this.assignIfPresent(e,"actionablePlanDecisionVersion",n,"actionablePlanDecisionVersion"),this.assignIfPresent(e,"canonicalPlanPromptVersion",n,"canonicalPlanPromptVersion"),this.assignIfPresent(e,"approvalPromptRequiredVersion",n,"approvalPromptRequiredVersion"),this.assignIfPresent(e,"approvalPromptVersion",n,"approvalPromptVersion"),this.assignIfPresent(e,"approvalPromptStatus",n,"approvalPromptStatus"),this.assignIfPresent(e,"approvalPromptTransport",n,"approvalPromptTransport"),this.assignIfPresent(e,"approvalPromptMessageKind",n,"approvalPromptMessageKind"),this.assignIfPresent(e,"approvalPromptLastAttemptAt",n,"approvalPromptLastAttemptAt"),this.assignIfPresent(e,"approvalPromptDeliveredAt",n,"approvalPromptDeliveredAt"),this.assignIfPresent(e,"approvalPromptFailedAt",n,"approvalPromptFailedAt"),this.setControlFieldIfPresent(e,"planModeApproved",n)}applySessionMetadataPatch(e,n){this.assignIfDefined(e,"approvalRationale",n.approvalRationale),this.assignIfDefined(e,"taskFlowMirror",n.taskFlowMirror)}applyWorktreeMetadataPatch(e,n){this.assignIfDefined(e,"worktreePath",n.worktreePath),this.assignIfDefined(e,"worktreeBranch",n.worktreeBranch),this.assignIfDefined(e,"worktreePrUrl",n.worktreePrUrl),this.assignIfDefined(e,"worktreePrNumber",n.worktreePrNumber),this.assignIfDefined(e,"worktreeMerged",n.worktreeMerged),this.assignIfDefined(e,"worktreeMergedAt",n.worktreeMergedAt),this.assignIfDefined(e,"worktreeDisposition",n.worktreeDisposition),this.assignIfDefined(e,"worktreePrTargetRepo",n.worktreePrTargetRepo),this.assignIfDefined(e,"worktreePushRemote",n.worktreePushRemote),this.assignIfDefined(e,"worktreeLifecycle",n.worktreeLifecycle),"autoMergeParentSessionId"in n&&(e.autoMergeParentSessionId=n.autoMergeParentSessionId),"autoMergeConflictResolutionAttemptCount"in n&&(e.autoMergeConflictResolutionAttemptCount=n.autoMergeConflictResolutionAttemptCount),"autoMergeResolverSessionId"in n&&(e.autoMergeResolverSessionId=n.autoMergeResolverSessionId)}assignIfDefined(e,n,r){r!==void 0&&(e[n]=r)}assignIfPresent(e,n,r,o){Object.hasOwn(r,o)&&(e[n]=r[o])}copyControlPatchField(e,n,r){Object.hasOwn(n,r)&&(e[r]=n[r])}setControlFieldIfPresent(e,n,r){Object.hasOwn(r,n)&&e.setControlField?.(n,r[n])}};ne();var Fy=new Set(["starting","running"]),Bo=class{constructor(e,n){this.sessions=e;this.store=n}sessions;store;resolveActive(e){let n=this.sessions.get(e);return n||(this.findPreferredMatch(e,r=>r.name===e)??this.findPreferredMatch(e,r=>O(r)===e)??this.findPreferredMatch(e,r=>r.harnessSessionId===e))}getPersistedSession(e){return this.store.getPersistedSession(e)}resolveBackendConversationId(e){let n=this.resolveActive(e);return this.store.resolveBackendConversationId(e,n?O(n)??n.harnessSessionId:void 0)}findPreferredMatch(e,n){let r,o;for(let i of this.sessions.values())n(i,e)&&((!o||i.startedAt>o.startedAt)&&(o=i),Fy.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};ne();ne();Ae();import{existsSync as qy}from"fs";var Hu=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),Fo=class{constructor(e){this.deps=e}deps;async plan(e){let n=G(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=Hu.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&Hu.has(e.worktreeLifecycle.state)?e.worktreeLifecycle.state:void 0;if(r&&!(r==="pr_open"&&e.worktreeStrategy==="auto-pr"))return`${e.name}${e.worktreeLifecycle?.state??e.worktreeState}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};if(e.status!=="completed")return{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};if(!this.deps.shouldRunWorktreeStrategy(e))return`${e.name}${e.phase}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let o=e.worktreeStrategy;if(!o||o==="off"||o==="manual")return{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let i=e.worktreePath,s=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,i),a=e.worktreeBranch;if(!s)return{kind:"notify",label:"worktree-missing-repo-dir",message:`⚠️ [${e.name}] Cannot determine the original repo for worktree ${i}. Manual inspection is required.`};if(!a)return{kind:"notify",label:"worktree-no-branch-name",message:`⚠️ [${e.name}] Cannot determine branch name for worktree ${i}. The worktree may have been removed or is in detached HEAD state. Manual cleanup may be needed.`};let d=ue(e);if(d&&!qy(i))return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};let l=e.worktreeBaseBranch??Fe(s),u=this.deps.getWorktreeCompletionState(s,i,a,l);if(u==="no-change")return{kind:"no-change",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};if(u==="merged")return{kind:"merged",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d};if(u==="released")return{kind:"released",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:d,reasons:["merge_noop_content_already_on_base"]};if(u==="base-advanced")return{kind:"notify",label:"worktree-no-commits-ahead",message:`⚠️ [${e.name}] Auto-merge: branch '${a}' has no commits ahead of '${l}', but '${l}' has new commits — commits likely landed outside the worktree branch. Verify that commits were not made directly to '${l}' instead of the worktree branch. Worktree: ${i}`};if(u==="dirty-uncommitted")return{kind:"dirty-uncommitted",worktreePath:i,branchName:a,baseBranch:l};let f=Qe(s,a,l);if(!f)return`${a}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let p=e.repoIntegrationPolicy?void 0:this.deps.resolveRepoPolicy?.(s),k=e.repoIntegrationPolicy??p?.policy,m=e.repoIntegrationPolicy?this.deps.isPrAvailable(s):p?.prAvailable??this.deps.isPrAvailable(s),c=Nl({requestedStrategy:o,policy:k,prAvailable:m,existingOpenPr:!1});return c.strategy?{kind:"decision",strategy:c.strategy,policy:k,policyReason:c.reason,policyBlocked:c.blocked,allowedActions:c.allowedActions,repoDir:s,worktreePath:i,branchName:a,baseBranch:l,diffSummary:f,sessionRef:n??void 0}:{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}}}};Wn();function ft(t){let e=[];typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)&&e.push(`$${t.costUsd.toFixed(2)}`);let n=Uy(t);n!==void 0&&e.push(Be(n));let r=ut({harness:t.harnessName??t.harness,model:t.model});return r&&e.push(...r.split(" | ")),e.length>0?` | ${e.join(" | ")}`:""}function Uy(t){if(typeof t.duration=="number"&&Number.isFinite(t.duration)&&t.duration>=0)return t.duration;if(typeof t.createdAt=="number"&&Number.isFinite(t.createdAt)&&typeof t.completedAt=="number"&&Number.isFinite(t.completedAt)&&t.completedAt>=t.createdAt)return t.completedAt-t.createdAt}function Ky(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 Vy(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function jy(){return/https?:\/\/\S+/gi}function qo(t){let e=Ky(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function Js(t){switch(t){case"user":return"Stopped by user";case"shutdown":return"Stopped by shutdown";case"startup-timeout":return"Stopped by startup timeout";case"unknown":case void 0:return"Stopped unexpectedly";default:return"Stopped"}}function Gy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function Hy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function zy(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function Ys(t){let{sessionId:e,canonicalStatusDetail:n,canonicalStatusDelivered:r=!0,hasOriginRouteBlock:o=!1}=t,i=o?["7. Before sending that follow-up, honor the Session origin route block above. If originRoute differs from the current chat, do NOT use a plain final assistant reply; use a routed send path that preserves provider/target/threadId."]:[],s=o?8:7,a=o?9:8;return["[ACTION REQUIRED] Follow your autonomy rules for session completion:",`1. Use agent_output(session='${e}', full=true) to read the full result.`,"2. If this is part of a multi-phase pipeline, launch the next phase NOW — do not wait for user input.",`3. ${n??(r?"The plugin already sent the canonical completion status to the user.":"The plugin did not confirm delivery of the canonical completion status to the user.")}`,"4. Treat the completed session output as source material, not visible delivery. A meaningful final summary inside agent_output is not enough to skip, because the user may only have seen the plugin's terse status line.","5. If the visible result is only the plugin's terse status line, use the full output to send the user one short factual completion summary for this completed session. Do this even when agent_output already contains a good final summary.","6. This requirement applies to ordinary terminal/manual completions too, not just delegated worktree decisions.",...i,`${s}. That follow-up belongs to you alone; keep it brief, concrete, and grounded in reliable result data. Send at most one orchestrator-owned human summary for this terminal/worktree outcome.`,...r?[`${a}. Do NOT repeat the plugin's status line, and do NOT rely on the plugin to summarize the completed work for you.`]:[`${a}. Because canonical status delivery was not confirmed, account for that gap yourself when you follow up; do NOT assume the plugin already reached the user.`],`${a+1}. Send a normal concise final response after any routed follow-up is visibly sent. Do not use marker text, do not answer NO_REPLY, and do not ask the user whether they want the summary.`]}function Qy(t){let{contract:e,canonicalStatusDelivered:n}=t;return["Completion diagnostics:",`- Canonical completion status delivered to user: ${n?"yes":"no"}`,`- Plugin requested short factual follow-up summary: ${e.requiresShortFactualSummary?"yes":"no"}`,`- Contract applies to ordinary terminal/manual completions: ${e.appliesToOrdinaryTerminalCompletions?"yes":"no"}`]}function Zs(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=Gy(),s=a=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...qo(e),"","Output preview:",r,"",...Qy({contract:i,canonicalStatusDelivered:a}),"",...Ys({sessionId:e.id,canonicalStatusDelivered:a,hasOriginRouteBlock:o})].join(`
197
197
  `);return{userMessage:`✅ [${e.name}] Completed${ft(e)}`,wakeMessageOnNotifySuccess:s(!0),wakeMessageOnNotifyFailed:s(!1),followupContract:i}}function an(t){let e=Hy(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>zu(i).trim()).filter(i=>i.length>0),o=zu(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(`
198
198
  `)}function Xs(t){let e=zy(),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(`
199
199
  `)}function zu(t){return t.replace(Vy(),"PR #$1").replace(jy(),"[link omitted]")}function ea(t){let{session:e,originThreadLine:n,errorSummary:r,preview:o,worktreeAutoCleaned:i,failedButtons:s}=t,a=o.trim()?["","Output preview:",o]:[],d=i?["","Note: Worktree and branch were auto-removed (zero cost, startup failure)."]:[];return{userMessage:[`❌ [${e.name}] Failed${ft(e)}`,` ⚠️ ${r}`].join(`
@@ -237,10 +237,10 @@ ${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for th
237
237
  `):`❓ [${t.sessionName}] Question waiting for reply:
238
238
 
239
239
  ${e}`}function dk(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function Qn(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(`
240
- `)}function la(t){let{session:e,preview:n,questionText:r,questionContextSummary:o,planArtifact:i,originThreadLine:s,planApprovalMode:a,planApprovalButtons:d,questionButtons:l}=t,u=e.pendingPlanApproval,f=e.actionablePlanDecisionVersion??e.planDecisionVersion,p=dk(e,f),k=a??"delegate",m=u&&k==="ask"&&!p?tc({sessionName:e.name,actionableVersion:f,preview:n,artifact:i,hasButtons:!!d}):void 0,c=u?m?.reviewSummary??da({preview:n,artifact:i}):void 0,h=u?m&&m.userMessages.length===1?m.userMessages[0]:void 0:ak({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!l}),S=u&&m&&m.userMessages.length>1?m.userMessages.map((x,T,A)=>({text:x,buttons:T===A.length-1?d:void 0})):void 0;if(u){let x=k,T="Permission mode: plan → will switch to bypassPermissions on approval";return x==="delegate"?{label:"plan-approval",userMessage:h,userMessages:S,planReviewSummary:c,wakeMessage:["[DELEGATED PLAN APPROVAL] Coding agent session has finished its plan and is requesting approval to implement.",`Name: ${e.name} | ID: ${e.id} | Plan v${f??"?"}`,s,T,"","⚠️ YOU MUST COMPLETE THESE STEPS IN ORDER. Do NOT skip any step.","","━━━ STEP 1 (MANDATORY): Read the full plan ━━━",`Call agent_output(session='${e.id}', full=true) to read the FULL plan output.`,"The preview below is truncated — you MUST read the full output before making any decision.","","Preview (truncated):",n,"","━━━ STEP 2 (MANDATORY): Review privately ━━━","You are the delegated decision-maker. Review the plan yourself before involving the user.","If you approve directly, you own the user-facing explanation of what was approved and why.","Keep it short and user-facing: one sentence is usually enough.","","━━━ STEP 3 (ONLY AFTER steps 1 and 2): Decide ━━━","Choose ONE:","","APPROVE the plan directly if ALL of the following are true:","- You have read the FULL plan (not just the preview)","- The plan scope matches the original task request","- The changes are low-risk (no destructive operations, no credential handling, no production deployments)","- The plan is clear and well-scoped (no ambiguous requirements or open design questions)","- No architectural decisions that the user should weigh in on","- The working directory and codebase are correct","","ESCALATE to the user and WAIT if ANY of the following are true:","- The plan involves destructive operations (deleting files, dropping tables, force-pushing)","- The plan involves credentials, secrets, or production environments","- The plan requires architectural decisions not covered by the original task","- The scope has expanded beyond the original request","- The requirements are ambiguous or the plan makes assumptions the user should confirm","- You are unsure — when in doubt, always escalate","",`If approving: call agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true, approval_rationale='<brief reason>').`,"That rationale should say why approval was safe: for example scope match, low risk, or no meaningful ambiguity.","After approving directly, send the user a short plain-text follow-up explaining what was approved and why.","The plugin's thumbs-up line is only the minimal approval acknowledgment, not the explanation.",`If escalating: call agent_request_plan_approval(session='${e.id}', summary='...') exactly once so the plugin posts the single canonical Approve / Revise / Reject prompt.`,"That summary must concisely explain why this was escalated, plus changed files/components, risk level and why, scope match/expansion, and any concerns or assumptions.","After the canonical prompt exists, WAIT for the user's button click or explicit response and do NOT send a second plain-text recap.",`To request changes without user escalation: call agent_respond(session='${e.id}', message='<your feedback>') and do NOT set approve=true. The agent will revise the plan.`].join(`
241
- `)}:x==="ask"?{label:"plan-approval",userMessage:h,userMessages:S,planReviewSummary:c,wakeMessage:["[USER APPROVAL REQUESTED] Coding agent session has finished its plan. The user has been notified via Telegram and must approve directly.",`Name: ${e.name} | ID: ${e.id} | Plan v${f??"?"}`,s,T,"","DO NOT approve this plan yourself. Wait for the user's explicit approval or rejection.","Once the user responds, forward their decision:",` To approve: agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true)`,` To request changes: agent_respond(session='${e.id}', message='<user feedback>')`,"","Preview (truncated):",n].join(`
240
+ `)}function la(t){let{session:e,preview:n,questionText:r,questionContextSummary:o,planArtifact:i,originThreadLine:s,planApprovalMode:a,planApprovalButtons:d,questionButtons:l}=t,u=e.pendingPlanApproval,f=e.actionablePlanDecisionVersion??e.planDecisionVersion,p=dk(e,f),k=a??"delegate",m=u&&k==="ask"&&!p?tc({sessionName:e.name,actionableVersion:f,preview:n,artifact:i,hasButtons:!!d}):void 0,c=u?m?.reviewSummary??da({preview:n,artifact:i}):void 0,h=u?m&&m.userMessages.length===1?m.userMessages[0]:void 0:ak({sessionName:e.name,questionText:r??n,contextSummary:o,hasButtons:!!l}),S=u&&m&&m.userMessages.length>1?m.userMessages.map((x,C,A)=>({text:x,buttons:C===A.length-1?d:void 0})):void 0;if(u){let x=k,C="Permission mode: plan → will switch to bypassPermissions on approval";return x==="delegate"?{label:"plan-approval",userMessage:h,userMessages:S,planReviewSummary:c,wakeMessage:["[DELEGATED PLAN APPROVAL] Coding agent session has finished its plan and is requesting approval to implement.",`Name: ${e.name} | ID: ${e.id} | Plan v${f??"?"}`,s,C,"","⚠️ 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(`
241
+ `)}:x==="ask"?{label:"plan-approval",userMessage:h,userMessages:S,planReviewSummary:c,wakeMessage:["[USER APPROVAL REQUESTED] Coding agent session has finished its plan. The user has been notified via Telegram and must approve directly.",`Name: ${e.name} | ID: ${e.id} | Plan v${f??"?"}`,s,C,"","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(`
242
242
  `),buttons:S?void 0:d}:{label:"plan-approval",userMessage:h,planReviewSummary:c,wakeMessage:["[AUTO-APPROVE] Session has a plan ready. Approve it now:",`agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true)`].join(`
243
- `)}}let b=e.multiTurn?"Multi-turn session":"Session";return{label:"waiting",userMessage:h,wakeMessage:[`[SYSTEM INSTRUCTION: Follow your auto-respond rules strictly. If this is a permission request or "should I continue?" → auto-respond. For ALL other questions → forward the agent's EXACT question to the user. Do NOT add your own analysis, commentary, or interpretation. Do NOT "nudge" or "poke" the session.]`,"",`${b} is waiting for a genuine user reply.`,`Name: ${e.name} | ID: ${e.id}`,s,"","Last output:",n,"",`Use agent_respond(session='${e.id}', message='...') to send a reply, or agent_output(session='${e.id}', full: true) to see full context before deciding.`].join(`
243
+ `)}}let P=e.multiTurn?"Multi-turn session":"Session";return{label:"waiting",userMessage:h,wakeMessage:[`[SYSTEM INSTRUCTION: Follow your auto-respond rules strictly. If this is a permission request or "should I continue?" → auto-respond. For ALL other questions → forward the agent's EXACT question to the user. Do NOT add your own analysis, commentary, or interpretation. Do NOT "nudge" or "poke" the session.]`,"",`${P} 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(`
244
244
  `),buttons:l}}yt();var Uo=3,ua=180,lk=4e3,rc=32;function oc(){let t=rt(),e=yk(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=kk(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 uk(t,e){let n=Sk(e);if(n.length>0)return n;let r=ck(t);if(r.length>0)return r;let o=[],i=t.changedFiles.slice(0,3).map(a=>`\`${a}\``);if(i.length>0){let a=t.changedFiles.length-i.length;o.push(a>0?`Touches ${i.join(", ")} and ${a} more file${a===1?"":"s"}`:`Touches ${i.join(", ")}`)}let s=[...new Set(t.commitMessages.map(a=>a.message.trim()).filter(Boolean))].slice(0,2);return s.length>0&&o.push(`Recent work: ${s.join("; ")}`),o}function ck(t){let e=new Set,n=t.commitMessages.length===1?t.changedFiles:[];return t.commitMessages.map(r=>pk(r.message,n)).filter(r=>!!r).filter(r=>{let o=r.toLowerCase();return e.has(o)?!1:(e.add(o),!0)}).slice(0,Uo)}function pk(t,e){let n=mk(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 ca(`${n}${r}.`,ua)}function mk(t){let e=Ko(Vo(t)).replace(/^(?:feat|fix|docs|style|refactor|perf|test|tests|build|ci|chore|revert)(?:\([^)]+\))?!?:\s*/i,"").replace(/\.$/,"").trim();if(!e||pa(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 ic(t){let e=fk(t),n=uk(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=gk(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 fk(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:Pk(t.prompt),stats:e?{commits:e.commits,filesChanged:e.filesChanged,insertions:e.insertions,deletions:e.deletions}:void 0,changedFiles:e?.changedFiles??[],commitSubjects:e?.commitMessages.map(n=>Ko(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:ca(Vo(t.outputPreview??""),lk)}}function gk(t){let e=hk(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>Uo)return[];let r=n.map(o=>typeof o=="string"?Ko(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>ua)?[]:r.some(pa)?[]:r}function hk(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
245
245
  `).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,Uo)}}}function yk(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 kk(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(`
246
246
  `)}function Sk(t){let e=new Set;return Vo(t??"").replace(/\r\n/g,`
@@ -255,10 +255,10 @@ ${e}`}function dk(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.a
255
255
  (Pre-existing changes on ${i} were auto-stashed and restored.)`),f=qe(f,a);let p=en(a),k=[a.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",`Auto-merge landed ${o} into ${i}.`,"Local worktree branch cleanup was requested.",...a.stashPopConflict?[`Pre-merge stash pop conflicted; run git stash show ${a.stashRef??"stash@{0}"} in ${n} to review stashed changes.`]:[],...!a.stashPopConflict&&a.stashed?[`Pre-existing changes on ${i} were auto-stashed and restored.`]:[],...p];return this.deps.dispatchSessionNotification(e,{label:"worktree-merge-success",idempotencyKey:`worktree-merge-success:${e.id}:${o}:${i}:${De(e)}`,userMessage:f,notifyUser:"always",completionSummary:{required:!0,producer:"worktree",outcomeKey:`worktree-merge:${e.id}:${o}:${i}:${De(e)}`},completionWakeSummaryRequired:!0,completionWakeOutcomeKey:`worktree-merge:${e.id}:${o}:${i}:${De(e)}`,deferConditionalWakeUntilNextTick:!0,wakeMessageOnNotifySuccess:an({sessionId:e.id,sessionName:e.name,outcomeLine:u,originThreadLine:this.deps.originThreadLine(e),detailLines:k,canonicalStatusDelivered:!0}),wakeMessageOnNotifyFailed:an({sessionId:e.id,sessionName:e.name,outcomeLine:u,originThreadLine:this.deps.originThreadLine(e),detailLines:k,canonicalStatusDelivered:!1})}),l}async handleInitialAutoMergeConflict(e,n,r,o,i,s,a,d){let l=d?en(d):[],u=e.autoMergeConflictResolutionAttemptCount??0;if(u>=1){this.markPendingDecision(e,{notes:["auto_merge_conflict_retry_exhausted"],clearResolverSessionId:!0}),this.notifyAutoMergeConflictEscalation(e,o,s.pr?`The rebased branch still conflicts with \`${i}\`. Open a PR or resolve manually in ${r}.`:`The rebased branch still conflicts with \`${i}\`. Resolve manually in ${r}.`,s,l);return}let f=this.buildConflictResolverPrompt({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,mergeError:a});try{let p=await this.deps.spawnConflictResolver({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,prompt:f});this.markAutoMergeConflictResolving(e,p.id,u+1),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-resolving",idempotencyKey:`worktree-merge-conflict-resolving:${e.id}:${o}:${p.id}`,userMessage:[`⚠️ [${e.name}] Auto-merge hit a rebase conflict. Started resolver session ${p.name} and will retry automatically if it succeeds.`,...l.map(k=>`⚠️ ${k}`)].join(`
256
256
  `)})}catch(p){this.markPendingDecision(e,{notes:["auto_merge_conflict_resolver_spawn_failed"]}),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-spawn-failed",idempotencyKey:`worktree-merge-conflict-spawn-failed:${e.id}:${o}:${De(e)}`,userMessage:[`❌ [${e.name}] Auto-merge hit a rebase conflict and failed to start the resolver: ${p instanceof Error?p.message:String(p)}`,...l.map(k=>`⚠️ ${k}`)].join(`
257
257
  `),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}:${De(e)}`,userMessage:[o,"","Auto-merge retry did not complete after conflict resolution.",`Branch \`${n}\` was preserved for manual follow-up in ${r}.`].join(`
258
- `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i,{},[[this.deps.makeOpenPrButton(e.id)]])})}async handleAutoMergeStrategy(e,n,r,o,i,s,a=G(e)??e.harnessSessionId,d={merge:!0,pr:!0}){if(this.deps.isAlreadyMerged(a)||e.autoMergeResolverSessionId)return!1;let l=!1;return await this.deps.enqueueMerge(n,async()=>{if(this.deps.isAlreadyMerged(a))return;let u=this.deps.mergeBranch(n,o,i,"merge",r);if(u.success){l=this.handleAutoMergeSuccess(e,n,r,o,i,s,u);return}if(u.rebaseConflict){await this.handleInitialAutoMergeConflict(e,n,r,o,i,d,u.error,u);return}let f=qe(u.dirtyError?`❌ [${e.name}] Merge blocked: ${u.error}`:`❌ [${e.name}] Merge failed: ${u.error??"unknown error"}`,u);if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,o,r,f,d);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${o}:${De(e)}`,userMessage:f})},()=>{this.deps.dispatchSessionNotification(e,{label:"worktree-merge-queued",idempotencyKey:`worktree-merge-queued:${e.id}:${o}:${De(e)}`,userMessage:`🕐 [${e.name}] Merge queued — another merge for this repo is in progress. Will notify when complete.`})}),l}async handleAutoPrStrategy(e,n,r,o,i,s={merge:!0,pr:!0}){let a=this.releaseIfRepresentedByTargetPrBranch(e,n,r,o,i);if(a)return a;if(this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_in_progress"}),!(await this.deps.runAutoPr(e,i)).success){let l=this.releaseIfRepresentedByTargetPrBranch(e,n,r,o,i);if(l)return l;this.markPendingDecision(e),this.deps.dispatchSessionNotification(e,{label:"worktree-auto-pr-failed",idempotencyKey:`worktree-auto-pr-failed:${e.id}:${i}:${De(e)}`,userMessage:`⚠️ [${e.name}] Auto-PR did not complete. The worktree is preserved for an explicit merge or PR decision.`,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,s)})}return{notificationSent:!0,worktreeRemoved:!1}}getPrStatusForUrl(e,n,r){return this.deps.getPrStatusForUrl?.(e,n,r)??Ye(e,n,r)}releaseIfRepresentedByTargetPrBranch(e,n,r,o,i){if(bt(r).length>0)return;let s=this.resolveExistingTargetPr(e,n,o,i),a=s?.headRefName;if(!a||a===o||a===i)return;let d=this.deps.fetchRemoteBranch?this.deps.fetchRemoteBranch(n,a):Gr(n,a);if(!d||!!!((s?.state==="open"||s?.state==="merged")&&s?.baseRefName===i&&ve(n,o,d)))return;let u=ue(e)?!0:pe(n,r);return u?(e.worktreePath=void 0,e.worktreePrUrl=s.url,e.worktreePrNumber=s.number,e.worktreePrTargetRepo=_n(n,e.worktreePrTargetRepo),this.updatePersistedSessionFor(e,{worktreePath:void 0,worktreePrUrl:s.url,worktreePrNumber:s.number,worktreePrTargetRepo:e.worktreePrTargetRepo,worktreeRemoteOutcome:"pr-updated"}),be(n,o),this.markReleased(e,[`released_by_branch:${a}`]),{notificationSent:!1,worktreeRemoved:u}):(this.markPendingDecision(e,{notes:[`represented_by_branch:${a}`,"represented_worktree_cleanup_failed"]}),{notificationSent:!1,worktreeRemoved:!1})}};import{existsSync as dS,statSync as lS,writeFileSync as uS}from"fs";ke();import{randomUUID as bk}from"crypto";function Rk(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var Go=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:bk(),sessionId:e,kind:n,createdAt:Date.now(),...r};return this.tokens.set(o.id,o),this.notifyChanged(),o}getActionToken(e){let n=this.tokens.get(e);if(n){if(n.expiresAt!=null&&n.expiresAt<=Date.now()){this.tokens.delete(e),this.notifyChanged();return}return n}}listActiveActionTokens(e){let n=[];for(let r of[...this.tokens.keys()]){let o=this.getActionToken(r);!o||o.consumedAt!=null||e&&o.kind!==e||n.push(o)}return n}consumeActionToken(e){let n=this.getActionToken(e);if(!(!n||n.consumedAt!=null))return n.consumedAt=Date.now(),this.notifyChanged(),n}consumeQuestionAnswerTokens(e,n){let r=[],o=Date.now();for(let i of this.tokens.values())i.sessionId!==e||i.kind!=="question-answer"||i.pendingInputRequestId!==n||i.consumedAt!=null||(i.consumedAt=o,r.push(i));return r.length>0&&this.notifyChanged(),r}deleteActionTokensForSession(e){let n=!1;for(let[r,o]of this.tokens)o.sessionId===e&&(this.tokens.delete(r),n=!0);n&&this.notifyChanged()}deleteActionTokensForSessionByKind(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId===e&&i.kind===n&&(this.tokens.delete(o),r=!0);r&&this.notifyChanged()}deletePlanDecisionTokensForSession(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId!==e||!Rk(i.kind)||n!=null&&i.planDecisionVersion===n||(this.tokens.delete(o),r=!0);r&&this.notifyChanged()}purgeExpiredActionTokens(e=Date.now()){let n=!1;for(let[r,o]of this.tokens){let i=o.expiresAt!=null&&o.expiresAt<=e,s=o.consumedAt!=null&&e-o.consumedAt>=this.retentionMs;(i||s)&&(this.tokens.delete(r),n=!0)}return n&&this.notifyChanged(),n}nextExpiryAt(){let e;for(let n of this.tokens.values()){let r=[n.expiresAt,n.consumedAt!=null?n.consumedAt+this.retentionMs:void 0].filter(o=>o!=null&&Number.isFinite(o));for(let o of r)(e==null||o<e)&&(e=o)}return e}setAfterChangeListener(e){this.afterChange=e}notifyChanged(){this.onChange(),this.afterChange?.()}};ne();ne();var Ho=class{constructor(e){this.indexes=e}indexes;hasRecordedSession(e){return this.indexes.idIndex.has(e)}getLatestPersistedByName(e){let n,r=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,s=0;for(let a of this.indexes.persisted.values()){if(a.name!==e){s++;continue}let d=a.createdAt??Number.NEGATIVE_INFINITY,l=a.completedAt??Number.NEGATIVE_INFINITY;(d>r||d===r&&l>o||d===r&&l===o&&s>i)&&(n=a,r=d,o=l,i=s),s++}return n}resolveBackendConversationId(e,n){if(n)return n;let r=this.indexes.idIndex.get(e);if(r){let s=this.indexes.persisted.get(r);return(s?O(s):void 0)??r}let o=this.getLatestPersistedByName(e);if(o)return O(o)??o.harnessSessionId;let i=this.indexes.backendIdIndex.get(e);if(i){let s=this.indexes.persisted.get(i);return(s?O(s):void 0)??i}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?O(s)??e:e}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e))return e}resolveHarnessSessionId(e,n){return this.resolveBackendConversationId(e,n)}getPersistedSession(e){let n=this.indexes.idIndex.get(e);if(n)return this.indexes.persisted.get(n);let r=this.getLatestPersistedByName(e);if(r)return r;let o=this.indexes.backendIdIndex.get(e);return o?this.indexes.persisted.get(o):this.indexes.persisted.get(e)}listPersistedSessions(){return[...this.indexes.persisted.values()].sort((e,n)=>(n.completedAt??0)-(e.completedAt??0))}};import{existsSync as hc,mkdirSync as Zk,readFileSync as Xk,readdirSync as eS,renameSync as yc,statSync as kc,unlinkSync as Sc,writeFileSync as vc}from"fs";import{tmpdir as tS}from"os";import{dirname as nS,join as wc}from"path";import{homedir as Ak}from"node:os";import{join as Ik}from"node:path";function zo(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||Ak();return Ik(n,".openclaw")}ke();var Qo=7,xk=new Set(["running","completed","failed","killed"]),Tk=new Set(["queued","running","waiting","blocked","succeeded","failed","cancelled","lost"]);function Ke(t){return!!t&&typeof t=="object"}function dn(t,e=""){return typeof t=="string"&&t.trim().length>0?t:e}function P(t){return typeof t=="string"&&t.trim().length>0?t:void 0}function me(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function Ck(t){if(!Ke(t))return;let e=P(t.flowId),n=me(t.revision);if(!e||n===void 0)return;let r=typeof t.status=="string"&&Tk.has(t.status)?t.status:void 0;return{flowId:e,revision:n,...r?{status:r}:{}}}function sc(t){return typeof t=="string"&&Ml.has(t)?t:void 0}function ma(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function Mk(t){return t==="never"||t==="on-request"?"never":void 0}function ac(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function _k(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function dc(t){return typeof t=="string"&&so.has(t)?t:void 0}function fa(t){return typeof t=="string"&&Cl.has(t)?t:void 0}function lc(t){return t==="github"||t==="unsupported"?t:void 0}function $k(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function Ek(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function uc(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 Dk(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function Ok(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 Nk(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 cc(t){return t==="live"||t==="stopped"?t:void 0}function Wk(t){if(!Ke(t)||t.reason!=="persisted-running-without-runtime")return;let e=P(t.recoveredAt);if(!e||!Number.isFinite(Date.parse(e)))return;let n=t.normalizedStatus==="killed"?"killed":void 0;if(n)return{reason:"persisted-running-without-runtime",recoveredAt:e,rawStatus:P(t.rawStatus),rawLifecycle:P(t.rawLifecycle),rawRuntimeState:P(t.rawRuntimeState),rawResumable:typeof t.rawResumable=="boolean"?t.rawResumable:void 0,rawCompletedAt:me(t.rawCompletedAt),rawOutputPath:P(t.rawOutputPath),normalizedStatus:n,normalizedLifecycle:uc(t.normalizedLifecycle),normalizedRuntimeState:cc(t.normalizedRuntimeState)}}function Lk(t){return{reason:"persisted-running-without-runtime",recoveredAt:new Date().toISOString(),rawStatus:P(t.status),rawLifecycle:P(t.lifecycle),rawRuntimeState:P(t.runtimeState),rawResumable:typeof t.resumable=="boolean"?t.resumable:void 0,rawCompletedAt:me(t.completedAt),rawOutputPath:P(t.outputPath),normalizedStatus:"killed",normalizedLifecycle:"suspended",normalizedRuntimeState:"stopped"}}function Bk(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function Fk(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function qk(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function Uk(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function Kk(t){return t==="in_flight"||t==="delivered"?t:void 0}function Vk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ke(n))return;let r=P(n.key),o=Kk(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 jk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ke(n))return;let r=P(n.key),o=P(n.recordedAt);if(!r||!o||!Number.isFinite(Date.parse(o)))return;let i=Array.isArray(n.linkedKeys)?[...new Set(n.linkedKeys.map(P).filter(s=>!!(s&&s!==r)))]:void 0;return{key:r,linkedKeys:i&&i.length>0?i:void 0,recordedAt:o,label:P(n.label),skipReason:P(n.skipReason)}}).filter(n=>!!n);return e.length>0?e.slice(-1024):void 0}function Gk(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 Hk(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 pc(t){if(!Ke(t))return;let e=P(t.provider),n=P(t.accountId),r=P(t.target),o=P(t.threadId),i=P(t.sessionKey);if(!(!e||!r))return{provider:e,accountId:n,target:r,threadId:o,sessionKey:i}}function zk(t,e,n){if(Ke(t)){let r=P(t.kind),o=P(t.conversationId);if(o&&(r==="claude-code"||r==="codex-app-server"||r==="opencode-server"))return{kind:r,conversationId:o,runId:P(t.runId),worktreeId:P(t.worktreeId),worktreePath:P(t.worktreePath)}}if(e==="claude-code")return{kind:"claude-code",conversationId:n}}function Qk(t){if(!Ke(t))return;let e=Nk(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 Jk(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 Yk(t){if(typeof t=="string"&&xk.has(t))return t==="running"?"killed":t}function mc(t){if(!Ke(t))return;let e=dn(t.harnessSessionId);if(!e)return;let n=Yk(t.status);if(!n)return;let r=t.status==="running",o=P(t.worktreePath),i=P(t.worktreeBranch),s=P(t.originChannel),a=typeof t.originThreadId=="string"||typeof t.originThreadId=="number"?t.originThreadId:void 0,d=P(t.originSessionKey),l=pc(t.route);if(!l)return;let u=Ne({route:l,originChannel:s,originThreadId:a,originSessionKey:d});if(!u||o&&!i)return;let f=P(t.harness),p=zk(t.backendRef,f,e),k=Qk(t.worktreeLifecycle)??Jk(t),m=P(t.completionWakeSucceededAt),c=P(t.completionWakeSkippedAt),h=t.completionWakeSummaryRequired===!0&&!c?!0:void 0;return{sessionId:P(t.sessionId),harnessSessionId:e,backendRef:p,name:dn(t.name,e),prompt:dn(t.prompt),workdir:dn(t.workdir,"(unknown)"),model:P(t.model),reasoningEffort:sc(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:me(t.createdAt),completedAt:me(t.completedAt),status:n,lifecycle:r?"suspended":uc(t.lifecycle),approvalState:Dk(t.approvalState),worktreeState:Ok(t.worktreeState),runtimeState:r?"stopped":cc(t.runtimeState),runtimeRecovery:r?Lk(t):Wk(t.runtimeRecovery),taskFlowMirror:Ck(t.taskFlowMirror),deliveryState:Uk(t.deliveryState),notificationDedupe:Vk(t.notificationDedupe),completionSummaryDedupe:jk(t.completionSummaryDedupe),completionWakeIssuedAt:P(t.completionWakeIssuedAt),completionWakeSucceededAt:m,completionWakeFailedAt:P(t.completionWakeFailedAt),completionWakeSkippedAt:c,completionWakeSkipReason:P(t.completionWakeSkipReason),completionWakeSummaryRequired:h,killReason:Ek(t.killReason),costUsd:typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)?t.costUsd:0,originAgentId:P(t.originAgentId),originChannel:s,originThreadId:a,originSessionKey:d,route:u,outputPath:P(t.outputPath),harness:f,resumedFromSessionName:P(t.resumedFromSessionName),goalTaskId:P(t.goalTaskId),requestedPermissionMode:ma(t.requestedPermissionMode),currentPermissionMode:ma(t.currentPermissionMode),approvalExecutionState:Gk(t.approvalExecutionState),approvalRationale:P(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:_k(t.planApprovalContext),planDecisionVersion:me(t.planDecisionVersion),actionablePlanDecisionVersion:me(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:me(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:me(t.approvalPromptRequiredVersion),approvalPromptVersion:me(t.approvalPromptVersion),approvalPromptStatus:Bk(t.approvalPromptStatus),approvalPromptTransport:Fk(t.approvalPromptTransport),approvalPromptMessageKind:qk(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:P(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:P(t.approvalPromptDeliveredAt),approvalPromptFailedAt:P(t.approvalPromptFailedAt),planApproval:ac(t.planApproval),codexApprovalPolicy:Mk(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:dc(t.worktreeStrategy),repoIntegrationPolicy:fa(t.repoIntegrationPolicy),repoIntegrationPolicySource:$k(t.repoIntegrationPolicySource),repoProvider:lc(t.repoProvider),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:P(t.worktreeMergedAt),worktreePrUrl:P(t.worktreePrUrl),worktreePrNumber:me(t.worktreePrNumber),pendingWorktreeDecisionSince:P(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:P(t.lastWorktreeReminderAt),worktreeBaseBranch:P(t.worktreeBaseBranch),worktreeParentBranch:P(t.worktreeParentBranch),worktreePrTargetRepo:P(t.worktreePrTargetRepo),autoMergeParentSessionId:P(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:me(t.autoMergeConflictResolutionAttemptCount),autoMergeResolverSessionId:P(t.autoMergeResolverSessionId),worktreePushRemote:P(t.worktreePushRemote),worktreeDecisionSnoozedUntil:P(t.worktreeDecisionSnoozedUntil),worktreeDisposition:t.worktreeDisposition==="active"||t.worktreeDisposition==="pr-opened"||t.worktreeDisposition==="merged"||t.worktreeDisposition==="dismissed"||t.worktreeDisposition==="no-change-cleaned"?t.worktreeDisposition:void 0,worktreeRemoteOutcome:t.worktreeRemoteOutcome==="pr-opened"||t.worktreeRemoteOutcome==="pr-updated"?t.worktreeRemoteOutcome:void 0,worktreeDismissedAt:P(t.worktreeDismissedAt),worktreeLifecycle:k,resumable:r?!0:t.resumable===!0}}function fc(t){if(!Ke(t))return;let e=P(t.key),n=P(t.repoRoot),r=fa(t.policy),o=lc(t.provider)??"unsupported",i=P(t.createdAt),s=P(t.updatedAt),a=t.source==="seeded"?"seeded":"stored";if(!(!e||!n||!r||!i||!s)&&!(!Number.isFinite(Date.parse(i))||!Number.isFinite(Date.parse(s))))return{key:e,policy:r,repoRoot:n,remoteUrl:P(t.remoteUrl),provider:o,createdAt:i,updatedAt:s,source:a}}function gc(t){if(!Ke(t))return;let e=Hk(t.kind),n=dn(t.id),r=dn(t.sessionId),o=me(t.createdAt);if(!(!n||!r||!e||o==null))return{id:n,sessionId:r,kind:e,createdAt:o,planDecisionVersion:me(t.planDecisionVersion),expiresAt:me(t.expiresAt),consumedAt:me(t.consumedAt),optionIndex:me(t.optionIndex),pendingInputRequestId:P(t.pendingInputRequestId),pendingInputQuestionId:P(t.pendingInputQuestionId),label:P(t.label),targetUrl:P(t.targetUrl),route:pc(t.route),launchName:P(t.launchName),launchPrompt:P(t.launchPrompt),launchWorkdir:P(t.launchWorkdir),launchModel:P(t.launchModel),launchReasoningEffort:sc(t.launchReasoningEffort),launchFastMode:t.launchFastMode===!0?!0:void 0,launchSystemPrompt:P(t.launchSystemPrompt),launchAllowedTools:Array.isArray(t.launchAllowedTools)?t.launchAllowedTools.filter(i=>typeof i=="string"):void 0,launchResumeSessionId:P(t.launchResumeSessionId),launchResumedFromSessionName:P(t.launchResumedFromSessionName),launchResumeWorktreeFrom:P(t.launchResumeWorktreeFrom),launchSessionIdOverride:P(t.launchSessionIdOverride),launchClearedPersistedCodexResume:t.launchClearedPersistedCodexResume===!0?!0:void 0,launchForkSession:typeof t.launchForkSession=="boolean"?t.launchForkSession:void 0,launchForceNewSession:typeof t.launchForceNewSession=="boolean"?t.launchForceNewSession:void 0,launchPermissionMode:ma(t.launchPermissionMode),launchPlanApproval:ac(t.launchPlanApproval),launchHarness:P(t.launchHarness),launchWorktreeStrategy:dc(t.launchWorktreeStrategy),launchWorktreeBaseBranch:P(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:P(t.launchWorktreePrTargetRepo),launchOriginAgentId:P(t.launchOriginAgentId),repoPolicy:fa(t.repoPolicy),repoPolicyWorkdir:P(t.repoPolicyWorkdir)}}function Jo(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 Jn(t){return!!t&&typeof t=="object"}function ga(t){return t instanceof Error?t.message:String(t)}function rS(t,e){JSON.stringify({component:"SessionStore",event:t,at:new Date().toISOString(),...e})}function oS(t){return Jn(t)?{backendRefKind:typeof t.kind=="string"?t.kind:void 0,hasBackendConversationId:typeof t.conversationId=="string"&&t.conversationId.length>0,hasBackendRunId:typeof t.runId=="string"&&t.runId.length>0,hasBackendWorktreeId:typeof t.worktreeId=="string"&&t.worktreeId.length>0,hasBackendWorktreePath:typeof t.worktreePath=="string"&&t.worktreePath.length>0}:{}}function Pc(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(!hc(s))return s}}function ha(){let t=tS();return eS(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>wc(t,e))}function bc(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||wc(zo(t),"code-agent-sessions.json")}function Rc(t,e,n,r=[]){try{Zk(nS(t),{recursive:!0});let o=t+".tmp";vc(o,JSON.stringify({schemaVersion:Qo,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),yc(o,t)}catch(o){`${ga(o)}`}}function iS(t,e){try{if(!hc(t))return!1;let n=Pc(t,"legacy");return n?(yc(t,n),`${e}${n}`,!0):!1}catch(n){return`${ga(n)}`,!1}}var sS={archiveLegacySessionIndex:iS};function aS(t,e){try{if(e.length===0)return;let n=Pc(t,"codex-sdk-legacy");if(!n)return;vc(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${ga(n)}`}}function Ac(t,e,n=[]){try{let r=new Set(n);for(let o of ha())if(!r.has(o))try{let i=kc(o).mtimeMs;t-i>e&&Sc(o)}catch{}}catch{}}function Ic(t,e,n=[]){try{let r=new Set(n),o;for(let i of ha())if(!r.has(i))try{let s=kc(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function xc(t){try{let e=new Set(t);for(let n of ha())if(!e.has(n))try{Sc(n)}catch{}}catch{}}function Tc(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:a}=t,d=l=>sS.archiveLegacySessionIndex(e,l)?(n(),!0):!1;try{let l=Xk(e,"utf-8"),u=JSON.parse(l);if(Array.isArray(u)){if(!d("legacy array store"))return;a();return}if(!Jn(u)||u.schemaVersion!==Qo&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!d(`schema mismatch (expected v${Qo})`))return;a();return}let f=(A,y)=>{if(!Object.prototype.hasOwnProperty.call(u,A))return[];let w=u[A];if(Array.isArray(w))return w;d(y)&&a()},p=f("sessions","invalid sessions collection");if(p===void 0)return;let k=[],m=[],c=!1;for(let A of p){if(Jn(A)&&A.harness==="codex"){let w=Jn(A.backendRef)?A.backendRef:void 0;if((typeof w?.kind=="string"?w.kind:void 0)!=="codex-app-server"){k.push(A);continue}}let y=mc(A);if(!y){if(!d("invalid v4 session entry"))return;a();return}Jn(A)&&A.status==="running"&&(c=!0,rS("session.recovered_from_running_persisted_row",{sessionId:typeof A.sessionId=="string"?A.sessionId:void 0,hasHarnessSessionId:typeof A.harnessSessionId=="string"&&A.harnessSessionId.length>0,...oS(A.backendRef),rawStatus:A.status,rawLifecycle:A.lifecycle,rawRuntimeState:A.runtimeState,normalizedStatus:y.status,normalizedLifecycle:y.lifecycle,normalizedRuntimeState:y.runtimeState,reason:y.runtimeRecovery?.reason})),m.push(y)}k.length>0&&aS(e,k);let h=f("actionTokens","invalid action token collection");if(h===void 0)return;let S=[];for(let A of h){let y=gc(A);if(!y){if(!d("invalid v4 action token"))return;a();return}S.push(y)}let b=f("repoPolicies","invalid repo policy collection");if(b===void 0)return;let x=[],T=!1;for(let A of b){let y=fc(A);if(!y){T=!0;continue}x.push(y)}for(let A of m)r(A);for(let A of S)o(A);for(let A of x)i(A);(k.length>0||c)&&a(),T&&a(),s()}catch(l){if(l.code==="ENOENT"||!d("corrupt or unreadable"))return;a()}}var cS=new Set(["completed","failed","killed"]),ya=1440*60*1e3;function pS(t){return t instanceof Error?t.message:String(t)}var mS={statSync:lS};function fS(t){try{return mS.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var Yo=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??bc(n),this.actionTokenStore=new Go(()=>this.saveIndex(),ya),this.actionTokens=this.actionTokenStore.tokens,this.queries=new Ho({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Tc({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(){Rc(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){Jo(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=os(e),r=n==="codex"?"codex-app-server":n==="opencode"?"opencode-server":"claude-code";return e.backendRef??{kind:e.backendKind??r,conversationId:e.harnessSessionId}}getSessionApprovalSnapshot(e){if(typeof e.approvalSnapshot=="function")return e.approvalSnapshot();let n=typeof e.controlStateSnapshot=="function"?e.controlStateSnapshot():{planModeApproved:!1};return{requestedPermissionMode:e.requestedPermissionMode,currentPermissionMode:e.currentPermissionMode,approvalExecutionState:e.approvalExecutionState,approvalRationale:e.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy}}getSessionRoutingSnapshot(e){return typeof e.routingSnapshot=="function"?e.routingSnapshot():{route:e.route,originAgentId:e.originAgentId,originChannel:e.originChannel,originThreadId:e.originThreadId,originSessionKey:e.originSessionKey}}getSessionWorktreeSnapshot(e){return typeof e.worktreeSnapshot=="function"?e.worktreeSnapshot():{worktreePath:e.worktreePath,worktreeBranch:e.worktreeBranch,worktreeStrategy:e.worktreeStrategy,repoIntegrationPolicy:e.repoIntegrationPolicy,repoIntegrationPolicySource:e.repoIntegrationPolicySource,repoProvider:e.repoProvider,worktreeBaseBranch:e.worktreeBaseBranch,worktreeParentBranch:e.worktreeParentBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,autoMergeParentSessionId:e.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:e.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:e.autoMergeResolverSessionId,worktreeLifecycle:e.worktreeLifecycle}}indexPersistedEntry(e){let n=this.getEntryStorageKey(e);this.persisted.set(n,e),e.sessionId&&this.idIndex.set(e.sessionId,n),e.name&&this.nameIndex.set(e.name,n);let r=O(e);r&&this.backendIdIndex.set(r,n)}removePersistedIndexes(e){let n=this.getEntryStorageKey(e);this.persisted.delete(n);for(let[r,o]of this.idIndex)o===n&&this.idIndex.delete(r);for(let[r,o]of this.nameIndex)o===n&&this.nameIndex.delete(r);for(let[r,o]of this.backendIdIndex)o===n&&this.backendIdIndex.delete(r)}markRunning(e){if(!e.harnessSessionId)return;let n=this.getSessionApprovalSnapshot(e),r=this.getSessionRoutingSnapshot(e),o=this.getSessionWorktreeSnapshot(e),i=Ne({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,status:"running",lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,taskFlowMirror:e.taskFlowMirror,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),costUsd:0,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:wt(e.id),harness:e.harnessName,resumedFromSessionName:e.resumedFromSessionName,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalRationale:n.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planApproval:n.planApproval,codexApprovalPolicy:n.codexApprovalPolicy,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,repoIntegrationPolicy:o.repoIntegrationPolicy,repoIntegrationPolicySource:o.repoIntegrationPolicySource,repoProvider:o.repoProvider,worktreeBaseBranch:o.worktreeBaseBranch,worktreeParentBranch:o.worktreeParentBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Jo(s),this.indexPersistedEntry(s),this.saveIndex()}hasRecordedSession(e){return this.queries.hasRecordedSession(e)}persistTerminal(e){if(!e.harnessSessionId)return;let n=this.getSessionApprovalSnapshot(e),r=this.getSessionRoutingSnapshot(e),o=this.getSessionWorktreeSnapshot(e),i=Ne({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let d=wt(e.id);if(dS(d))s=d;else{let l=e.getOutput().join(`
258
+ `),buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,i,{},[[this.deps.makeOpenPrButton(e.id)]])})}async handleAutoMergeStrategy(e,n,r,o,i,s,a=G(e)??e.harnessSessionId,d={merge:!0,pr:!0}){if(this.deps.isAlreadyMerged(a)||e.autoMergeResolverSessionId)return!1;let l=!1;return await this.deps.enqueueMerge(n,async()=>{if(this.deps.isAlreadyMerged(a))return;let u=this.deps.mergeBranch(n,o,i,"merge",r);if(u.success){l=this.handleAutoMergeSuccess(e,n,r,o,i,s,u);return}if(u.rebaseConflict){await this.handleInitialAutoMergeConflict(e,n,r,o,i,d,u.error,u);return}let f=qe(u.dirtyError?`❌ [${e.name}] Merge blocked: ${u.error}`:`❌ [${e.name}] Merge failed: ${u.error??"unknown error"}`,u);if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,o,r,f,d);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${o}:${De(e)}`,userMessage:f})},()=>{this.deps.dispatchSessionNotification(e,{label:"worktree-merge-queued",idempotencyKey:`worktree-merge-queued:${e.id}:${o}:${De(e)}`,userMessage:`🕐 [${e.name}] Merge queued — another merge for this repo is in progress. Will notify when complete.`})}),l}async handleAutoPrStrategy(e,n,r,o,i,s={merge:!0,pr:!0}){let a=this.releaseIfRepresentedByTargetPrBranch(e,n,r,o,i);if(a)return a;if(this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_in_progress"}),!(await this.deps.runAutoPr(e,i)).success){let l=this.releaseIfRepresentedByTargetPrBranch(e,n,r,o,i);if(l)return l;this.markPendingDecision(e),this.deps.dispatchSessionNotification(e,{label:"worktree-auto-pr-failed",idempotencyKey:`worktree-auto-pr-failed:${e.id}:${i}:${De(e)}`,userMessage:`⚠️ [${e.name}] Auto-PR did not complete. The worktree is preserved for an explicit merge or PR decision.`,buttons:this.getPolicyAwareWorktreeDecisionButtons(e.id,s)})}return{notificationSent:!0,worktreeRemoved:!1}}getPrStatusForUrl(e,n,r){return this.deps.getPrStatusForUrl?.(e,n,r)??Ye(e,n,r)}releaseIfRepresentedByTargetPrBranch(e,n,r,o,i){if(bt(r).length>0)return;let s=this.resolveExistingTargetPr(e,n,o,i),a=s?.headRefName;if(!a||a===o||a===i)return;let d=this.deps.fetchRemoteBranch?this.deps.fetchRemoteBranch(n,a):Gr(n,a);if(!d||!!!((s?.state==="open"||s?.state==="merged")&&s?.baseRefName===i&&ve(n,o,d)))return;let u=ue(e)?!0:pe(n,r);return u?(e.worktreePath=void 0,e.worktreePrUrl=s.url,e.worktreePrNumber=s.number,e.worktreePrTargetRepo=_n(n,e.worktreePrTargetRepo),this.updatePersistedSessionFor(e,{worktreePath:void 0,worktreePrUrl:s.url,worktreePrNumber:s.number,worktreePrTargetRepo:e.worktreePrTargetRepo,worktreeRemoteOutcome:"pr-updated"}),be(n,o),this.markReleased(e,[`released_by_branch:${a}`]),{notificationSent:!1,worktreeRemoved:u}):(this.markPendingDecision(e,{notes:[`represented_by_branch:${a}`,"represented_worktree_cleanup_failed"]}),{notificationSent:!1,worktreeRemoved:!1})}};import{existsSync as dS,statSync as lS,writeFileSync as uS}from"fs";ke();import{randomUUID as bk}from"crypto";function Rk(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var Go=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:bk(),sessionId:e,kind:n,createdAt:Date.now(),...r};return this.tokens.set(o.id,o),this.notifyChanged(),o}getActionToken(e){let n=this.tokens.get(e);if(n){if(n.expiresAt!=null&&n.expiresAt<=Date.now()){this.tokens.delete(e),this.notifyChanged();return}return n}}listActiveActionTokens(e){let n=[];for(let r of[...this.tokens.keys()]){let o=this.getActionToken(r);!o||o.consumedAt!=null||e&&o.kind!==e||n.push(o)}return n}consumeActionToken(e){let n=this.getActionToken(e);if(!(!n||n.consumedAt!=null))return n.consumedAt=Date.now(),this.notifyChanged(),n}consumeQuestionAnswerTokens(e,n,r){let o=[],i=Date.now();for(let s of this.tokens.values())s.sessionId!==e||s.kind!=="question-answer"||s.pendingInputRequestId!==n||r!=null&&s.pendingInputQuestionId!==r||s.consumedAt!=null||(s.consumedAt=i,o.push(s));return o.length>0&&this.notifyChanged(),o}deleteActionTokensForSession(e){let n=!1;for(let[r,o]of this.tokens)o.sessionId===e&&(this.tokens.delete(r),n=!0);n&&this.notifyChanged()}deleteActionTokensForSessionByKind(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId===e&&i.kind===n&&(this.tokens.delete(o),r=!0);r&&this.notifyChanged()}deletePlanDecisionTokensForSession(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId!==e||!Rk(i.kind)||n!=null&&i.planDecisionVersion===n||(this.tokens.delete(o),r=!0);r&&this.notifyChanged()}purgeExpiredActionTokens(e=Date.now()){let n=!1;for(let[r,o]of this.tokens){let i=o.expiresAt!=null&&o.expiresAt<=e,s=o.consumedAt!=null&&e-o.consumedAt>=this.retentionMs;(i||s)&&(this.tokens.delete(r),n=!0)}return n&&this.notifyChanged(),n}nextExpiryAt(){let e;for(let n of this.tokens.values()){let r=[n.expiresAt,n.consumedAt!=null?n.consumedAt+this.retentionMs:void 0].filter(o=>o!=null&&Number.isFinite(o));for(let o of r)(e==null||o<e)&&(e=o)}return e}setAfterChangeListener(e){this.afterChange=e}notifyChanged(){this.onChange(),this.afterChange?.()}};ne();ne();var Ho=class{constructor(e){this.indexes=e}indexes;hasRecordedSession(e){return this.indexes.idIndex.has(e)}getLatestPersistedByName(e){let n,r=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,s=0;for(let a of this.indexes.persisted.values()){if(a.name!==e){s++;continue}let d=a.createdAt??Number.NEGATIVE_INFINITY,l=a.completedAt??Number.NEGATIVE_INFINITY;(d>r||d===r&&l>o||d===r&&l===o&&s>i)&&(n=a,r=d,o=l,i=s),s++}return n}resolveBackendConversationId(e,n){if(n)return n;let r=this.indexes.idIndex.get(e);if(r){let s=this.indexes.persisted.get(r);return(s?O(s):void 0)??r}let o=this.getLatestPersistedByName(e);if(o)return O(o)??o.harnessSessionId;let i=this.indexes.backendIdIndex.get(e);if(i){let s=this.indexes.persisted.get(i);return(s?O(s):void 0)??i}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?O(s)??e:e}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e))return e}resolveHarnessSessionId(e,n){return this.resolveBackendConversationId(e,n)}getPersistedSession(e){let n=this.indexes.idIndex.get(e);if(n)return this.indexes.persisted.get(n);let r=this.getLatestPersistedByName(e);if(r)return r;let o=this.indexes.backendIdIndex.get(e);return o?this.indexes.persisted.get(o):this.indexes.persisted.get(e)}listPersistedSessions(){return[...this.indexes.persisted.values()].sort((e,n)=>(n.completedAt??0)-(e.completedAt??0))}};import{existsSync as hc,mkdirSync as Zk,readFileSync as Xk,readdirSync as eS,renameSync as yc,statSync as kc,unlinkSync as Sc,writeFileSync as vc}from"fs";import{tmpdir as tS}from"os";import{dirname as nS,join as wc}from"path";import{homedir as Ak}from"node:os";import{join as Ik}from"node:path";function zo(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||Ak();return Ik(n,".openclaw")}ke();var Qo=7,xk=new Set(["running","completed","failed","killed"]),Tk=new Set(["queued","running","waiting","blocked","succeeded","failed","cancelled","lost"]);function Ke(t){return!!t&&typeof t=="object"}function dn(t,e=""){return typeof t=="string"&&t.trim().length>0?t:e}function b(t){return typeof t=="string"&&t.trim().length>0?t:void 0}function me(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function Ck(t){if(!Ke(t))return;let e=b(t.flowId),n=me(t.revision);if(!e||n===void 0)return;let r=typeof t.status=="string"&&Tk.has(t.status)?t.status:void 0;return{flowId:e,revision:n,...r?{status:r}:{}}}function sc(t){return typeof t=="string"&&Ml.has(t)?t:void 0}function ma(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function Mk(t){return t==="never"||t==="on-request"?"never":void 0}function ac(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function _k(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function dc(t){return typeof t=="string"&&so.has(t)?t:void 0}function fa(t){return typeof t=="string"&&Cl.has(t)?t:void 0}function lc(t){return t==="github"||t==="unsupported"?t:void 0}function $k(t){return t==="stored"||t==="seeded"||t==="unknown"?t:void 0}function Ek(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function uc(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 Dk(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function Ok(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 Nk(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 cc(t){return t==="live"||t==="stopped"?t:void 0}function Wk(t){if(!Ke(t)||t.reason!=="persisted-running-without-runtime")return;let e=b(t.recoveredAt);if(!e||!Number.isFinite(Date.parse(e)))return;let n=t.normalizedStatus==="killed"?"killed":void 0;if(n)return{reason:"persisted-running-without-runtime",recoveredAt:e,rawStatus:b(t.rawStatus),rawLifecycle:b(t.rawLifecycle),rawRuntimeState:b(t.rawRuntimeState),rawResumable:typeof t.rawResumable=="boolean"?t.rawResumable:void 0,rawCompletedAt:me(t.rawCompletedAt),rawOutputPath:b(t.rawOutputPath),normalizedStatus:n,normalizedLifecycle:uc(t.normalizedLifecycle),normalizedRuntimeState:cc(t.normalizedRuntimeState)}}function Lk(t){return{reason:"persisted-running-without-runtime",recoveredAt:new Date().toISOString(),rawStatus:b(t.status),rawLifecycle:b(t.lifecycle),rawRuntimeState:b(t.runtimeState),rawResumable:typeof t.resumable=="boolean"?t.resumable:void 0,rawCompletedAt:me(t.completedAt),rawOutputPath:b(t.outputPath),normalizedStatus:"killed",normalizedLifecycle:"suspended",normalizedRuntimeState:"stopped"}}function Bk(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function Fk(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function qk(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function Uk(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function Kk(t){return t==="in_flight"||t==="delivered"?t:void 0}function Vk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ke(n))return;let r=b(n.key),o=Kk(n.status),i=b(n.recordedAt);if(!(!r||!o||!i||!Number.isFinite(Date.parse(i))))return{key:r,status:o,recordedAt:i,label:b(n.label)}}).filter(n=>!!n);return e.length>0?e.slice(-64):void 0}function jk(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ke(n))return;let r=b(n.key),o=b(n.recordedAt);if(!r||!o||!Number.isFinite(Date.parse(o)))return;let i=Array.isArray(n.linkedKeys)?[...new Set(n.linkedKeys.map(b).filter(s=>!!(s&&s!==r)))]:void 0;return{key:r,linkedKeys:i&&i.length>0?i:void 0,recordedAt:o,label:b(n.label),skipReason:b(n.skipReason)}}).filter(n=>!!n);return e.length>0?e.slice(-1024):void 0}function Gk(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 Hk(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 pc(t){if(!Ke(t))return;let e=b(t.provider),n=b(t.accountId),r=b(t.target),o=b(t.threadId),i=b(t.sessionKey);if(!(!e||!r))return{provider:e,accountId:n,target:r,threadId:o,sessionKey:i}}function zk(t,e,n){if(Ke(t)){let r=b(t.kind),o=b(t.conversationId);if(o&&(r==="claude-code"||r==="codex-app-server"||r==="opencode-server"))return{kind:r,conversationId:o,runId:b(t.runId),worktreeId:b(t.worktreeId),worktreePath:b(t.worktreePath)}}if(e==="claude-code")return{kind:"claude-code",conversationId:n}}function Qk(t){if(!Ke(t))return;let e=Nk(t.state),n=b(t.updatedAt);if(!e||!n)return;let r=b(t.resolutionSource);return{state:e,updatedAt:n,resolvedAt:b(t.resolvedAt),resolutionSource:r==="agent_merge"||r==="agent_pr"||r==="strategy_no_change"||r==="lifecycle_resolver"||r==="dismiss"||r==="maintenance"?r:void 0,baseBranch:b(t.baseBranch),targetRepo:b(t.targetRepo),pushRemote:b(t.pushRemote),notes:Array.isArray(t.notes)?t.notes.filter(o=>typeof o=="string"&&o.length>0):void 0}}function Jk(t){let e=new Date(0).toISOString(),n=b(t.worktreeMergedAt)??b(t.worktreeDismissedAt)??b(t.pendingWorktreeDecisionSince)??e;if(t.worktreeMerged===!0||t.worktreeDisposition==="merged")return{state:"merged",updatedAt:n,resolvedAt:b(t.worktreeMergedAt)??n,resolutionSource:"agent_merge",baseBranch:b(t.worktreeBaseBranch),targetRepo:b(t.worktreePrTargetRepo),pushRemote:b(t.worktreePushRemote)};if(t.worktreeDisposition==="dismissed")return{state:"dismissed",updatedAt:n,resolvedAt:b(t.worktreeDismissedAt)??n,resolutionSource:"dismiss",baseBranch:b(t.worktreeBaseBranch),targetRepo:b(t.worktreePrTargetRepo),pushRemote:b(t.worktreePushRemote)};if(t.worktreeDisposition==="no-change-cleaned")return{state:"no_change",updatedAt:n,resolvedAt:n,resolutionSource:"strategy_no_change",baseBranch:b(t.worktreeBaseBranch),targetRepo:b(t.worktreePrTargetRepo),pushRemote:b(t.worktreePushRemote)};if(t.worktreeDisposition==="pr-opened"||t.worktreeState==="pr_open")return{state:"pr_open",updatedAt:n,baseBranch:b(t.worktreeBaseBranch),targetRepo:b(t.worktreePrTargetRepo),pushRemote:b(t.worktreePushRemote)};if(t.pendingWorktreeDecisionSince||t.worktreeState==="pending_decision")return{state:"pending_decision",updatedAt:n,baseBranch:b(t.worktreeBaseBranch),targetRepo:b(t.worktreePrTargetRepo),pushRemote:b(t.worktreePushRemote)};if(t.worktreeState==="merge_conflict_resolving")return{state:"merge_conflict_resolving",updatedAt:n,baseBranch:b(t.worktreeBaseBranch),targetRepo:b(t.worktreePrTargetRepo),pushRemote:b(t.worktreePushRemote)};if(b(t.worktreePath)||b(t.worktreeBranch))return{state:"provisioned",updatedAt:n,baseBranch:b(t.worktreeBaseBranch),targetRepo:b(t.worktreePrTargetRepo),pushRemote:b(t.worktreePushRemote)}}function Yk(t){if(typeof t=="string"&&xk.has(t))return t==="running"?"killed":t}function mc(t){if(!Ke(t))return;let e=dn(t.harnessSessionId);if(!e)return;let n=Yk(t.status);if(!n)return;let r=t.status==="running",o=b(t.worktreePath),i=b(t.worktreeBranch),s=b(t.originChannel),a=typeof t.originThreadId=="string"||typeof t.originThreadId=="number"?t.originThreadId:void 0,d=b(t.originSessionKey),l=pc(t.route);if(!l)return;let u=Ne({route:l,originChannel:s,originThreadId:a,originSessionKey:d});if(!u||o&&!i)return;let f=b(t.harness),p=zk(t.backendRef,f,e),k=Qk(t.worktreeLifecycle)??Jk(t),m=b(t.completionWakeSucceededAt),c=b(t.completionWakeSkippedAt),h=t.completionWakeSummaryRequired===!0&&!c?!0:void 0;return{sessionId:b(t.sessionId),harnessSessionId:e,backendRef:p,name:dn(t.name,e),prompt:dn(t.prompt),workdir:dn(t.workdir,"(unknown)"),model:b(t.model),reasoningEffort:sc(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:me(t.createdAt),completedAt:me(t.completedAt),status:n,lifecycle:r?"suspended":uc(t.lifecycle),approvalState:Dk(t.approvalState),worktreeState:Ok(t.worktreeState),runtimeState:r?"stopped":cc(t.runtimeState),runtimeRecovery:r?Lk(t):Wk(t.runtimeRecovery),taskFlowMirror:Ck(t.taskFlowMirror),deliveryState:Uk(t.deliveryState),notificationDedupe:Vk(t.notificationDedupe),completionSummaryDedupe:jk(t.completionSummaryDedupe),completionWakeIssuedAt:b(t.completionWakeIssuedAt),completionWakeSucceededAt:m,completionWakeFailedAt:b(t.completionWakeFailedAt),completionWakeSkippedAt:c,completionWakeSkipReason:b(t.completionWakeSkipReason),completionWakeSummaryRequired:h,killReason:Ek(t.killReason),costUsd:typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)?t.costUsd:0,originAgentId:b(t.originAgentId),originChannel:s,originThreadId:a,originSessionKey:d,route:u,outputPath:b(t.outputPath),harness:f,resumedFromSessionName:b(t.resumedFromSessionName),goalTaskId:b(t.goalTaskId),requestedPermissionMode:ma(t.requestedPermissionMode),currentPermissionMode:ma(t.currentPermissionMode),approvalExecutionState:Gk(t.approvalExecutionState),approvalRationale:b(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:_k(t.planApprovalContext),planDecisionVersion:me(t.planDecisionVersion),actionablePlanDecisionVersion:me(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:me(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:me(t.approvalPromptRequiredVersion),approvalPromptVersion:me(t.approvalPromptVersion),approvalPromptStatus:Bk(t.approvalPromptStatus),approvalPromptTransport:Fk(t.approvalPromptTransport),approvalPromptMessageKind:qk(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:b(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:b(t.approvalPromptDeliveredAt),approvalPromptFailedAt:b(t.approvalPromptFailedAt),planApproval:ac(t.planApproval),codexApprovalPolicy:Mk(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:dc(t.worktreeStrategy),repoIntegrationPolicy:fa(t.repoIntegrationPolicy),repoIntegrationPolicySource:$k(t.repoIntegrationPolicySource),repoProvider:lc(t.repoProvider),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:b(t.worktreeMergedAt),worktreePrUrl:b(t.worktreePrUrl),worktreePrNumber:me(t.worktreePrNumber),pendingWorktreeDecisionSince:b(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:b(t.lastWorktreeReminderAt),worktreeBaseBranch:b(t.worktreeBaseBranch),worktreeParentBranch:b(t.worktreeParentBranch),worktreePrTargetRepo:b(t.worktreePrTargetRepo),autoMergeParentSessionId:b(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:me(t.autoMergeConflictResolutionAttemptCount),autoMergeResolverSessionId:b(t.autoMergeResolverSessionId),worktreePushRemote:b(t.worktreePushRemote),worktreeDecisionSnoozedUntil:b(t.worktreeDecisionSnoozedUntil),worktreeDisposition:t.worktreeDisposition==="active"||t.worktreeDisposition==="pr-opened"||t.worktreeDisposition==="merged"||t.worktreeDisposition==="dismissed"||t.worktreeDisposition==="no-change-cleaned"?t.worktreeDisposition:void 0,worktreeRemoteOutcome:t.worktreeRemoteOutcome==="pr-opened"||t.worktreeRemoteOutcome==="pr-updated"?t.worktreeRemoteOutcome:void 0,worktreeDismissedAt:b(t.worktreeDismissedAt),worktreeLifecycle:k,resumable:r?!0:t.resumable===!0}}function fc(t){if(!Ke(t))return;let e=b(t.key),n=b(t.repoRoot),r=fa(t.policy),o=lc(t.provider)??"unsupported",i=b(t.createdAt),s=b(t.updatedAt),a=t.source==="seeded"?"seeded":"stored";if(!(!e||!n||!r||!i||!s)&&!(!Number.isFinite(Date.parse(i))||!Number.isFinite(Date.parse(s))))return{key:e,policy:r,repoRoot:n,remoteUrl:b(t.remoteUrl),provider:o,createdAt:i,updatedAt:s,source:a}}function gc(t){if(!Ke(t))return;let e=Hk(t.kind),n=dn(t.id),r=dn(t.sessionId),o=me(t.createdAt);if(!(!n||!r||!e||o==null))return{id:n,sessionId:r,kind:e,createdAt:o,planDecisionVersion:me(t.planDecisionVersion),expiresAt:me(t.expiresAt),consumedAt:me(t.consumedAt),optionIndex:me(t.optionIndex),pendingInputRequestId:b(t.pendingInputRequestId),pendingInputQuestionId:b(t.pendingInputQuestionId),label:b(t.label),targetUrl:b(t.targetUrl),route:pc(t.route),launchName:b(t.launchName),launchPrompt:b(t.launchPrompt),launchWorkdir:b(t.launchWorkdir),launchModel:b(t.launchModel),launchReasoningEffort:sc(t.launchReasoningEffort),launchFastMode:t.launchFastMode===!0?!0:void 0,launchSystemPrompt:b(t.launchSystemPrompt),launchAllowedTools:Array.isArray(t.launchAllowedTools)?t.launchAllowedTools.filter(i=>typeof i=="string"):void 0,launchResumeSessionId:b(t.launchResumeSessionId),launchResumedFromSessionName:b(t.launchResumedFromSessionName),launchResumeWorktreeFrom:b(t.launchResumeWorktreeFrom),launchSessionIdOverride:b(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:ma(t.launchPermissionMode),launchPlanApproval:ac(t.launchPlanApproval),launchHarness:b(t.launchHarness),launchWorktreeStrategy:dc(t.launchWorktreeStrategy),launchWorktreeBaseBranch:b(t.launchWorktreeBaseBranch),launchWorktreePrTargetRepo:b(t.launchWorktreePrTargetRepo),launchOriginAgentId:b(t.launchOriginAgentId),repoPolicy:fa(t.repoPolicy),repoPolicyWorkdir:b(t.repoPolicyWorkdir)}}function Jo(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 Jn(t){return!!t&&typeof t=="object"}function ga(t){return t instanceof Error?t.message:String(t)}function rS(t,e){JSON.stringify({component:"SessionStore",event:t,at:new Date().toISOString(),...e})}function oS(t){return Jn(t)?{backendRefKind:typeof t.kind=="string"?t.kind:void 0,hasBackendConversationId:typeof t.conversationId=="string"&&t.conversationId.length>0,hasBackendRunId:typeof t.runId=="string"&&t.runId.length>0,hasBackendWorktreeId:typeof t.worktreeId=="string"&&t.worktreeId.length>0,hasBackendWorktreePath:typeof t.worktreePath=="string"&&t.worktreePath.length>0}:{}}function Pc(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(!hc(s))return s}}function ha(){let t=tS();return eS(t).filter(e=>e.startsWith("openclaw-agent-")&&e.endsWith(".txt")).map(e=>wc(t,e))}function bc(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||wc(zo(t),"code-agent-sessions.json")}function Rc(t,e,n,r=[]){try{Zk(nS(t),{recursive:!0});let o=t+".tmp";vc(o,JSON.stringify({schemaVersion:Qo,sessions:e,actionTokens:n,repoPolicies:r},null,2),"utf-8"),yc(o,t)}catch(o){`${ga(o)}`}}function iS(t,e){try{if(!hc(t))return!1;let n=Pc(t,"legacy");return n?(yc(t,n),`${e}${n}`,!0):!1}catch(n){return`${ga(n)}`,!1}}var sS={archiveLegacySessionIndex:iS};function aS(t,e){try{if(e.length===0)return;let n=Pc(t,"codex-sdk-legacy");if(!n)return;vc(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${ga(n)}`}}function Ac(t,e,n=[]){try{let r=new Set(n);for(let o of ha())if(!r.has(o))try{let i=kc(o).mtimeMs;t-i>e&&Sc(o)}catch{}}catch{}}function Ic(t,e,n=[]){try{let r=new Set(n),o;for(let i of ha())if(!r.has(i))try{let s=kc(i).mtimeMs+e;if(s<=t)return t;o=o==null?s:Math.min(o,s)}catch{}return o}catch{return}}function xc(t){try{let e=new Set(t);for(let n of ha())if(!e.has(n))try{Sc(n)}catch{}}catch{}}function Tc(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,setRepoPolicy:i,purgeExpiredActionTokens:s,saveIndex:a}=t,d=l=>sS.archiveLegacySessionIndex(e,l)?(n(),!0):!1;try{let l=Xk(e,"utf-8"),u=JSON.parse(l);if(Array.isArray(u)){if(!d("legacy array store"))return;a();return}if(!Jn(u)||u.schemaVersion!==Qo&&u.schemaVersion!==6&&u.schemaVersion!==4){if(!d(`schema mismatch (expected v${Qo})`))return;a();return}let f=(A,y)=>{if(!Object.prototype.hasOwnProperty.call(u,A))return[];let w=u[A];if(Array.isArray(w))return w;d(y)&&a()},p=f("sessions","invalid sessions collection");if(p===void 0)return;let k=[],m=[],c=!1;for(let A of p){if(Jn(A)&&A.harness==="codex"){let w=Jn(A.backendRef)?A.backendRef:void 0;if((typeof w?.kind=="string"?w.kind:void 0)!=="codex-app-server"){k.push(A);continue}}let y=mc(A);if(!y){if(!d("invalid v4 session entry"))return;a();return}Jn(A)&&A.status==="running"&&(c=!0,rS("session.recovered_from_running_persisted_row",{sessionId:typeof A.sessionId=="string"?A.sessionId:void 0,hasHarnessSessionId:typeof A.harnessSessionId=="string"&&A.harnessSessionId.length>0,...oS(A.backendRef),rawStatus:A.status,rawLifecycle:A.lifecycle,rawRuntimeState:A.runtimeState,normalizedStatus:y.status,normalizedLifecycle:y.lifecycle,normalizedRuntimeState:y.runtimeState,reason:y.runtimeRecovery?.reason})),m.push(y)}k.length>0&&aS(e,k);let h=f("actionTokens","invalid action token collection");if(h===void 0)return;let S=[];for(let A of h){let y=gc(A);if(!y){if(!d("invalid v4 action token"))return;a();return}S.push(y)}let P=f("repoPolicies","invalid repo policy collection");if(P===void 0)return;let x=[],C=!1;for(let A of P){let y=fc(A);if(!y){C=!0;continue}x.push(y)}for(let A of m)r(A);for(let A of S)o(A);for(let A of x)i(A);(k.length>0||c)&&a(),C&&a(),s()}catch(l){if(l.code==="ENOENT"||!d("corrupt or unreadable"))return;a()}}var cS=new Set(["completed","failed","killed"]),ya=1440*60*1e3;function pS(t){return t instanceof Error?t.message:String(t)}var mS={statSync:lS};function fS(t){try{return mS.statSync(t).isDirectory()}catch(e){let n=e.code;return n!=="ENOENT"&&n!=="ENOTDIR"}}var Yo=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??bc(n),this.actionTokenStore=new Go(()=>this.saveIndex(),ya),this.actionTokens=this.actionTokenStore.tokens,this.queries=new Ho({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Tc({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(){Rc(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence(),[...this.repoPolicies.values()])}assertPersistedEntry(e){Jo(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=os(e),r=n==="codex"?"codex-app-server":n==="opencode"?"opencode-server":"claude-code";return e.backendRef??{kind:e.backendKind??r,conversationId:e.harnessSessionId}}getSessionApprovalSnapshot(e){if(typeof e.approvalSnapshot=="function")return e.approvalSnapshot();let n=typeof e.controlStateSnapshot=="function"?e.controlStateSnapshot():{planModeApproved:!1};return{requestedPermissionMode:e.requestedPermissionMode,currentPermissionMode:e.currentPermissionMode,approvalExecutionState:e.approvalExecutionState,approvalRationale:e.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy}}getSessionRoutingSnapshot(e){return typeof e.routingSnapshot=="function"?e.routingSnapshot():{route:e.route,originAgentId:e.originAgentId,originChannel:e.originChannel,originThreadId:e.originThreadId,originSessionKey:e.originSessionKey}}getSessionWorktreeSnapshot(e){return typeof e.worktreeSnapshot=="function"?e.worktreeSnapshot():{worktreePath:e.worktreePath,worktreeBranch:e.worktreeBranch,worktreeStrategy:e.worktreeStrategy,repoIntegrationPolicy:e.repoIntegrationPolicy,repoIntegrationPolicySource:e.repoIntegrationPolicySource,repoProvider:e.repoProvider,worktreeBaseBranch:e.worktreeBaseBranch,worktreeParentBranch:e.worktreeParentBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,autoMergeParentSessionId:e.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:e.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:e.autoMergeResolverSessionId,worktreeLifecycle:e.worktreeLifecycle}}indexPersistedEntry(e){let n=this.getEntryStorageKey(e);this.persisted.set(n,e),e.sessionId&&this.idIndex.set(e.sessionId,n),e.name&&this.nameIndex.set(e.name,n);let r=O(e);r&&this.backendIdIndex.set(r,n)}removePersistedIndexes(e){let n=this.getEntryStorageKey(e);this.persisted.delete(n);for(let[r,o]of this.idIndex)o===n&&this.idIndex.delete(r);for(let[r,o]of this.nameIndex)o===n&&this.nameIndex.delete(r);for(let[r,o]of this.backendIdIndex)o===n&&this.backendIdIndex.delete(r)}markRunning(e){if(!e.harnessSessionId)return;let n=this.getSessionApprovalSnapshot(e),r=this.getSessionRoutingSnapshot(e),o=this.getSessionWorktreeSnapshot(e),i=Ne({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,status:"running",lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,taskFlowMirror:e.taskFlowMirror,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),costUsd:0,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:wt(e.id),harness:e.harnessName,resumedFromSessionName:e.resumedFromSessionName,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalRationale:n.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planApproval:n.planApproval,codexApprovalPolicy:n.codexApprovalPolicy,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,repoIntegrationPolicy:o.repoIntegrationPolicy,repoIntegrationPolicySource:o.repoIntegrationPolicySource,repoProvider:o.repoProvider,worktreeBaseBranch:o.worktreeBaseBranch,worktreeParentBranch:o.worktreeParentBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Jo(s),this.indexPersistedEntry(s),this.saveIndex()}hasRecordedSession(e){return this.queries.hasRecordedSession(e)}persistTerminal(e){if(!e.harnessSessionId)return;let n=this.getSessionApprovalSnapshot(e),r=this.getSessionRoutingSnapshot(e),o=this.getSessionWorktreeSnapshot(e),i=Ne({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let d=wt(e.id);if(dS(d))s=d;else{let l=e.getOutput().join(`
259
259
  `);l.length>0&&(uS(d,l,"utf-8"),s=d)}}catch(d){`${e.id}${pS(d)}`}let a={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,completedAt:e.completedAt,status:e.status,lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,taskFlowMirror:e.taskFlowMirror,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),killReason:e.killReason,costUsd:e.costUsd,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:s,harness:e.harnessName,resumedFromSessionName:e.resumedFromSessionName,goalTaskId:e.goalTaskId,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalRationale:n.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planApproval:n.planApproval,codexApprovalPolicy:n.codexApprovalPolicy,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,worktreeBaseBranch:o.worktreeBaseBranch,worktreeParentBranch:o.worktreeParentBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Jo(a),this.indexPersistedEntry(a),this.saveIndex()}getExistingNotificationDedupe(e){return this.getPersistedSession(e.id)?.notificationDedupe??(e.harnessSessionId?this.getPersistedSession(e.harnessSessionId)?.notificationDedupe:void 0)??(O(e)?this.getPersistedSession(O(e))?.notificationDedupe:void 0)}getLatestPersistedByName(e){return this.queries.getLatestPersistedByName(e)}resolveBackendConversationId(e,n){return this.queries.resolveBackendConversationId(e,n)}resolveHarnessSessionId(e,n){return this.queries.resolveHarnessSessionId(e,n)}getPersistedSession(e){return this.queries.getPersistedSession(e)}listPersistedSessions(){return this.queries.listPersistedSessions()}getRepoPolicy(e){return this.repoPolicies.get(e)}listRepoPolicies(){return[...this.repoPolicies.values()].sort((e,n)=>e.repoRoot.localeCompare(n.repoRoot)||e.key.localeCompare(n.key))}setRepoPolicy(e){let n=this.repoPolicies.get(e.key),r={...e,createdAt:n?.createdAt??e.createdAt,updatedAt:new Date().toISOString(),source:"stored"};return this.repoPolicies.set(r.key,r),this.saveIndex(),r}updateRepoPolicy(e,n){let r=this.repoPolicies.get(e);if(r)return this.setRepoPolicy({...r,policy:n})}resetRepoPolicy(e){let n=this.repoPolicies.delete(e);return n&&this.saveIndex(),n}removeRepoPolicies(e){let n=[];for(let r of e){let o=this.repoPolicies.get(r);o&&(this.repoPolicies.delete(r),n.push(o))}return n.length>0&&this.saveIndex(),n.sort((r,o)=>r.repoRoot.localeCompare(o.repoRoot)||r.key.localeCompare(o.key))}cleanupRepoPolicies(){let e=[];for(let[n,r]of this.repoPolicies)fS(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),Ac(e,ya,this.getReferencedOutputPaths())}getNextTmpOutputCleanupAt(e){return Ic(e,ya,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||!cS.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(){xc(this.getReferencedOutputPaths())}};var gS=new Set(["completed","failed","killed"]),Zo=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),gS.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:ce(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 Cc from"child_process";var ln=class{tails=new Map;enqueue(e,n,r){let o=this.tails.get(e);o!==void 0&&r?.();let s=(o?.catch(()=>{})??Promise.resolve()).then(()=>n()),a=s.catch(()=>{});return this.tails.set(e,a),a.finally(()=>{this.tails.get(e)===a&&this.tails.delete(e)}),s}clear(){this.tails.clear()}};var ka=3e4,hS=2e3,yS=2e4,we=4;function Yn(t){return t instanceof Error?t.message:String(t)}function kS(){return new Error(`Dispatch timed out after ${ka}ms`)}function SS(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var vS={execFile:Cc.execFile},Xo=class{pendingRetryTimers=new Map;orderedDispatches=new ln;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:we}),vS.execFile("openclaw",e,{timeout:ka,killSignal:"SIGKILL"},(s,a,d)=>{if(this.disposed){r?.();return}let l=Date.now()-i;if(!s){let m=n.successValidator?.(a??"");if(m?.outcome==="failure"){this.log("error","dispatch_success_validation_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:we,elapsedMs:l,error:m.reason,terminal:!0}),n.onFinalFailure?.(),r?.();return}if(m?.outcome==="skipped"){this.log("info","dispatch_skipped",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:we,elapsedMs:l,reason:m.reason}),n.shouldContinue?.()!==!1&&n.onSkipped?.(m.reason),r?.();return}this.log("info","dispatch_succeeded",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:we,elapsedMs:l}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.();return}let u=d?.trim()?` | stderr: ${d.trim()}`:"";if(n.shouldContinue?.()===!1){r?.();return}if(n.target==="message.send"&&SS(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:we,elapsedMs:l,error:`${Yn(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(o>=we||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:we,elapsedMs:l,error:`${Yn(s)}${u}`,terminal:!0}),n.onFinalFailure?.(),r?.();return}let p=this.retryDelayMs(o);this.log("error","dispatch_retry_scheduled",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:we,elapsedMs:l,retryDelayMs:p,error:`${Yn(s)}${u}`});let k={timer:setTimeout(()=>{let m=this.pendingRetryTimers.get(n.sessionId);if(m&&(m.delete(k),m.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executeNow(e,n,r,o+1)},p),onCleared:r};k.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(k)})}executePromiseNow(e,n,r,o=1){if(this.disposed||n.shouldContinue?.()===!1){r?.();return}let i=Date.now();o===1&&n.onStarted?.(),this.log("info","dispatch_started",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:we}),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:we,elapsedMs:s}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.()}).catch(s=>{if(this.disposed){r?.();return}let a=Date.now()-i;if(n.shouldContinue?.()===!1){r?.();return}if(o>=we||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:we,elapsedMs:a,error:Yn(s),terminal:!0,...n.terminalOnFailure===!0&&o<we?{terminalReason:"non_retryable"}:{}}),n.onFinalFailure?.(),r?.();return}let d=this.retryDelayMs(o);this.log("error","dispatch_retry_scheduled",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:we,elapsedMs:a,retryDelayMs:d,error:Yn(s)});let l={timer:setTimeout(()=>{let u=this.pendingRetryTimers.get(n.sessionId);if(u&&(u.delete(l),u.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executePromiseNow(e,n,r,o+1)},d),onCleared:r};l.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(l)})}executePromiseWithTimeout(e){return new Promise((n,r)=>{let o=!1,i=setTimeout(()=>{o||(o=!0,r(kS()))},ka);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=hS*2**n;return Math.min(r,yS)}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}}};ke();var ei=class{resolve(e){let n=Ve(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 wS}from"crypto";var ti=class{constructor(e={}){}buildChatSendArgs(e,n,r,o=wS()){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=rr(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 PS(t){let e=bS(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 bS(t){let e=t.trim();if(!e)return"";try{return Sa(JSON.parse(e)).trim()}catch{return e}}function Sa(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>Sa(r)).filter(Boolean).join(`
260
- `);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=Sa(e[r]);if(o.trim())return o}return""}var ni=class{routes=new ei;transport;directNotifications;executor=new Xo;constructor(e={}){this.transport=e.transport??new ti(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new Nt:e.directNotifications}clearPendingRetries(){this.executor.clearPendingRetries()}clearRetryTimersForSession(e){this.executor.clearRetryTimersForSession(e)}dispose(){this.executor.dispose()}buildDispatchContext(e){let n=e.buttons??[],r=n.flat();return{transportRoute:e.routeSummary,transportChannel:e.route?.channel??"system",transportTarget:e.route?.target??"system",transportAccountId:e.route?.accountId,transportThreadId:e.route?.threadId,transportSessionKey:e.route?.sessionKey,messageTextLength:e.text.length,buttonsPresent:r.length>0,buttonRows:n.length||void 0,buttonCount:r.length||void 0,buttonLabels:r.length>0?r.map(o=>o.label):void 0,maxCallbackDataLength:r.length>0?Math.max(...r.map(o=>o.callbackData.length)):void 0}}sendWake(e,n,r,o,i,s,a,d,l,u){let f=this.routes.resolve(e),p=a;if(p?.()===!1)return;let k=f?.sessionKey?.trim();if(!k){this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-system`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:l,onFinalFailure:i,successValidator:d,shouldContinue:p});return}this.executor.execute(this.transport.buildChatSendArgs(k,n,!0,u),{label:r,sessionId:e.id,target:"chat.send",phase:o,routeSummary:`session:${k}`,messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:`session:${k}`,route:f,text:n}),onSuccess:s,onSkipped:l,successValidator:d,shouldContinue:p,onFinalFailure:()=>{p?.()!==!1&&this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-fallback`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:l,onFinalFailure:i,successValidator:d,shouldContinue:p})}})}sendUserNotification(e,n,r,o,i,s,a=!1,d){if(d?.()===!1)return;let l=!!o?.some(m=>Array.isArray(m)&&m.length>0),u=this.routes.resolve(e);B("wake_notify_selected",{sessionId:e.id,sessionName:e.name,label:r,messageTextLength:n.length,requireDirectDelivery:a,hasDirectNotificationTransport:!!this.directNotifications,routeSummary:u?this.routes.summary(u):"system",channel:u?.channel,target:u?.target,accountId:u?.accountId,threadId:u?.threadId,sessionKey:u?.sessionKey,...X(o)});let f=u?`notify:${u.channel}|${u.accountId??""}|${u.target}|${u.threadId??""}`:`notify:system:${e.id}`;if(!u){if(B("wake_notify_no_direct_route",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:l,...X(o)}),a){`${r}${e.id}`,i?.();return}if(l){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-system`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n,buttons:o}),orderingKey:f,onSuccess:s,onFinalFailure:i,shouldContinue:d});return}let p=()=>{if(B("wake_notify_direct_failed",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:l,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...X(o)}),a){`${r}${e.id}`,i?.();return}if(l){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-fallback`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),orderingKey:f,onSuccess:s,onFinalFailure:i,shouldContinue:d})},k={label:`${r}-notify`,sessionId:e.id,target:"message.send",phase:"notify",routeSummary:this.routes.summary(u),messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:this.routes.summary(u),route:u,text:n,buttons:o}),orderingKey:f,onSuccess:s,onAmbiguousResult:p,onFinalFailure:p,terminalOnFailure:this.directNotifications?!0:void 0,shouldContinue:d};if(this.directNotifications){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,...X(o)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,o),k);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,...X(o)}),this.executor.execute(this.transport.buildDirectNotificationArgs(u,n,o),k)}sendUserNotificationSequence(e,n,r,o,i,s=!1,a){let d=n.map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0);if(d.length===0){o?.();return}B("wake_notify_sequence_started",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length,buttonChunkIndexes:d.map((u,f)=>u.buttons?.some(p=>Array.isArray(p)&&p.length>0)?f+1:void 0).filter(u=>typeof u=="number"),requireDirectDelivery:s});let l=u=>{if(a?.()===!1)return;let f=d[u];if(!f){B("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length}),i?.();return}let p=u===0?o:i;B("wake_notify_sequence_chunk_selected",{sessionId:e.id,sessionName:e.name,label:r,chunkIndex:u+1,chunkCount:d.length,messageTextLength:f.text.length,failureHandler:u===0?"all-failed":"sequence-success",...X(f.buttons)}),this.sendUserNotification(e,f.text,`${r}-part-${u+1}`,f.buttons,p,()=>l(u+1),s,a)};l(0)}dispatchSessionNotification(e,n){let r=n.hooks,o=n.wakeMessageOnNotifySuccess!=null||n.wakeMessageOnNotifyFailed!=null,i=n.notifyUser??(n.wakeMessage?"on-wake-fallback":"always"),s=(n.userMessages?.length?n.userMessages:n.userMessage?.trim()?[{text:n.userMessage.trim(),buttons:n.buttons}]:[]).map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0),a=n.wakeMessage?.trim(),d=n.shouldDispatch,l=n.completionWakeSummaryRequired===!0?PS:void 0;if(o){let u=n.wakeMessageOnNotifySuccess?.trim(),f=n.wakeMessageOnNotifyFailed?.trim(),p=h=>{h&&d?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,h,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,d,l,r?.onWakeSkipped,n.idempotencyKey))},k=h=>{if(h){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let S=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>p(h),S).unref?.();return}p(h)}},m=()=>{d?.()!==!1&&(r?.onNotifySucceeded?.(),u&&k(u))},c=f?()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),k(f))}:()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,c,m,n.requireDirectUserNotification===!0,d)}else c();return}if(i==="always"&&s.length>0){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{d?.()!==!1&&r?.onNotifySucceeded?.()},n.requireDirectUserNotification===!0,d)}if(a&&d?.()!==!1){if(r?.onWakeStarted?.(),i==="on-wake-fallback"&&s.length>0&&!this.routes.resolve(e)?.sessionKey){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{d?.()!==!1&&r?.onNotifySucceeded?.()},!1,d)}this.sendWake(e,a,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,d,l,r?.onWakeSkipped,n.idempotencyKey)}}};var Mc=36,_c=2,$c="...";function RS(t){let e=Array.from(t);return e.length<=Mc?t:`${e.slice(0,Mc-$c.length).join("")}${$c}`}var ri=class{constructor(e,n){this.actionTokens=e;this.isGitHubCliAvailable=n}actionTokens;isGitHubCliAvailable;createActionToken(e,n,r={}){return this.actionTokens.createActionToken(e,n,{expiresAt:Date.now()+10080*60*1e3,...r})}consumeActionToken(e){return this.actionTokens.consumeActionToken(e)}consumeQuestionAnswerTokens(e,n){return this.actionTokens.consumeQuestionAnswerTokens(e,n)}getActionToken(e){return this.actionTokens.getActionToken(e)}listActiveActionTokens(e){return this.actionTokens.listActiveActionTokens(e)}clearRepoPolicyChoiceTokens(e){this.actionTokens.deleteActionTokensForSessionByKind(e,"repo-policy-set")}clearPlanDecisionTokens(e,n){this.actionTokens.deletePlanDecisionTokensForSession(e,n)}makeActionButton(e,n,r,o={}){let i=this.createActionToken(e,n,{label:r,...o});return{label:r,callbackData:i.id,style:this.resolveButtonStyle(n)}}resolveButtonStyle(e){switch(e){case"plan-approve":case"worktree-create-pr":case"worktree-update-pr":case"plan-offer-start":case"repo-policy-set":return"primary";case"worktree-merge":case"session-resume":case"session-restart":case"plugin-update-install":case"plugin-update-restart":return"success";case"plugin-update-remind-later":return"secondary";case"plan-reject":case"worktree-dismiss":case"plugin-update-dismiss":return"danger";default:return"secondary"}}getWorktreeDecisionButtons(e,n,r={merge:!0,pr:!0}){if(!n)return[];let o=[],i=[];if(r.merge&&i.push(this.makeActionButton(e,"worktree-merge","Merge")),r.pr&&this.isGitHubCliAvailable())n.worktreePrUrl?(i.push(this.makeActionButton(e,"worktree-view-pr","View PR",{targetUrl:n.worktreePrUrl})),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-update-pr","Sync PR"),this.makeActionButton(e,"worktree-decide-later","Later")])):(i.push(this.makeActionButton(e,"worktree-create-pr","Open PR")),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-decide-later","Later"),this.makeActionButton(e,"worktree-dismiss","Discard")]));else return o.push([...i,this.makeActionButton(e,"worktree-decide-later","Later")]),o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o;return n.worktreePrUrl&&o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o}getPlanApprovalButtons(e,n){let r=n?.actionablePlanDecisionVersion??n?.planDecisionVersion;this.clearPlanDecisionTokens(e,r);let o=[[this.makeActionButton(e,"plan-approve","Approve",{planDecisionVersion:r}),this.makeActionButton(e,"plan-request-changes","Revise",{planDecisionVersion:r}),this.makeActionButton(e,"plan-reject","Reject",{planDecisionVersion:r})]];return B("plan_approval_buttons_created",{sessionId:e,planDecisionVersion:r,...X(o)}),o}getResumeButtons(e,n){let r=[];return n.isExplicitlyResumable&&r.push(this.makeActionButton(e,"session-resume","Resume")),r.push(this.makeActionButton(e,"view-output","View output")),[r]}getQuestionButtons(e,n,r={}){if(n.length===0)return;let o=n.map((s,a)=>{let d=this.createActionToken(e,"question-answer",{label:s.label,optionIndex:a,pendingInputRequestId:r.requestId,pendingInputQuestionId:r.questionId});return{label:RS(s.label),callbackData:d.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=_c)i.push(o.slice(s,s+_c));return i}getPlanOfferButtons(e){let{offerId:n,route:r,planName:o,planPrompt:i,planWorkdir:s,planWorktreeStrategy:a}=e,d=[[this.makeActionButton(n,"plan-offer-start","Start Plan",{route:r,launchName:o,launchPrompt:i,launchWorkdir:s,launchWorktreeStrategy:a}),this.makeActionButton(n,"plan-offer-dismiss","Dismiss",{route:r})]];return B("plan_offer_buttons_created",{offerId:n,planName:o,channel:r.provider,target:r.target,accountId:r.accountId,threadId:r.threadId,sessionKey:r.sessionKey,planPromptLength:i.length,planWorkdirLength:s.length,planWorktreeStrategy:a,...X(d)}),d}getRepoPolicyChoiceButtons(e){let n=Dn(e.prAvailable??!0),r=Array.from({length:Math.ceil(n.length/2)},(o,i)=>n.slice(i*2,i*2+2)).map(o=>o.map(i=>this.makeActionButton(e.choiceId,"repo-policy-set",i.label,{route:e.route,repoPolicy:i.policy,repoPolicyWorkdir:e.repoRoot,launchName:e.launchName,launchPrompt:e.launchPrompt,launchWorkdir:e.launchWorkdir,launchModel:e.launchModel,launchReasoningEffort:e.launchReasoningEffort,launchFastMode:e.launchFastMode,launchSystemPrompt:e.launchSystemPrompt,launchAllowedTools:e.launchAllowedTools,launchResumeSessionId:e.launchResumeSessionId,launchResumedFromSessionName:e.launchResumedFromSessionName,launchResumeWorktreeFrom:e.launchResumeWorktreeFrom,launchSessionIdOverride:e.launchSessionIdOverride,launchClearedPersistedCodexResume:e.launchClearedPersistedCodexResume,launchForkSession:e.launchForkSession,launchForceNewSession:e.launchForceNewSession,launchPermissionMode:e.launchPermissionMode,launchPlanApproval:e.launchPlanApproval,launchHarness:e.launchHarness,launchWorktreeStrategy:e.launchWorktreeStrategy,launchWorktreeBaseBranch:e.launchWorktreeBaseBranch,launchWorktreePrTargetRepo:e.launchWorktreePrTargetRepo,launchOriginAgentId:e.launchOriginAgentId})));return 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),...X(r)}),r}};ne();ke();import{createHash as TS}from"crypto";var AS="duplicate notification already delivered or in flight",oi=class{maxRecords;inFlightTtlMs;now;inFlight=new Set;delivered=new Set;constructor(e={}){this.maxRecords=Math.max(1,Math.floor(e.maxRecords??64)),this.inFlightTtlMs=Math.max(1,Math.floor(e.inFlightTtlMs??6e5)),this.now=e.now??(()=>new Date)}claim(e,n,r){if(!e)return{allowed:!0};let o=this.now(),i=this.prune(n??[],o),s=i.find(a=>a.key===e);return this.delivered.has(e)||this.inFlight.has(e)||s?.status==="delivered"||s?.status==="in_flight"&&this.isFreshInFlight(s,o)?{allowed:!1,records:i,reason:AS}:(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))}};ke();ne();ke();import{createHash as IS}from"crypto";var xS=1024,Zn="duplicate completion follow-up wake already handled",ii="prior human-visible summary already delivered",si=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??xS))}decide(e,n,r){if(n?.required!==!0)return{required:!1,allowed:!1,explicit:!1};let o=this.buildKeySet(e,n);if(!o)return{required:!0,allowed:!0,explicit:!1};let i=this.normalizeRecords(r),s=this.buildPersistedKeyMap(i),a=o.decisionKeys.find(u=>this.inFlight.has(u)||!!this.getCompletedRecord(u)||s.has(u)),d=a?this.getCompletedRecord(a):void 0,l=a?s.get(a):void 0;return a?{required:!0,allowed:!1,explicit:o.explicit,dedupeKey:o.primary,skipReason:d?.skipReason??l?.skipReason??Zn}:(this.registerClaim(o.primary,o.claimKeys),{required:!0,allowed:!0,key:o.primary,explicit:o.explicit})}recordVisibleDelivery(e,n,r,o){if(n.required!==!0)return{required:!1,allowed:!1,explicit:!1};let i=this.buildKeySet(e,n);if(!i)return{required:!0,allowed:!0,explicit:!1};let s=this.normalizeRecords(r),a=this.buildPersistedKeyMap(s),d=i.decisionKeys.find(p=>!!this.getCompletedRecord(p)||a.has(p)),l=d?this.getCompletedRecord(d):void 0,u=d?a.get(d):void 0;if(l||u)return{required:!0,allowed:!1,explicit:i.explicit,dedupeKey:i.primary,skipReason:l?.skipReason??u?.skipReason};this.finishKeys(i.primary,i.claimKeys,!0,ii);let f=this.deliveredRecords(i.claimKeys,s,o,ii);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:f}}finish(e,n,r=Zn){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=Zn){if(!e)return;let i=this.claimKeysByPrimary.get(e)??[e];return this.deliveredRecords(i,n,r,o)}registerClaim(e,n){for(let r of n)this.inFlight.add(r);for(this.claimKeysByPrimary.delete(e),this.claimKeysByPrimary.set(e,n);this.claimKeysByPrimary.size>this.maxCompletedKeys;){let r=this.claimKeysByPrimary.keys().next().value;if(r===void 0)break;let o=this.claimKeysByPrimary.get(r)??[r];for(let i of o)this.inFlight.delete(i);this.claimKeysByPrimary.delete(r)}}finishKeys(e,n,r,o=Zn){for(let i of n)this.inFlight.delete(i);if(this.claimKeysByPrimary.delete(e),!!r){for(let i of n)this.completed.get(i)?.skipReason===ii&&o!==ii||(this.completed.delete(i),this.completed.set(i,{skipReason:o,linkedKeys:n.filter(a=>a!==i)}));for(;this.completed.size>this.maxCompletedKeys;){let i=this.completed.keys().next().value;if(i===void 0)break;this.completed.delete(i)}}}buildKeySet(e,n){let r=this.getDeliveryRef(e);if(!r)return;let o=this.normalizeOutcomeKey(e,n.outcomeKey?.trim());if(o){let a=`${this.buildVisibleScope(r,e)}:outcome:${this.digest(o)}`,d=this.isGoalLike(e,n,o),l=this.buildSessionAliasKeys(r,e,"visible-summary"),u=this.buildSessionAliasKeys(r,e,"goal-summary"),f=this.isTerminalLike(n,o),p=o.startsWith("worktree-pr:")?this.normalizeWorktreePrOutcome(n.outcomeKey?.trim()):void 0,k=p?.aliases.map(m=>`${this.buildVisibleScope(r,e)}:outcome:${this.digest(m)}`)??[];return{primary:a,explicit:!0,claimKeys:[...l,...d?u:[],...k,a],decisionKeys:[a,...p?.blocksAliases?k:[],...d||f?l:[],...u]}}let i=n.fallbackFingerprint?.trim();if(!i)return;let s=`${r}:${n.producer}:${this.digest(i)}`;return{primary:s,explicit:!1,claimKeys:[s],decisionKeys:[s]}}isGoalLike(e,n,r){return!!e.goalTaskId?.trim()||n.producer==="goal"||/^goal:/i.test(r)}isTerminalLike(e,n){return e.producer==="terminal"||/^terminal:/i.test(n)}normalizeOutcomeKey(e,n){let r=e.goalTaskId?.trim();if(r)return`goal:${r}`;let o=this.normalizeWorktreePrOutcome(n);return o?o.primary:n}normalizeWorktreePrOutcome(e){if(!e)return;let n=e.split(":");if(n[0]!=="worktree-pr"||n.length<5)return;let r=n[1]?.trim().toLowerCase();if(!r||!/^(?:draft-)?(?:opened|updated)$/.test(r))return;let o=n[2]?.trim()||"default-repo",i=n[3]?.trim();if(!i)return;let s=this.normalizePrIdentity(i),a=n[4]?.trim();if(!s||!a)return;let d=["worktree-pr",o.toLowerCase(),s,a].join(":"),l=`${d}:created`;if(r.endsWith("updated")){let u=n.slice(5).join(":").trim();return{primary:u?`${d}:updated:${u}`:`${d}:updated`,aliases:[l,d],blocksAliases:!1}}return{primary:l,aliases:[d],blocksAliases:!0}}normalizePrIdentity(e){let n=e.match(/#?(\d+)$/);if(n?.[1])return`#${n[1]}`;let r=e.match(/\/pull\/(\d+)(?:\b|\/|$)/);if(r?.[1])return`#${r[1]}`;let o=e.trim();return o||void 0}buildVisibleScope(e,n){let r=Ve(n);return r?`route:${this.digest(JSON.stringify({provider:r.provider,accountId:r.accountId,target:r.target,threadId:r.threadId}))}`:e}buildSessionAliasKeys(e,n,r){let o=this.buildVisibleScope(e,n),i=["id"in n?n.id:void 0,"sessionId"in n?n.sessionId:void 0,n.name,O(n),n.harnessSessionId,e].map(s=>s?.trim()).filter(s=>!!s);return[...new Set(i)].map(s=>`${o}:session:${this.digest(s)}:${r}`)}getDeliveryRef(e){return G(e)??O(e)??""}digest(e){return IS("sha256").update(e).digest("hex").slice(0,16)}normalizeRecords(e){return e?.length?e.filter(n=>n.key.trim()&&Number.isFinite(Date.parse(n.recordedAt))).slice(-this.maxCompletedKeys):[]}buildPersistedKeyMap(e){let n=new Map;for(let r of e){n.set(r.key,r);for(let o of r.linkedKeys??[])o.trim()&&n.set(o,r)}return n}getCompletedRecord(e){let n=this.completed.get(e);if(n)return n;for(let r of this.completed.values())if(r.linkedKeys?.includes(e))return r}deliveredRecords(e,n,r,o=Zn){let i=new Date().toISOString(),s=this.normalizeRecords(n),a=new Set(e),l=[...s.filter(u=>!a.has(u.key)&&!(u.linkedKeys??[]).some(f=>a.has(f))),...e.map(u=>{let f=e.filter(p=>p!==u);return{key:u,linkedKeys:f.length>0?f:void 0,recordedAt:i,label:r,skipReason:o}})];return l.slice(Math.max(0,l.length-this.maxCompletedKeys))}};var CS=2e3,MS=new Set(["1","true","yes","on"]);function _S(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&MS.has(t))||Ri()}function $S(t){_S()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
261
- `)}function ES(t){let e=t?.trim().split(":")??[];if(e[0]!=="worktree-pr")return;let n=e[1]?.toLowerCase();if(n==="updated"||n==="draft-updated")return"pr-updated";if(n==="opened"||n==="draft-opened")return"pr-opened"}var ai=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new si({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new oi({maxRecords:r.maxNotificationDedupeRecords}),this.getPersistedSession=r.getPersistedSession}wakeDispatcher;applyPersistedPatch;completionSummaries;notificationDedupe;getPersistedSession;dispatch(e,n){let r=this.getDeliveryRef(e),o=this.getPersistedSession?.(r),i=this.buildNotificationDedupeKey(e,n),s=this.notificationDedupe.claim(i,o?.notificationDedupe,n.label);if(s.records&&this.applyNotificationDedupePatch(r,s.records),!s.allowed){this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:i,decision:"skip",reason:s.reason??"duplicate notification skipped",deliveryPath:"notify"}),n.hooks?.onDuplicateSkipped?.(s.reason??"duplicate notification skipped");return}let a=this.buildCompletionSummaryFact(n),d=n.completionSummaryOwner==="foreground"&&a?.required===!0,l=d?this.completionSummaries.recordVisibleDelivery(e,a,o?.completionSummaryDedupe,n.label):this.completionSummaries.decide(e,a,o?.completionSummaryDedupe);l.records&&this.applyCompletionSummaryDedupePatch(r,l.records);let u=d?this.withoutCompletionWake(n):n;if(l.required&&!l.allowed)if(this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:l.dedupeKey??l.key,outcomeKey:a?.outcomeKey,decision:d?"skip":l.explicit?"send_without_followup":"skip",reason:l.skipReason??"completion follow-up wake suppressed",deliveryPath:d?"foreground-summary":"wake",followupKind:a?.producer}),n.hooks?.onWakeSkipped?.(l.skipReason??"completion follow-up wake suppressed"),d){this.releaseNotificationDedupe(r,i);return}else if(l.explicit)u=this.withoutCompletionWake(n);else{this.releaseNotificationDedupe(r,i);return}a?.required===!0&&this.logNotificationDecision({session:e,request:u,deliveryRef:r,dedupeKey:l.dedupeKey??l.key,outcomeKey:a.outcomeKey,decision:d?"record_visible":u.completionWakeSummaryRequired===!0?"send_with_followup":"send_without_followup",reason:d?"foreground summary owns completion follow-up":void 0,deliveryPath:d?"foreground-summary":"wake",followupKind:a.producer});let f=this.buildCompletionWakePatch(u),p=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifySuccess?.trim()),k=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifyFailed?.trim()),m=!1,c=!1,h=()=>{c||(c=!0,m||(this.releaseNotificationDedupe(r,i),m=!0),this.completionSummaries.finish(l.key,!1))},S=u.shouldDispatch?()=>{let x=u.shouldDispatch?.()!==!1;return x||h(),x}:void 0,b={onNotifyStarted:()=>{this.applyDeliveryState(r,"notifying"),u.hooks?.onNotifyStarted?.()},onNotifySucceeded:()=>{m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.applyNotifyDeliveryState(r,p?"wake_pending":"idle",p?f:void 0),p||this.completionSummaries.finish(l.key,!1),u.hooks?.onNotifySucceeded?.()},onNotifyFailed:()=>{this.applyNotifyDeliveryState(r,k?"wake_pending":"failed",k?f:void 0),k||(this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),m=!0),u.hooks?.onNotifyFailed?.()},onWakeStarted:()=>{this.applyPersistedPatchWithCompletionWake(r,"wake_pending",f,{completionWakeIssuedAt:new Date().toISOString(),completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),u.hooks?.onWakeStarted?.()},onWakeSucceeded:()=>{m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(f),{completionWakeSucceededAt:new Date().toISOString(),completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSucceeded?.()},onWakeSkipped:x=>{if(c){u.hooks?.onWakeSkipped?.(x);return}m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label,x),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(f),{completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:new Date().toISOString(),completionWakeSkipReason:x}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSkipped?.(x)},onWakeFailed:()=>{this.applyPersistedPatchWithCompletionWake(r,"failed",f,{completionWakeFailedAt:new Date().toISOString()}),this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),m=!0,u.hooks?.onWakeFailed?.()}};this.wakeDispatcher.dispatchSessionNotification(e,{...u,idempotencyKey:i??u.idempotencyKey,shouldDispatch:S,hooks:b})}notifyWorktreeOutcome(e,n,r={}){let o=this.getDeliveryRef(e),i=ES(r.completionWakeOutcomeKey);o&&i&&this.applyPersistedPatch(o,{worktreeRemoteOutcome:i});let s=DS(n,e),a=f=>an({sessionId:o,sessionName:e.name,outcomeLine:s,originThreadLine:hn(e),detailLines:r.detailLines,canonicalStatusDelivered:f}),d=r.summaryWakeRequired??!0,l={required:d,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},u=r.completionSummaryOwner!=="foreground";if(d&&!u){let f=this.getDeliveryRef(e),p=this.completionSummaries.recordVisibleDelivery(e,l,f?this.getPersistedSession?.(f)?.completionSummaryDedupe:void 0,"worktree-outcome");p.records&&this.applyCompletionSummaryDedupePatch(f,p.records)}this.dispatch(e,{label:"worktree-outcome",userMessage:s,notifyUser:"always",requireDirectUserNotification:!0,completionSummary:{...l,required:d&&u},completionWakeSummaryRequired:d&&u,completionWakeOutcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`,idempotencyKey:`worktree-outcome:${r.completionWakeOutcomeKey??n}`,deferConditionalWakeUntilNextTick:!0,deferConditionalWakeMs:CS,wakeMessageOnNotifySuccess:d&&u?a(!0):void 0,wakeMessageOnNotifyFailed:d&&u?a(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return G(e)??O(e)??""}applyDeliveryState(e,n){!e||!n||this.applyPersistedPatch(e,{deliveryState:n})}applyNotifyDeliveryState(e,n,r){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r}:{deliveryState:n})}applyPersistedPatchWithCompletionWake(e,n,r,o){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r,...o}:{deliveryState:n})}buildCompletionWakePatch(e){if(e.completionWakeSummaryRequired===!0)return{completionWakeSummaryRequired:!0}}buildCompletionWakeSucceededPatch(e){if(e)return{completionWakeSummaryRequired:void 0}}withoutCompletionWake(e){return{...e,completionSummary:e.completionSummary?{...e.completionSummary,required:!1}:void 0,wakeMessage:void 0,wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:void 0,completionWakeSummaryRequired:!1}}buildCompletionSummaryFact(e){if(e.completionSummary)return e.completionSummary;if(e.completionWakeSummaryRequired!==!0)return;let n=[e.wakeMessage,e.wakeMessageOnNotifySuccess,e.wakeMessageOnNotifyFailed].map(r=>r?.trim()).filter(r=>!!r);return{required:!0,producer:"legacy",outcomeKey:e.completionWakeOutcomeKey,fallbackFingerprint:n.length>0?`${e.label}
260
+ `);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=Sa(e[r]);if(o.trim())return o}return""}var ni=class{routes=new ei;transport;directNotifications;executor=new Xo;constructor(e={}){this.transport=e.transport??new ti(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new Nt:e.directNotifications}clearPendingRetries(){this.executor.clearPendingRetries()}clearRetryTimersForSession(e){this.executor.clearRetryTimersForSession(e)}dispose(){this.executor.dispose()}buildDispatchContext(e){let n=e.buttons??[],r=n.flat();return{transportRoute:e.routeSummary,transportChannel:e.route?.channel??"system",transportTarget:e.route?.target??"system",transportAccountId:e.route?.accountId,transportThreadId:e.route?.threadId,transportSessionKey:e.route?.sessionKey,messageTextLength:e.text.length,buttonsPresent:r.length>0,buttonRows:n.length||void 0,buttonCount:r.length||void 0,buttonLabels:r.length>0?r.map(o=>o.label):void 0,maxCallbackDataLength:r.length>0?Math.max(...r.map(o=>o.callbackData.length)):void 0}}sendWake(e,n,r,o,i,s,a,d,l,u){let f=this.routes.resolve(e),p=a;if(p?.()===!1)return;let k=f?.sessionKey?.trim();if(!k){this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-system`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:l,onFinalFailure:i,successValidator:d,shouldContinue:p});return}this.executor.execute(this.transport.buildChatSendArgs(k,n,!0,u),{label:r,sessionId:e.id,target:"chat.send",phase:o,routeSummary:`session:${k}`,messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:`session:${k}`,route:f,text:n}),onSuccess:s,onSkipped:l,successValidator:d,shouldContinue:p,onFinalFailure:()=>{p?.()!==!1&&this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-fallback`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:l,onFinalFailure:i,successValidator:d,shouldContinue:p})}})}sendUserNotification(e,n,r,o,i,s,a=!1,d){if(d?.()===!1)return;let l=!!o?.some(m=>Array.isArray(m)&&m.length>0),u=this.routes.resolve(e);B("wake_notify_selected",{sessionId:e.id,sessionName:e.name,label:r,messageTextLength:n.length,requireDirectDelivery:a,hasDirectNotificationTransport:!!this.directNotifications,routeSummary:u?this.routes.summary(u):"system",channel:u?.channel,target:u?.target,accountId:u?.accountId,threadId:u?.threadId,sessionKey:u?.sessionKey,...X(o)});let f=u?`notify:${u.channel}|${u.accountId??""}|${u.target}|${u.threadId??""}`:`notify:system:${e.id}`;if(!u){if(B("wake_notify_no_direct_route",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:l,...X(o)}),a){`${r}${e.id}`,i?.();return}if(l){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-system`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n,buttons:o}),orderingKey:f,onSuccess:s,onFinalFailure:i,shouldContinue:d});return}let p=()=>{if(B("wake_notify_direct_failed",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:l,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...X(o)}),a){`${r}${e.id}`,i?.();return}if(l){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-fallback`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),orderingKey:f,onSuccess:s,onFinalFailure:i,shouldContinue:d})},k={label:`${r}-notify`,sessionId:e.id,target:"message.send",phase:"notify",routeSummary:this.routes.summary(u),messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:this.routes.summary(u),route:u,text:n,buttons:o}),orderingKey:f,onSuccess:s,onAmbiguousResult:p,onFinalFailure:p,terminalOnFailure:this.directNotifications?!0:void 0,shouldContinue:d};if(this.directNotifications){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,...X(o)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,o),k);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,...X(o)}),this.executor.execute(this.transport.buildDirectNotificationArgs(u,n,o),k)}sendUserNotificationSequence(e,n,r,o,i,s=!1,a){let d=n.map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0);if(d.length===0){o?.();return}B("wake_notify_sequence_started",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length,buttonChunkIndexes:d.map((u,f)=>u.buttons?.some(p=>Array.isArray(p)&&p.length>0)?f+1:void 0).filter(u=>typeof u=="number"),requireDirectDelivery:s});let l=u=>{if(a?.()===!1)return;let f=d[u];if(!f){B("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length}),i?.();return}let p=u===0?o:i;B("wake_notify_sequence_chunk_selected",{sessionId:e.id,sessionName:e.name,label:r,chunkIndex:u+1,chunkCount:d.length,messageTextLength:f.text.length,failureHandler:u===0?"all-failed":"sequence-success",...X(f.buttons)}),this.sendUserNotification(e,f.text,`${r}-part-${u+1}`,f.buttons,p,()=>l(u+1),s,a)};l(0)}dispatchSessionNotification(e,n){let r=n.hooks,o=n.wakeMessageOnNotifySuccess!=null||n.wakeMessageOnNotifyFailed!=null,i=n.notifyUser??(n.wakeMessage?"on-wake-fallback":"always"),s=(n.userMessages?.length?n.userMessages:n.userMessage?.trim()?[{text:n.userMessage.trim(),buttons:n.buttons}]:[]).map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0),a=n.wakeMessage?.trim(),d=n.shouldDispatch,l=n.completionWakeSummaryRequired===!0?PS:void 0;if(o){let u=n.wakeMessageOnNotifySuccess?.trim(),f=n.wakeMessageOnNotifyFailed?.trim(),p=h=>{h&&d?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,h,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,d,l,r?.onWakeSkipped,n.idempotencyKey))},k=h=>{if(h){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let S=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>p(h),S).unref?.();return}p(h)}},m=()=>{d?.()!==!1&&(r?.onNotifySucceeded?.(),u&&k(u))},c=f?()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),k(f))}:()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,c,m,n.requireDirectUserNotification===!0,d)}else c();return}if(i==="always"&&s.length>0){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{d?.()!==!1&&r?.onNotifySucceeded?.()},n.requireDirectUserNotification===!0,d)}if(a&&d?.()!==!1){if(r?.onWakeStarted?.(),i==="on-wake-fallback"&&s.length>0&&!this.routes.resolve(e)?.sessionKey){if(d?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{d?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{d?.()!==!1&&r?.onNotifySucceeded?.()},!1,d)}this.sendWake(e,a,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,d,l,r?.onWakeSkipped,n.idempotencyKey)}}};var Mc=36,_c=2,$c="...";function RS(t){let e=Array.from(t);return e.length<=Mc?t:`${e.slice(0,Mc-$c.length).join("")}${$c}`}var ri=class{constructor(e,n){this.actionTokens=e;this.isGitHubCliAvailable=n}actionTokens;isGitHubCliAvailable;createActionToken(e,n,r={}){return this.actionTokens.createActionToken(e,n,{expiresAt:Date.now()+10080*60*1e3,...r})}consumeActionToken(e){return this.actionTokens.consumeActionToken(e)}consumeQuestionAnswerTokens(e,n,r){return this.actionTokens.consumeQuestionAnswerTokens(e,n,r)}getActionToken(e){return this.actionTokens.getActionToken(e)}listActiveActionTokens(e){return this.actionTokens.listActiveActionTokens(e)}clearRepoPolicyChoiceTokens(e){this.actionTokens.deleteActionTokensForSessionByKind(e,"repo-policy-set")}clearPlanDecisionTokens(e,n){this.actionTokens.deletePlanDecisionTokensForSession(e,n)}makeActionButton(e,n,r,o={}){let i=this.createActionToken(e,n,{label:r,...o});return{label:r,callbackData:i.id,style:this.resolveButtonStyle(n)}}resolveButtonStyle(e){switch(e){case"plan-approve":case"worktree-create-pr":case"worktree-update-pr":case"plan-offer-start":case"repo-policy-set":return"primary";case"worktree-merge":case"session-resume":case"session-restart":case"plugin-update-install":case"plugin-update-restart":return"success";case"plugin-update-remind-later":return"secondary";case"plan-reject":case"worktree-dismiss":case"plugin-update-dismiss":return"danger";default:return"secondary"}}getWorktreeDecisionButtons(e,n,r={merge:!0,pr:!0}){if(!n)return[];let o=[],i=[];if(r.merge&&i.push(this.makeActionButton(e,"worktree-merge","Merge")),r.pr&&this.isGitHubCliAvailable())n.worktreePrUrl?(i.push(this.makeActionButton(e,"worktree-view-pr","View PR",{targetUrl:n.worktreePrUrl})),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-update-pr","Sync PR"),this.makeActionButton(e,"worktree-decide-later","Later")])):(i.push(this.makeActionButton(e,"worktree-create-pr","Open PR")),i.length>0&&o.push(i),o.push([this.makeActionButton(e,"worktree-decide-later","Later"),this.makeActionButton(e,"worktree-dismiss","Discard")]));else return o.push([...i,this.makeActionButton(e,"worktree-decide-later","Later")]),o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o;return n.worktreePrUrl&&o.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),o}getPlanApprovalButtons(e,n){let r=n?.actionablePlanDecisionVersion??n?.planDecisionVersion;this.clearPlanDecisionTokens(e,r);let o=[[this.makeActionButton(e,"plan-approve","Approve",{planDecisionVersion:r}),this.makeActionButton(e,"plan-request-changes","Revise",{planDecisionVersion:r}),this.makeActionButton(e,"plan-reject","Reject",{planDecisionVersion:r})]];return B("plan_approval_buttons_created",{sessionId:e,planDecisionVersion:r,...X(o)}),o}getResumeButtons(e,n){let r=[];return n.isExplicitlyResumable&&r.push(this.makeActionButton(e,"session-resume","Resume")),r.push(this.makeActionButton(e,"view-output","View output")),[r]}getQuestionButtons(e,n,r={}){if(n.length===0)return;let o=n.map((s,a)=>{let d=this.createActionToken(e,"question-answer",{label:s.label,optionIndex:a,pendingInputRequestId:r.requestId,pendingInputQuestionId:r.questionId});return{label:RS(s.label),callbackData:d.id,style:this.resolveButtonStyle("question-answer")}}),i=[];for(let s=0;s<o.length;s+=_c)i.push(o.slice(s,s+_c));return i}getPlanOfferButtons(e){let{offerId:n,route:r,planName:o,planPrompt:i,planWorkdir:s,planWorktreeStrategy:a}=e,d=[[this.makeActionButton(n,"plan-offer-start","Start Plan",{route:r,launchName:o,launchPrompt:i,launchWorkdir:s,launchWorktreeStrategy:a}),this.makeActionButton(n,"plan-offer-dismiss","Dismiss",{route:r})]];return B("plan_offer_buttons_created",{offerId:n,planName:o,channel:r.provider,target:r.target,accountId:r.accountId,threadId:r.threadId,sessionKey:r.sessionKey,planPromptLength:i.length,planWorkdirLength:s.length,planWorktreeStrategy:a,...X(d)}),d}getRepoPolicyChoiceButtons(e){let n=Dn(e.prAvailable??!0),r=Array.from({length:Math.ceil(n.length/2)},(o,i)=>n.slice(i*2,i*2+2)).map(o=>o.map(i=>this.makeActionButton(e.choiceId,"repo-policy-set",i.label,{route:e.route,repoPolicy:i.policy,repoPolicyWorkdir:e.repoRoot,launchName:e.launchName,launchPrompt:e.launchPrompt,launchWorkdir:e.launchWorkdir,launchModel:e.launchModel,launchReasoningEffort:e.launchReasoningEffort,launchFastMode:e.launchFastMode,launchSystemPrompt:e.launchSystemPrompt,launchAllowedTools:e.launchAllowedTools,launchResumeSessionId:e.launchResumeSessionId,launchResumedFromSessionName:e.launchResumedFromSessionName,launchResumeWorktreeFrom:e.launchResumeWorktreeFrom,launchSessionIdOverride:e.launchSessionIdOverride,launchClearedPersistedCodexResume:e.launchClearedPersistedCodexResume,launchForkSession:e.launchForkSession,launchForceNewSession:e.launchForceNewSession,launchPermissionMode:e.launchPermissionMode,launchPlanApproval:e.launchPlanApproval,launchHarness:e.launchHarness,launchWorktreeStrategy:e.launchWorktreeStrategy,launchWorktreeBaseBranch:e.launchWorktreeBaseBranch,launchWorktreePrTargetRepo:e.launchWorktreePrTargetRepo,launchOriginAgentId:e.launchOriginAgentId})));return 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),...X(r)}),r}};ne();ke();import{createHash as TS}from"crypto";var AS="duplicate notification already delivered or in flight",oi=class{maxRecords;inFlightTtlMs;now;inFlight=new Set;delivered=new Set;constructor(e={}){this.maxRecords=Math.max(1,Math.floor(e.maxRecords??64)),this.inFlightTtlMs=Math.max(1,Math.floor(e.inFlightTtlMs??6e5)),this.now=e.now??(()=>new Date)}claim(e,n,r){if(!e)return{allowed:!0};let o=this.now(),i=this.prune(n??[],o),s=i.find(a=>a.key===e);return this.delivered.has(e)||this.inFlight.has(e)||s?.status==="delivered"||s?.status==="in_flight"&&this.isFreshInFlight(s,o)?{allowed:!1,records:i,reason:AS}:(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))}};ke();ne();ke();import{createHash as IS}from"crypto";var xS=1024,Zn="duplicate completion follow-up wake already handled",ii="prior human-visible summary already delivered",si=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??xS))}decide(e,n,r){if(n?.required!==!0)return{required:!1,allowed:!1,explicit:!1};let o=this.buildKeySet(e,n);if(!o)return{required:!0,allowed:!0,explicit:!1};let i=this.normalizeRecords(r),s=this.buildPersistedKeyMap(i),a=o.decisionKeys.find(u=>this.inFlight.has(u)||!!this.getCompletedRecord(u)||s.has(u)),d=a?this.getCompletedRecord(a):void 0,l=a?s.get(a):void 0;return a?{required:!0,allowed:!1,explicit:o.explicit,dedupeKey:o.primary,skipReason:d?.skipReason??l?.skipReason??Zn}:(this.registerClaim(o.primary,o.claimKeys),{required:!0,allowed:!0,key:o.primary,explicit:o.explicit})}recordVisibleDelivery(e,n,r,o){if(n.required!==!0)return{required:!1,allowed:!1,explicit:!1};let i=this.buildKeySet(e,n);if(!i)return{required:!0,allowed:!0,explicit:!1};let s=this.normalizeRecords(r),a=this.buildPersistedKeyMap(s),d=i.decisionKeys.find(p=>!!this.getCompletedRecord(p)||a.has(p)),l=d?this.getCompletedRecord(d):void 0,u=d?a.get(d):void 0;if(l||u)return{required:!0,allowed:!1,explicit:i.explicit,dedupeKey:i.primary,skipReason:l?.skipReason??u?.skipReason};this.finishKeys(i.primary,i.claimKeys,!0,ii);let f=this.deliveredRecords(i.claimKeys,s,o,ii);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:f}}finish(e,n,r=Zn){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=Zn){if(!e)return;let i=this.claimKeysByPrimary.get(e)??[e];return this.deliveredRecords(i,n,r,o)}registerClaim(e,n){for(let r of n)this.inFlight.add(r);for(this.claimKeysByPrimary.delete(e),this.claimKeysByPrimary.set(e,n);this.claimKeysByPrimary.size>this.maxCompletedKeys;){let r=this.claimKeysByPrimary.keys().next().value;if(r===void 0)break;let o=this.claimKeysByPrimary.get(r)??[r];for(let i of o)this.inFlight.delete(i);this.claimKeysByPrimary.delete(r)}}finishKeys(e,n,r,o=Zn){for(let i of n)this.inFlight.delete(i);if(this.claimKeysByPrimary.delete(e),!!r){for(let i of n)this.completed.get(i)?.skipReason===ii&&o!==ii||(this.completed.delete(i),this.completed.set(i,{skipReason:o,linkedKeys:n.filter(a=>a!==i)}));for(;this.completed.size>this.maxCompletedKeys;){let i=this.completed.keys().next().value;if(i===void 0)break;this.completed.delete(i)}}}buildKeySet(e,n){let r=this.getDeliveryRef(e);if(!r)return;let o=this.normalizeOutcomeKey(e,n.outcomeKey?.trim());if(o){let a=`${this.buildVisibleScope(r,e)}:outcome:${this.digest(o)}`,d=this.isGoalLike(e,n,o),l=this.buildSessionAliasKeys(r,e,"visible-summary"),u=this.buildSessionAliasKeys(r,e,"goal-summary"),f=this.isTerminalLike(n,o),p=o.startsWith("worktree-pr:")?this.normalizeWorktreePrOutcome(n.outcomeKey?.trim()):void 0,k=p?.aliases.map(m=>`${this.buildVisibleScope(r,e)}:outcome:${this.digest(m)}`)??[];return{primary:a,explicit:!0,claimKeys:[...l,...d?u:[],...k,a],decisionKeys:[a,...p?.blocksAliases?k:[],...d||f?l:[],...u]}}let i=n.fallbackFingerprint?.trim();if(!i)return;let s=`${r}:${n.producer}:${this.digest(i)}`;return{primary:s,explicit:!1,claimKeys:[s],decisionKeys:[s]}}isGoalLike(e,n,r){return!!e.goalTaskId?.trim()||n.producer==="goal"||/^goal:/i.test(r)}isTerminalLike(e,n){return e.producer==="terminal"||/^terminal:/i.test(n)}normalizeOutcomeKey(e,n){let r=e.goalTaskId?.trim();if(r)return`goal:${r}`;let o=this.normalizeWorktreePrOutcome(n);return o?o.primary:n}normalizeWorktreePrOutcome(e){if(!e)return;let n=e.split(":");if(n[0]!=="worktree-pr"||n.length<5)return;let r=n[1]?.trim().toLowerCase();if(!r||!/^(?:draft-)?(?:opened|updated)$/.test(r))return;let o=n[2]?.trim()||"default-repo",i=n[3]?.trim();if(!i)return;let s=this.normalizePrIdentity(i),a=n[4]?.trim();if(!s||!a)return;let d=["worktree-pr",o.toLowerCase(),s,a].join(":"),l=`${d}:created`;if(r.endsWith("updated")){let u=n.slice(5).join(":").trim();return{primary:u?`${d}:updated:${u}`:`${d}:updated`,aliases:[l,d],blocksAliases:!1}}return{primary:l,aliases:[d],blocksAliases:!0}}normalizePrIdentity(e){let n=e.match(/#?(\d+)$/);if(n?.[1])return`#${n[1]}`;let r=e.match(/\/pull\/(\d+)(?:\b|\/|$)/);if(r?.[1])return`#${r[1]}`;let o=e.trim();return o||void 0}buildVisibleScope(e,n){let r=Ve(n);return r?`route:${this.digest(JSON.stringify({provider:r.provider,accountId:r.accountId,target:r.target,threadId:r.threadId}))}`:e}buildSessionAliasKeys(e,n,r){let o=this.buildVisibleScope(e,n),i=["id"in n?n.id:void 0,"sessionId"in n?n.sessionId:void 0,n.name,O(n),n.harnessSessionId,e].map(s=>s?.trim()).filter(s=>!!s);return[...new Set(i)].map(s=>`${o}:session:${this.digest(s)}:${r}`)}getDeliveryRef(e){return G(e)??O(e)??""}digest(e){return IS("sha256").update(e).digest("hex").slice(0,16)}normalizeRecords(e){return e?.length?e.filter(n=>n.key.trim()&&Number.isFinite(Date.parse(n.recordedAt))).slice(-this.maxCompletedKeys):[]}buildPersistedKeyMap(e){let n=new Map;for(let r of e){n.set(r.key,r);for(let o of r.linkedKeys??[])o.trim()&&n.set(o,r)}return n}getCompletedRecord(e){let n=this.completed.get(e);if(n)return n;for(let r of this.completed.values())if(r.linkedKeys?.includes(e))return r}deliveredRecords(e,n,r,o=Zn){let i=new Date().toISOString(),s=this.normalizeRecords(n),a=new Set(e),l=[...s.filter(u=>!a.has(u.key)&&!(u.linkedKeys??[]).some(f=>a.has(f))),...e.map(u=>{let f=e.filter(p=>p!==u);return{key:u,linkedKeys:f.length>0?f:void 0,recordedAt:i,label:r,skipReason:o}})];return l.slice(Math.max(0,l.length-this.maxCompletedKeys))}};var CS=2e3,MS=new Set(["1","true","yes","on"]);function _S(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&MS.has(t))||Ri()}function $S(t){_S()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
261
+ `)}function ES(t){let e=t?.trim().split(":")??[];if(e[0]!=="worktree-pr")return;let n=e[1]?.toLowerCase();if(n==="updated"||n==="draft-updated")return"pr-updated";if(n==="opened"||n==="draft-opened")return"pr-opened"}var ai=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new si({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new oi({maxRecords:r.maxNotificationDedupeRecords}),this.getPersistedSession=r.getPersistedSession}wakeDispatcher;applyPersistedPatch;completionSummaries;notificationDedupe;getPersistedSession;dispatch(e,n){let r=this.getDeliveryRef(e),o=this.getPersistedSession?.(r),i=this.buildNotificationDedupeKey(e,n),s=this.notificationDedupe.claim(i,o?.notificationDedupe,n.label);if(s.records&&this.applyNotificationDedupePatch(r,s.records),!s.allowed){this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:i,decision:"skip",reason:s.reason??"duplicate notification skipped",deliveryPath:"notify"}),n.hooks?.onDuplicateSkipped?.(s.reason??"duplicate notification skipped");return}let a=this.buildCompletionSummaryFact(n),d=n.completionSummaryOwner==="foreground"&&a?.required===!0,l=d?this.completionSummaries.recordVisibleDelivery(e,a,o?.completionSummaryDedupe,n.label):this.completionSummaries.decide(e,a,o?.completionSummaryDedupe);l.records&&this.applyCompletionSummaryDedupePatch(r,l.records);let u=d?this.withoutCompletionWake(n):n;if(l.required&&!l.allowed)if(this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:l.dedupeKey??l.key,outcomeKey:a?.outcomeKey,decision:d?"skip":l.explicit?"send_without_followup":"skip",reason:l.skipReason??"completion follow-up wake suppressed",deliveryPath:d?"foreground-summary":"wake",followupKind:a?.producer}),n.hooks?.onWakeSkipped?.(l.skipReason??"completion follow-up wake suppressed"),d){this.releaseNotificationDedupe(r,i);return}else if(l.explicit)u=this.withoutCompletionWake(n);else{this.releaseNotificationDedupe(r,i);return}a?.required===!0&&this.logNotificationDecision({session:e,request:u,deliveryRef:r,dedupeKey:l.dedupeKey??l.key,outcomeKey:a.outcomeKey,decision:d?"record_visible":u.completionWakeSummaryRequired===!0?"send_with_followup":"send_without_followup",reason:d?"foreground summary owns completion follow-up":void 0,deliveryPath:d?"foreground-summary":"wake",followupKind:a.producer});let f=this.buildCompletionWakePatch(u),p=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifySuccess?.trim()),k=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifyFailed?.trim()),m=!1,c=!1,h=()=>{c||(c=!0,m||(this.releaseNotificationDedupe(r,i),m=!0),this.completionSummaries.finish(l.key,!1))},S=u.shouldDispatch?()=>{let x=u.shouldDispatch?.()!==!1;return x||h(),x}:void 0,P={onNotifyStarted:()=>{this.applyDeliveryState(r,"notifying"),u.hooks?.onNotifyStarted?.()},onNotifySucceeded:()=>{m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.applyNotifyDeliveryState(r,p?"wake_pending":"idle",p?f:void 0),p||this.completionSummaries.finish(l.key,!1),u.hooks?.onNotifySucceeded?.()},onNotifyFailed:()=>{this.applyNotifyDeliveryState(r,k?"wake_pending":"failed",k?f:void 0),k||(this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),m=!0),u.hooks?.onNotifyFailed?.()},onWakeStarted:()=>{this.applyPersistedPatchWithCompletionWake(r,"wake_pending",f,{completionWakeIssuedAt:new Date().toISOString(),completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),u.hooks?.onWakeStarted?.()},onWakeSucceeded:()=>{m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(f),{completionWakeSucceededAt:new Date().toISOString(),completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSucceeded?.()},onWakeSkipped:x=>{if(c){u.hooks?.onWakeSkipped?.(x);return}m=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label,x),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(f),{completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:new Date().toISOString(),completionWakeSkipReason:x}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSkipped?.(x)},onWakeFailed:()=>{this.applyPersistedPatchWithCompletionWake(r,"failed",f,{completionWakeFailedAt:new Date().toISOString()}),this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),m=!0,u.hooks?.onWakeFailed?.()}};this.wakeDispatcher.dispatchSessionNotification(e,{...u,idempotencyKey:i??u.idempotencyKey,shouldDispatch:S,hooks:P})}notifyWorktreeOutcome(e,n,r={}){let o=this.getDeliveryRef(e),i=ES(r.completionWakeOutcomeKey);o&&i&&this.applyPersistedPatch(o,{worktreeRemoteOutcome:i});let s=DS(n,e),a=f=>an({sessionId:o,sessionName:e.name,outcomeLine:s,originThreadLine:hn(e),detailLines:r.detailLines,canonicalStatusDelivered:f}),d=r.summaryWakeRequired??!0,l={required:d,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},u=r.completionSummaryOwner!=="foreground";if(d&&!u){let f=this.getDeliveryRef(e),p=this.completionSummaries.recordVisibleDelivery(e,l,f?this.getPersistedSession?.(f)?.completionSummaryDedupe:void 0,"worktree-outcome");p.records&&this.applyCompletionSummaryDedupePatch(f,p.records)}this.dispatch(e,{label:"worktree-outcome",userMessage:s,notifyUser:"always",requireDirectUserNotification:!0,completionSummary:{...l,required:d&&u},completionWakeSummaryRequired:d&&u,completionWakeOutcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`,idempotencyKey:`worktree-outcome:${r.completionWakeOutcomeKey??n}`,deferConditionalWakeUntilNextTick:!0,deferConditionalWakeMs:CS,wakeMessageOnNotifySuccess:d&&u?a(!0):void 0,wakeMessageOnNotifyFailed:d&&u?a(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return G(e)??O(e)??""}applyDeliveryState(e,n){!e||!n||this.applyPersistedPatch(e,{deliveryState:n})}applyNotifyDeliveryState(e,n,r){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r}:{deliveryState:n})}applyPersistedPatchWithCompletionWake(e,n,r,o){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r,...o}:{deliveryState:n})}buildCompletionWakePatch(e){if(e.completionWakeSummaryRequired===!0)return{completionWakeSummaryRequired:!0}}buildCompletionWakeSucceededPatch(e){if(e)return{completionWakeSummaryRequired:void 0}}withoutCompletionWake(e){return{...e,completionSummary:e.completionSummary?{...e.completionSummary,required:!1}:void 0,wakeMessage:void 0,wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:void 0,completionWakeSummaryRequired:!1}}buildCompletionSummaryFact(e){if(e.completionSummary)return e.completionSummary;if(e.completionWakeSummaryRequired!==!0)return;let n=[e.wakeMessage,e.wakeMessageOnNotifySuccess,e.wakeMessageOnNotifyFailed].map(r=>r?.trim()).filter(r=>!!r);return{required:!0,producer:"legacy",outcomeKey:e.completionWakeOutcomeKey,fallbackFingerprint:n.length>0?`${e.label}
262
262
  ${n.join(`
263
263
  ---completion-wake---
264
264
  `)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=Ve(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=Ve(e.session);$S({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 TS("sha256").update(e).digest("hex").slice(0,16)}};function DS(t,e){let n=ft(e);return n?`${t}${n}`:t}Ae();import{existsSync as OS}from"fs";var di=class{getCompletionState(e,n,r,o){let i=Mn(e,r,o);if(i===void 0)return"has-commits";if(i===0){let s=Mn(e,o,r);return s===void 0?"has-commits":s>0?ve(e,r,o)?"merged":"base-advanced":Rt(n)?"dirty-uncommitted":"no-change"}return Rt(n)?"dirty-uncommitted":Hr(e,r,o)?"released":"has-commits"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!OS(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 NS}from"node:crypto";function WS(t){let e=t.pendingInputState,n=e?.activeQuestionIndex??0;return e?.questions?.[n]?.id??(e?.activeQuestionIndex!=null?`q${e.activeQuestionIndex}`:void 0)}var li=class{constructor(e,n,r,o){this.pendingQuestions=e;this.dispatchSessionNotification=n;this.clearWaitingTimestamp=r;this.getQuestionButtons=o}pendingQuestions;dispatchSessionNotification;clearWaitingTimestamp;getQuestionButtons;async handleAskUserQuestion(e,n){let i=n?.questions??[];if(i.length===0)throw new Error("AskUserQuestion: no questions in input");let s=i[0],a=s.options??[],d=`❓ [${e.name}] ${s.question}`,l=WS(e),u=e.pendingInputState?.requestId??`legacy:${NS()}`,f=this.getQuestionButtons(e.id,a,{requestId:u,questionId:l}),p=[`[ASK USER QUESTION] Session "${e.name}" has a question requiring user input.`,"",`Question: ${s.question}`,...a.length>0?["Options:",...a.map((k,m)=>` ${m+1}. ${k.label}`)]:[],"",`Send the question to the user and call agent_respond(session="${e.id}", message="<answer>") with their answer.`].join(`
@@ -272,16 +272,16 @@ ${n.join(`
272
272
  `)}function tv(t){return t.options.map(e=>({label:e.label,description:e.description?.trim()??""})).filter(e=>e.description&&e.description.length<=ZS)}function Wc(t){let e=t?.activeQuestionIndex??0;return t?.questions?.[e]?.id??(t?.activeQuestionIndex!=null?`q${t.activeQuestionIndex}`:void 0)}function nv(t,e,n){let r=t.pendingInputState;return!!(r&&r.requestId===e&&Wc(r)===n)}function rv(t){return[t.startedAt??"unknown-started-at",t.result?.session_id??"unknown-backend-session",t.result?.num_turns??0].join(":")}function Nc(t){return[t.status,t.startedAt??"unknown-started-at",t.result?.session_id??"unknown-backend-session",t.result?.num_turns??0,t.killReason??"unknown"].join(":")}var mi=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:Qn({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>er(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:un(e,n,!0),wakeMessageOnNotifyFailed:ci({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:!!Ve(e)}async handleTurnEnd(e,n){if(e.status!=="running"){`${e.id}${e.status}`;return}if(!e.goalTaskId){if(n||e.pendingPlanApproval){await this.emitWaitingForInput(e);return}if(e.worktreeStrategy==="ask"||e.worktreeStrategy==="delegate"){`${e.id}${e.worktreeStrategy}`;return}this.deps.shouldEmitTurnCompleteWake(e)&&this.emitTurnComplete(e)}}async handleSessionTerminal(e){if(this.deps.persistSession(e),this.deps.clearWaitingTimestamp(e.id),e.goalTaskId){this.deps.clearRetryTimersForSession(e.id);return}let n={notificationSent:!1,worktreeRemoved:!1};e.worktreePath&&e.originalWorkdir&&(n=await this.deps.handleWorktreeStrategy(e));let r=!1;if(e.worktreePath&&e.originalWorkdir&&e.status==="failed"&&e.costUsd===0&&e.duration<3e4){let a=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath),d=e.worktreeBranch,l=ue(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(a&&!l&&(u=pe(a,e.worktreePath)),a&&d&&!l&&u&&be(a,d),u){for(let f of ge(e))this.deps.updatePersistedSession(f,{worktreePath:void 0,worktreeBranch:void 0});r=!0}}let o=e.worktreeStrategy&&e.worktreeStrategy!=="off"&&e.worktreeStrategy!=="manual";if(!r&&e.worktreePath&&e.originalWorkdir){let a=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath),d=ue(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:a&&!d&&pe(a,e.worktreePath)}if(n.notificationSent){`${e.id}`;return}if(e.killReason==="done"){if(this.deps.hasTurnCompleteWakeMarker(e.id)||!this.deps.shouldEmitTerminalWake(e))return;this.emitCompleted(e);return}if(e.status==="completed"){if(!this.deps.shouldEmitTerminalWake(e))return;this.emitCompleted(e);return}if(e.status==="failed"){if(!this.deps.shouldEmitTerminalWake(e))return;let a=e.error||e.result?.is_error&&e.result.result||e.result?.result||this.deps.extractLastOutputLine(e)||`Session failed with no error details (session=${e.id}, subtype=${e.result?.subtype??"none"}, turns=${e.result?.num_turns??0})`;this.emitFailed(e,ce(a,200),r);return}let i=`$${(e.costUsd??0).toFixed(2)}`,s=e.duration;if(e.killReason==="idle-timeout"){let a=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0;if(e.pendingPlanApproval){let d=e.actionablePlanDecisionVersion??e.planDecisionVersion,l=Xn(e,d);if(a==="delegate"){this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${d??"unknown"}:delegate`,wakeMessage:["[DELEGATED PLAN APPROVAL REMINDER] Plan review is still pending after the session hit idle timeout.",`Name: ${e.name} | ID: ${e.id}`,this.deps.originThreadLine(e),"The agent already produced a plan and is waiting for a delegated decision.","Review privately first. Approve directly with agent_respond(..., approve=true, approval_rationale='...') if the plan is clearly within scope and low risk.","Escalate only if needed via agent_request_plan_approval(summary='...').","If you approve directly, follow up with a short user-facing explanation; the plugin's thumbs-up line is only the minimal approval acknowledgment.","If a canonical approval prompt was already posted for this plan version, do not restate it in plain text."].join(`
273
273
  `),notifyUser:"never"}),this.deps.clearRetryTimersForSession(e.id);return}if(a==="ask"&&l){this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${d??"unknown"}:already-delivered`,notifyUser:"never",wakeMessage:["[PLAN APPROVAL REMINDER] The user already has an actionable plan review prompt for this plan version.",`Name: ${e.name} | ID: ${e.id} | Plan v${d??"?"}`,this.deps.originThreadLine(e),"Do NOT post another approval summary unless canonical delivery is known to be missing."].join(`
274
274
  `)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${d??"unknown"}:user-prompt`,userMessage:[`📋 [${e.name}] Plan v${d??"?"} still awaiting approval after idle timeout | ${i} | ${Be(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(`
275
- `),notifyUser:"always",buttons:a==="ask"&&!l?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:d}):void 0}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"suspended",idempotencyKey:`suspended:${e.id}:${e.killReason??"idle-timeout"}:${e.completedAt??"unknown"}`,userMessage:`💤 [${e.name}] Suspended after idle timeout | ${i} | ${Be(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${Js(e.killReason)} | ${i} | ${Be(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=Wc(e.pendingInputState),s=o?[o,i].filter(Boolean).join(":"):void 0,a=s?`pending-input:${s}`:void 0;if(!this.deps.debounceWaitingEvent(e.id,a))return;let d=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0,l=e.actionablePlanDecisionVersion??e.planDecisionVersion,u=e.pendingPlanApproval&&d==="ask"&&Xn(e,l),f=e.pendingInputState?.promptText?.trim()||void 0,p=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),k=!e.pendingPlanApproval&&f?f:!e.pendingPlanApproval&&p!==void 0?p:this.deps.getOutputPreview(e,e.pendingPlanApproval&&d!=="delegate"?Number.POSITIVE_INFINITY:void 0),m=e.pendingInputState?.options.map(w=>({label:w}))??[],c=!n||n.length===0?m:r&&r.options.length>0&&r.options.length<=6&&!r.options.some(w=>w.isOther)&&!r.multiSelect?r.options:n.length===1&&r&&r.options.length===0?m:[],h=e.pendingPlanApproval&&d==="ask"&&!u?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:l}):!e.pendingPlanApproval&&c.length?this.deps.getQuestionButtons(e.id,c,{requestId:e.pendingInputState?.requestId,questionId:r?.id}):void 0,S=XS(e,l),b=r?tv(r):[],x=r?ev({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:b}):f,T=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await Oc({sessionName:e.name,question:x??k,context:p,provider:this.deps.questionContextSummaryProvider}):void 0,A=la({session:e,preview:k,questionText:e.pendingPlanApproval?void 0:x,questionContextPreview:p,questionContextSummary:T,planArtifact:S,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:d,planApprovalButtons:h,questionButtons:e.pendingPlanApproval?void 0:h}),y=A.planReviewSummary??k;if(A.label==="plan-approval"&&d==="ask"&&u){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"never",buttons:A.buttons,wakeMessage:A.wakeMessage});return}if(A.label==="plan-approval"&&d==="ask"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"always",buttons:A.buttons,hooks:{onNotifyStarted:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.deps.updatePersistedSession(e.id,{canonicalPlanPromptVersion:l,approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>er(e,l),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,l,y),wakeMessageOnNotifySuccess:un(e,l)});return}if(A.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:wake-only`,userMessage:A.userMessage,wakeMessage:A.wakeMessage,notifyUser:"never",buttons:A.buttons});return}this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`waiting:${e.id}:${s??`${A.label}:${A.userMessage}`}`,userMessage:A.userMessage,notifyUser:"always",buttons:A.buttons,shouldDispatch:o?()=>nv(e,o,i):void 0,wakeMessageOnNotifyFailed:A.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=ta({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${rv(e)}`,userMessage:n.userMessage,wakeMessage:n.wakeMessage,notifyUser:"always",onUserNotifyFailed:()=>{`${e.id}`,this.deps.shouldEmitTerminalWake(e)&&this.emitCompleted(e)}})}emitCompleted(e){let n=this.deps.getOutputPreview(e),r=this.shouldRequestCompletionFollowup(e),o=Zs({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i=Nc(e),s=`terminal:${e.id}:${i}`,a;this.deps.dispatchSessionNotification(e,{label:"completed",idempotencyKey:`terminal-completed:${e.id}:${i}`,userMessage:o.userMessage,notifyUser:"always",completionSummary:{required:r,producer:"terminal",outcomeKey:s},completionWakeSummaryRequired:r,completionWakeOutcomeKey:s,requireDirectUserNotification:!0,wakeMessageOnNotifySuccess:r?o.wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:r?o.wakeMessageOnNotifyFailed:void 0,hooks:{onNotifySucceeded:()=>{a=!0,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_succeeded",canonicalStatusDelivered:a,followupSummaryRequired:r})},onNotifyFailed:()=>{a=!1,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_failed",canonicalStatusDelivered:a,followupSummaryRequired:r})},onWakeSucceeded:()=>{this.logCompletionWakeDiagnostic({session:e,event:"completion_wake_succeeded",canonicalStatusDelivered:a,followupSummaryRequired:r})}}})}emitFailed(e,n,r){let o=ea({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}:${Nc(e)}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};ne();Ae();import{existsSync as ov}from"fs";var fi=class{constructor(e){this.deps=e}deps;async dismissWorktree(e){let n=this.deps.getPersistedSession(e),r=this.deps.resolveActiveSession(e),o=r??n;if(!o)return`Error: Session "${e}" not found.`;let i=r?.worktreePath??n?.worktreePath,s=this.deps.resolveWorktreeRepoDir(r?.originalWorkdir??n?.workdir,i),a=r?.worktreeBranch??n?.worktreeBranch,d=r?.name??n?.name??e;if(!s)return`Error: No workdir found for session "${e}".`;let l=ue(o);!l&&i&&ov(i)&&pe(s,i,{destructive:!0}),a&&be(s,a);for(let f of ge(r??n))this.deps.updatePersistedSession(f,{worktreeDisposition:"dismissed",worktreeDismissedAt:new Date().toISOString(),pendingWorktreeDecisionSince:void 0,worktreeState:"dismissed",lifecycle:"terminal",worktreePath:void 0,worktreeBranch:void 0,worktreeLifecycle:{state:"dismissed",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"dismiss",baseBranch:n?.worktreeLifecycle?.baseBranch,targetRepo:n?.worktreePrTargetRepo,pushRemote:n?.worktreePushRemote}});let u=l?`🗑️ [${d}] Branch \`${a??"unknown"}\` dismissed. Native backend worktree released for backend cleanup.`:`🗑️ [${d}] Branch \`${a??"unknown"}\` dismissed and permanently deleted.`;return this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:G(r??n??{id:e})??e,sessionId:n?.sessionId,harnessSessionId:r?.harnessSessionId??n?.harnessSessionId,backendRef:r?.backendRef??n?.backendRef,route:r?.route??n?.route}),{label:"worktree-dismissed",idempotencyKey:`worktree-dismissed:${G(r??n??{id:e})??e}:${a??"unknown"}`,userMessage:u,notifyUser:"always"}),u}snoozeWorktreeDecision(e,n={}){let r=this.deps.getPersistedSession(e);if(!r)return`Error: Session "${e}" not found.`;let o=Date.now(),i=new Date(o+1440*60*1e3).toISOString();for(let d of ge(r))this.deps.updatePersistedSession(d,{worktreeDecisionSnoozedUntil:i,lastWorktreeReminderAt:new Date(o).toISOString()});let a=`⏭️ Reminder snoozed 24h for \`${r.worktreeBranch??"unknown"}\` (session: ${r.name})`;return n.notifyUser!==!1&&this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:G(r)??O(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${G(r)??O(r)??r.harnessSessionId}:${i}`,userMessage:a,notifyUser:"always"}),a}};var Lc=new Set(["starting","running"]);function Bc(t,e){JSON.stringify({component:"SessionRuntimeRegistry",event:t,at:new Date().toISOString(),...e})}function Fc(t){return{sessionId:t.id,name:t.name,status:t.status,lifecycle:t.lifecycle,runtimeState:t.runtimeState,harness:t.harnessName,hasHarnessSessionId:!!t.harnessSessionId,backendRefKind:t.backendRef?.kind,hasBackendConversationId:!!t.backendRef?.conversationId,hasBackendRunId:!!t.backendRef?.runId,hasBackendWorktreeId:!!t.backendRef?.worktreeId,hasBackendWorktreePath:!!t.backendRef?.worktreePath}}var gi=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>Lc.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>Lc.has(o.status)).map(o=>o.name));if(!n.has(e))return e;let r=2;for(;n.has(`${e}-${r}`);)r+=1;return`${e}-${r}`}add(e,n="spawn"){Bc("runtime.add",{reason:n,...Fc(e),activeCountBefore:this.activeSessionCount()}),this.sessions.set(e.id,e)}remove(e,n="unknown"){let r=this.sessions.get(e);Bc("runtime.remove",{reason:n,sessionId:e,existed:!!r,...r?Fc(r):{},activeCountBefore:this.activeSessionCount()}),this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var hi=class{constructor(e){this.deps=e}deps;initializeSession(e,n,r,o={}){if(this.deps.hydrateSpawnedSession(e,n,r),r.taskLifecycle?.create(e),e.on("statusChange",(i,s)=>{s==="running"?(e.harnessSessionId&&this.deps.markRunning(e),r.taskLifecycle?.progress(e)):(s==="completed"||s==="failed"||s==="killed")&&(r.taskLifecycle?.finalize(e),this.deps.handleTerminal(e).catch(a=>{console.error(`[SessionRuntimeBootstrap] handleTerminal threw for session ${e.id}:`,a)}))}),e.on("lifecycleChange",(i,s)=>{r.taskLifecycle?.progress(e)}),e.on("turnEnd",(i,s)=>{this.deps.handleTurnEnd(e,s).catch(a=>{console.error(`[SessionRuntimeBootstrap] handleTurnEnd threw for session ${e.id}:`,a)})}),e.start(),o.notifyLaunch!==!1){let i=this.buildLaunchNotification(e);this.deps.notifySession(e,i.text,i.label,i.idempotencyKey)}return e}buildLaunchNotification(e){let n=this.deps.formatLaunchWorkdirLabel(e),r=ut({harness:e.harnessName,model:e.model})??"default";return e.resumeSessionId?{text:dr({sessionName:e.name,resumedFromSessionName:e.resumedFromSessionName,workdirLabel:n,harnessLabel:r}),label:"resumed-launch",idempotencyKey:`resumed-launch:${e.id}:${e.startedAt}:${e.resumeSessionId}`}:{text:`🚀 [${e.name}] Launched | ${n} | ${r}`,label:"launch"}}};var yi=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,worktreeBranch:s,preview:a,originThreadLine:d,preservedSummary:l,remoteOutcome:u}=e,f=l?"preserved":o?"cleaned":"cleanup-failed",p=[s?.trim()||"unknown-branch",i.trim()||"unknown-worktree",n.startedAt].join(":"),k=l??(o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`),m=ft({costUsd:n.costUsd,duration:typeof n.completedAt=="number"?n.completedAt-n.startedAt:void 0,harnessName:n.harnessName,model:n.model}),c=u==="pr-updated"?"PR updated; no local worktree changes remained to merge":u==="pr-opened"?"PR opened; no local worktree changes remained to merge":"Session completed with no worktree changes to merge",h=u==="pr-updated"?`PR updated; no local worktree changes remained to merge — ${k}`:u==="pr-opened"?`PR opened; no local worktree changes remained to merge — ${k}`:void 0,S=u==="pr-updated"?"PR updated; no local worktree changes remained to merge":u==="pr-opened"?"PR opened; no local worktree changes remained to merge":"Session completed with no worktree changes to merge",b=u==="pr-updated"?"Coding agent session updated a PR; no local worktree changes remained to merge.":u==="pr-opened"?"Coding agent session opened a PR; no local worktree changes remained to merge.":void 0;return{label:l?"worktree-no-changes-preserved":o?"worktree-no-changes":"worktree-no-changes-cleanup-failed",idempotencyKey:`worktree-no-change:${n.id}:${f}:${p}`,userMessage:l?`ℹ️ [${n.name}] ${c} — ${l}${m}`:o?r?`ℹ️ [${n.name}] ${c} — native backend worktree released for backend cleanup${m}`:`ℹ️ [${n.name}] ${c} — worktree cleaned up${m}`:`⚠️ [${n.name}] ${S}, but worktree cleanup failed. Worktree still exists at ${i}${m}`,wakeMessage:oa({sessionName:n.name,sessionId:n.id,headline:b,cleanupSummary:h??k,preview:a,originThreadLine:d,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalState:n.approvalState,planApproval:n.planApproval,approvalPromptStatus:n.approvalPromptStatus,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt}),notifyUser:"always"}}buildAskNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,buttons:s,summaryLines:a=[],policyReason:d}=e,l=i.commitMessages.slice(0,5).map(p=>`• ${p.hash} ${p.message} (${p.author})`),u=i.commits>5?`...and ${i.commits-5} more`:"",f=n.worktreePrTargetRepo?`Branch: \`${r}\` → \`${o}\` | PR target: ${n.worktreePrTargetRepo}`:`Branch: \`${r}\` → \`${o}\``;return{label:"worktree-merge-ask",idempotencyKey:["worktree-decision",n.id,r,o,i.commits,i.commitMessages.map(p=>p.hash).join(",")].join(":"),userMessage:[`🔀 Worktree decision required for session \`${n.name}\``,"",f,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`,"",...a.length>0?["Summary:",...a.map(p=>`- ${p}`),""]:[],...d?[`Policy: ${d}`,""]:[],"Recent commits:",...l,...u?[u]:[],"",`⚠️ Discard will permanently delete branch \`${r}\` and all local changes. This cannot be undone.`].join(`
275
+ `),notifyUser:"always",buttons:a==="ask"&&!l?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:d}):void 0}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"suspended",idempotencyKey:`suspended:${e.id}:${e.killReason??"idle-timeout"}:${e.completedAt??"unknown"}`,userMessage:`💤 [${e.name}] Suspended after idle timeout | ${i} | ${Be(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${Js(e.killReason)} | ${i} | ${Be(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=Wc(e.pendingInputState),s=o?[o,i].filter(Boolean).join(":"):void 0,a=s?`pending-input:${s}`:void 0;if(!this.deps.debounceWaitingEvent(e.id,a))return;let d=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0,l=e.actionablePlanDecisionVersion??e.planDecisionVersion,u=e.pendingPlanApproval&&d==="ask"&&Xn(e,l),f=e.pendingInputState?.promptText?.trim()||void 0,p=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),k=!e.pendingPlanApproval&&f?f:!e.pendingPlanApproval&&p!==void 0?p:this.deps.getOutputPreview(e,e.pendingPlanApproval&&d!=="delegate"?Number.POSITIVE_INFINITY:void 0),m=e.pendingInputState?.options.map(w=>({label:w}))??[],c=!n||n.length===0?m:r&&r.options.length>0&&r.options.length<=6&&!r.options.some(w=>w.isOther)&&!r.multiSelect?r.options:n.length===1&&r&&r.options.length===0?m:[],h=e.pendingPlanApproval&&d==="ask"&&!u?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:l}):!e.pendingPlanApproval&&c.length?this.deps.getQuestionButtons(e.id,c,{requestId:e.pendingInputState?.requestId,questionId:r?.id}):void 0,S=XS(e,l),P=r?tv(r):[],x=r?ev({question:r,index:e.pendingInputState?.activeQuestionIndex??0,total:n?.length??1,optionDescriptions:P}):f,C=!e.pendingPlanApproval&&this.deps.questionContextSummaryProvider?await Oc({sessionName:e.name,question:x??k,context:p,provider:this.deps.questionContextSummaryProvider}):void 0,A=la({session:e,preview:k,questionText:e.pendingPlanApproval?void 0:x,questionContextPreview:p,questionContextSummary:C,planArtifact:S,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:d,planApprovalButtons:h,questionButtons:e.pendingPlanApproval?void 0:h}),y=A.planReviewSummary??k;if(A.label==="plan-approval"&&d==="ask"&&u){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"never",buttons:A.buttons,wakeMessage:A.wakeMessage});return}if(A.label==="plan-approval"&&d==="ask"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:canonical`,userMessage:A.userMessage,userMessages:A.userMessages,notifyUser:"always",buttons:A.buttons,hooks:{onNotifyStarted:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.deps.updatePersistedSession(e.id,{canonicalPlanPromptVersion:l,approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>er(e,l),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,l,y),wakeMessageOnNotifySuccess:un(e,l)});return}if(A.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`plan-approval:${e.id}:v${l??"unknown"}:wake-only`,userMessage:A.userMessage,wakeMessage:A.wakeMessage,notifyUser:"never",buttons:A.buttons});return}this.deps.dispatchSessionNotification(e,{label:A.label,idempotencyKey:`waiting:${e.id}:${s??`${A.label}:${A.userMessage}`}`,userMessage:A.userMessage,notifyUser:"always",buttons:A.buttons,shouldDispatch:o?()=>nv(e,o,i):void 0,wakeMessageOnNotifyFailed:A.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=ta({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${rv(e)}`,userMessage:n.userMessage,wakeMessage:n.wakeMessage,notifyUser:"always",onUserNotifyFailed:()=>{`${e.id}`,this.deps.shouldEmitTerminalWake(e)&&this.emitCompleted(e)}})}emitCompleted(e){let n=this.deps.getOutputPreview(e),r=this.shouldRequestCompletionFollowup(e),o=Zs({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i=Nc(e),s=`terminal:${e.id}:${i}`,a;this.deps.dispatchSessionNotification(e,{label:"completed",idempotencyKey:`terminal-completed:${e.id}:${i}`,userMessage:o.userMessage,notifyUser:"always",completionSummary:{required:r,producer:"terminal",outcomeKey:s},completionWakeSummaryRequired:r,completionWakeOutcomeKey:s,requireDirectUserNotification:!0,wakeMessageOnNotifySuccess:r?o.wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:r?o.wakeMessageOnNotifyFailed:void 0,hooks:{onNotifySucceeded:()=>{a=!0,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_succeeded",canonicalStatusDelivered:a,followupSummaryRequired:r})},onNotifyFailed:()=>{a=!1,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_failed",canonicalStatusDelivered:a,followupSummaryRequired:r})},onWakeSucceeded:()=>{this.logCompletionWakeDiagnostic({session:e,event:"completion_wake_succeeded",canonicalStatusDelivered:a,followupSummaryRequired:r})}}})}emitFailed(e,n,r){let o=ea({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}:${Nc(e)}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};ne();Ae();import{existsSync as ov}from"fs";var fi=class{constructor(e){this.deps=e}deps;async dismissWorktree(e){let n=this.deps.getPersistedSession(e),r=this.deps.resolveActiveSession(e),o=r??n;if(!o)return`Error: Session "${e}" not found.`;let i=r?.worktreePath??n?.worktreePath,s=this.deps.resolveWorktreeRepoDir(r?.originalWorkdir??n?.workdir,i),a=r?.worktreeBranch??n?.worktreeBranch,d=r?.name??n?.name??e;if(!s)return`Error: No workdir found for session "${e}".`;let l=ue(o);!l&&i&&ov(i)&&pe(s,i,{destructive:!0}),a&&be(s,a);for(let f of ge(r??n))this.deps.updatePersistedSession(f,{worktreeDisposition:"dismissed",worktreeDismissedAt:new Date().toISOString(),pendingWorktreeDecisionSince:void 0,worktreeState:"dismissed",lifecycle:"terminal",worktreePath:void 0,worktreeBranch:void 0,worktreeLifecycle:{state:"dismissed",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"dismiss",baseBranch:n?.worktreeLifecycle?.baseBranch,targetRepo:n?.worktreePrTargetRepo,pushRemote:n?.worktreePushRemote}});let u=l?`🗑️ [${d}] Branch \`${a??"unknown"}\` dismissed. Native backend worktree released for backend cleanup.`:`🗑️ [${d}] Branch \`${a??"unknown"}\` dismissed and permanently deleted.`;return this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:G(r??n??{id:e})??e,sessionId:n?.sessionId,harnessSessionId:r?.harnessSessionId??n?.harnessSessionId,backendRef:r?.backendRef??n?.backendRef,route:r?.route??n?.route}),{label:"worktree-dismissed",idempotencyKey:`worktree-dismissed:${G(r??n??{id:e})??e}:${a??"unknown"}`,userMessage:u,notifyUser:"always"}),u}snoozeWorktreeDecision(e,n={}){let r=this.deps.getPersistedSession(e);if(!r)return`Error: Session "${e}" not found.`;let o=Date.now(),i=new Date(o+1440*60*1e3).toISOString();for(let d of ge(r))this.deps.updatePersistedSession(d,{worktreeDecisionSnoozedUntil:i,lastWorktreeReminderAt:new Date(o).toISOString()});let a=`⏭️ Reminder snoozed 24h for \`${r.worktreeBranch??"unknown"}\` (session: ${r.name})`;return n.notifyUser!==!1&&this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:G(r)??O(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${G(r)??O(r)??r.harnessSessionId}:${i}`,userMessage:a,notifyUser:"always"}),a}};var Lc=new Set(["starting","running"]);function Bc(t,e){JSON.stringify({component:"SessionRuntimeRegistry",event:t,at:new Date().toISOString(),...e})}function Fc(t){return{sessionId:t.id,name:t.name,status:t.status,lifecycle:t.lifecycle,runtimeState:t.runtimeState,harness:t.harnessName,hasHarnessSessionId:!!t.harnessSessionId,backendRefKind:t.backendRef?.kind,hasBackendConversationId:!!t.backendRef?.conversationId,hasBackendRunId:!!t.backendRef?.runId,hasBackendWorktreeId:!!t.backendRef?.worktreeId,hasBackendWorktreePath:!!t.backendRef?.worktreePath}}var gi=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>Lc.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>Lc.has(o.status)).map(o=>o.name));if(!n.has(e))return e;let r=2;for(;n.has(`${e}-${r}`);)r+=1;return`${e}-${r}`}add(e,n="spawn"){Bc("runtime.add",{reason:n,...Fc(e),activeCountBefore:this.activeSessionCount()}),this.sessions.set(e.id,e)}remove(e,n="unknown"){let r=this.sessions.get(e);Bc("runtime.remove",{reason:n,sessionId:e,existed:!!r,...r?Fc(r):{},activeCountBefore:this.activeSessionCount()}),this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var hi=class{constructor(e){this.deps=e}deps;initializeSession(e,n,r,o={}){if(this.deps.hydrateSpawnedSession(e,n,r),r.taskLifecycle?.create(e),e.on("statusChange",(i,s)=>{s==="running"?(e.harnessSessionId&&this.deps.markRunning(e),r.taskLifecycle?.progress(e)):(s==="completed"||s==="failed"||s==="killed")&&(r.taskLifecycle?.finalize(e),this.deps.handleTerminal(e).catch(a=>{console.error(`[SessionRuntimeBootstrap] handleTerminal threw for session ${e.id}:`,a)}))}),e.on("lifecycleChange",(i,s)=>{r.taskLifecycle?.progress(e)}),e.on("turnEnd",(i,s)=>{this.deps.handleTurnEnd(e,s).catch(a=>{console.error(`[SessionRuntimeBootstrap] handleTurnEnd threw for session ${e.id}:`,a)})}),e.start(),o.notifyLaunch!==!1){let i=this.buildLaunchNotification(e);this.deps.notifySession(e,i.text,i.label,i.idempotencyKey)}return e}buildLaunchNotification(e){let n=this.deps.formatLaunchWorkdirLabel(e),r=ut({harness:e.harnessName,model:e.model})??"default";return e.resumeSessionId?{text:dr({sessionName:e.name,resumedFromSessionName:e.resumedFromSessionName,workdirLabel:n,harnessLabel:r}),label:"resumed-launch",idempotencyKey:`resumed-launch:${e.id}:${e.startedAt}:${e.resumeSessionId}`}:{text:`🚀 [${e.name}] Launched | ${n} | ${r}`,label:"launch"}}};var yi=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,worktreeBranch:s,preview:a,originThreadLine:d,preservedSummary:l,remoteOutcome:u}=e,f=l?"preserved":o?"cleaned":"cleanup-failed",p=[s?.trim()||"unknown-branch",i.trim()||"unknown-worktree",n.startedAt].join(":"),k=l??(o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`),m=ft({costUsd:n.costUsd,duration:typeof n.completedAt=="number"?n.completedAt-n.startedAt:void 0,harnessName:n.harnessName,model:n.model}),c=u==="pr-updated"?"PR updated; no local worktree changes remained to merge":u==="pr-opened"?"PR opened; no local worktree changes remained to merge":"Session completed with no worktree changes to merge",h=u==="pr-updated"?`PR updated; no local worktree changes remained to merge — ${k}`:u==="pr-opened"?`PR opened; no local worktree changes remained to merge — ${k}`:void 0,S=u==="pr-updated"?"PR updated; no local worktree changes remained to merge":u==="pr-opened"?"PR opened; no local worktree changes remained to merge":"Session completed with no worktree changes to merge",P=u==="pr-updated"?"Coding agent session updated a PR; no local worktree changes remained to merge.":u==="pr-opened"?"Coding agent session opened a PR; no local worktree changes remained to merge.":void 0;return{label:l?"worktree-no-changes-preserved":o?"worktree-no-changes":"worktree-no-changes-cleanup-failed",idempotencyKey:`worktree-no-change:${n.id}:${f}:${p}`,userMessage:l?`ℹ️ [${n.name}] ${c} — ${l}${m}`:o?r?`ℹ️ [${n.name}] ${c} — native backend worktree released for backend cleanup${m}`:`ℹ️ [${n.name}] ${c} — worktree cleaned up${m}`:`⚠️ [${n.name}] ${S}, but worktree cleanup failed. Worktree still exists at ${i}${m}`,wakeMessage:oa({sessionName:n.name,sessionId:n.id,headline:P,cleanupSummary:h??k,preview:a,originThreadLine:d,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalState:n.approvalState,planApproval:n.planApproval,approvalPromptStatus:n.approvalPromptStatus,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt}),notifyUser:"always"}}buildAskNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,buttons:s,summaryLines:a=[],policyReason:d}=e,l=i.commitMessages.slice(0,5).map(p=>`• ${p.hash} ${p.message} (${p.author})`),u=i.commits>5?`...and ${i.commits-5} more`:"",f=n.worktreePrTargetRepo?`Branch: \`${r}\` → \`${o}\` | PR target: ${n.worktreePrTargetRepo}`:`Branch: \`${r}\` → \`${o}\``;return{label:"worktree-merge-ask",idempotencyKey:["worktree-decision",n.id,r,o,i.commits,i.commitMessages.map(p=>p.hash).join(",")].join(":"),userMessage:[`🔀 Worktree decision required for session \`${n.name}\``,"",f,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`,"",...a.length>0?["Summary:",...a.map(p=>`- ${p}`),""]:[],...d?[`Policy: ${d}`,""]:[],"Recent commits:",...l,...u?[u]:[],"",`⚠️ Discard will permanently delete branch \`${r}\` and all local changes. This cannot be undone.`].join(`
276
276
  `),notifyUser:"always",buttons:s,wakeMessageOnNotifySuccess:["Worktree decision buttons delivered to the user.",`Session: ${n.name} | ID: ${n.id}`,f,"Wait for their button callback — do NOT act on this worktree yourself."].join(`
277
277
  `),wakeMessageOnNotifyFailed:[`🔀 Worktree decision required for session \`${n.name}\``,"",f,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`].join(`
278
278
  `)}}buildDelegateNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,policyReason:s,allowedActions:a,originThreadLine:d}=e,l=i.commitMessages.slice(0,5).map(p=>`• ${p.hash} ${p.message} (${p.author})`),u=i.commits>5?`...and ${i.commits-5} more`:void 0,f=n.prompt?n.prompt.slice(0,500):"(no prompt)";return{label:"worktree-delegate",idempotencyKey:["worktree-delegate",n.id,r,o,i.commits,i.commitMessages.map(p=>p.hash).join(",")].join(":"),wakeMessage:na({sessionName:n.name,sessionId:n.id,branchName:r,baseBranch:o,promptSnippet:f,commitLines:l,moreNote:u,originThreadLine:d,diffSummary:i,allowedActions:a,policyReason:s}),notifyUser:"never"}}};function qc(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
279
279
  `):iv(t);return n?o:o.length>e?Uc(t)?Ed(o,e):Dd(o,e):o}function iv(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
280
280
  `).trim();return n?Uc(t)?sv(n)??n:e.slice(-20).join(`
281
281
  `):""}function Uc(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 sv(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(`
282
- `)?n:void 0}ke();Ae();ae();import{unlinkSync as av}from"fs";var ki=class t{timers=new Map;disposed=!1;static MAX_DELAY_MS=2147483647;schedule(e,n,r){if(this.disposed||(this.cancel(e),!Number.isFinite(n)))return;let o=Math.max(0,n-Date.now()),i=setTimeout(()=>{if(this.timers.delete(e),!this.disposed){if(n-Date.now()>0){this.schedule(e,n,r);return}r()}},Math.min(o,t.MAX_DELAY_MS));i.unref?.(),this.timers.set(e,i)}cancel(e){let n=this.timers.get(e);n&&(clearTimeout(n),this.timers.delete(e))}cancelPrefix(e){for(let n of this.timers.keys())n.startsWith(e)&&this.cancel(n)}dispose(){this.disposed=!0;for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}};ne();$n();Ae();var Kc=10080*60*1e3,dv=300*1e3,Vc="tmp-output:cleanup",lv=60*1e3;function uv(t){return t instanceof Error?t.message:String(t)}var Si=class{constructor(e){this.deps=e}deps;scheduler=new ki;lastTmpOutputCleanupAttemptAt;schedule(e,n,r){this.scheduler.schedule(e,n,r)}cancel(e){this.scheduler.cancel(e)}cancelPrefix(e){this.scheduler.cancelPrefix(e)}bootstrapMaintenanceSchedules(){let e=Date.now();this.runTmpOutputCleanup(e);for(let n of this.deps.store.listPersistedSessions())this.syncPersistedSessionMaintenance(n);this.syncActionTokenExpiryDeadline(),this.deps.store.cleanupOrphanOutputFiles(),this.syncTmpOutputCleanupDeadline(e)}syncRuntimeGcDeadline(e){if(!e.completedAt)return;let n=this.runtimeGcKey(e.id);this.schedule(n,e.completedAt+this.runtimeGcMaxAgeMs(),()=>{let r=this.deps.sessions.get(e.id);if(!r||!r.completedAt)return;let o=this.runtimeGcMaxAgeMs();if(!this.deps.store.shouldGcActiveSession(r,Date.now(),o)){this.syncRuntimeGcDeadline(r);return}this.deps.removeRuntimeSession(e.id,"runtime-gc"),this.deps.persistSession(r,{scheduleRuntimeGc:!1}),this.deps.clearRuntimeSessionState(e.id)})}cancelRuntimeGc(e){this.cancel(this.runtimeGcKey(e))}cancelPersistedMaintenance(e){let n=this.persistedMaintenanceRef(e);n&&this.cancelPrefix(`persisted:${n}:`)}syncPersistedSessionMaintenance(e){let n=this.persistedMaintenanceRef(e);if(!n)return;this.cancel(this.persistedMaintenanceKey(n,"worktree-reminder"));let r=this.deps.reminders.getNextReminderAt(e);r!=null?this.schedulePersistedWorktreeReminder(n,r):this.deps.reminders.clearResolvedReminderState(e),this.cancel(this.persistedMaintenanceKey(n,"worktree-retention"));let o=pt(e,{activeSession:!1,includePrSync:e.worktreeLifecycle?.state==="pr_open"||!!e.worktreePrUrl}),i=this.resolvedAtIso(e),s=this.isLegacyResolvedWorktree(e);if((o.cleanupSafe||s)&&typeof i=="string"){let a=new Date(i).getTime();Number.isFinite(a)&&this.schedule(this.persistedMaintenanceKey(n,"worktree-retention"),a+Kc,()=>{let d=this.deps.store.getPersistedSession(n);d&&this.reconcileResolvedWorktreeRetention(d,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=pt(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<Kc))try{if(!e.worktreePath&&!ue(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let d=ue(e)?!1:pe(a,e.worktreePath);if(!ue(e)&&!d)return;for(let l of ge(e))this.deps.updatePersistedSession(l,{worktreePath:void 0,worktreeBranch:void 0,worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{...e.worktreeLifecycle??r.lifecycle,state:r.cleanupSafe?r.derivedState:s??r.derivedState,updatedAt:new Date(n).toISOString(),resolvedAt:e.worktreeLifecycle?.resolvedAt??o,resolutionSource:e.worktreeLifecycle?.resolutionSource??"maintenance",notes:r.reasons}})}catch(a){`${e.worktreePath}${uv(a)}`}}syncActionTokenExpiryDeadline(){let e="tokens:expiry";this.cancel(e);let n=this.deps.store.getNextActionTokenExpiry();n!=null&&this.schedule(e,n,()=>{this.deps.store.purgeExpiredActionTokens(Date.now())||this.syncActionTokenExpiryDeadline()})}syncTmpOutputCleanupDeadline(e=Date.now()){this.cancel(Vc);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(Vc,this.getTmpOutputCleanupScheduleAt(n,e),()=>{let r=Date.now();this.runTmpOutputCleanup(r),this.syncTmpOutputCleanupDeadline(r)})}enforcePersistedRetention(){let e=this.deps.store.evictOldestPersisted(this.deps.getMaxPersistedSessions());for(let n of e)this.cancelPersistedMaintenance(n),n.sessionId&&this.cancelRuntimeGc(n.sessionId),this.cleanupOutputPathIfUnreferenced(n.outputPath)}dispose(){this.scheduler.dispose()}persistedMaintenanceRef(e){return e.sessionId??O(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(D.sessionGcAgeMinutes??1440)*6e4}runTmpOutputCleanup(e){this.lastTmpOutputCleanupAttemptAt=e,this.deps.store.cleanupTmpOutputFiles(e)}getTmpOutputCleanupScheduleAt(e,n){if(e>n||this.lastTmpOutputCleanupAttemptAt==null)return e;let r=this.lastTmpOutputCleanupAttemptAt+lv;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()+dv))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{av(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"}};Wn();var jc=new Set(["completed","failed","killed"]),cv=new Set(["starting","running"]),pv=5e3;function mv(t,e){return Gc("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.prompt,workdir:t.workdir,name:t.name,model:t.model,reasoningEffort:t.reasoningEffort,fastMode:t.fastMode,systemPrompt:t.systemPrompt,allowedTools:t.allowedTools?[...t.allowedTools].sort():t.allowedTools,resumeSessionId:t.resumeSessionId,resumedFromSessionName:t.resumedFromSessionName,resumeWorktreeFrom:t.resumeWorktreeFrom,sessionIdOverride:t.sessionIdOverride,clearedPersistedCodexResume:t.clearedPersistedCodexResume,forkSession:t.forkSession,forceNewSession:t.forceNewSession,permissionMode:t.permissionMode,planApproval:t.planApproval,harness:t.harness,worktreeStrategy:t.worktreeStrategy,effectiveWorktreeStrategy:e,worktreeBaseBranch:t.worktreeBaseBranch,worktreePrTargetRepo:t.worktreePrTargetRepo,originAgentId:t.originAgentId})).digest("hex").slice(0,16)}function fv(t){return Gc("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.launchPrompt,workdir:t.launchWorkdir,name:t.launchName,model:t.launchModel,reasoningEffort:t.launchReasoningEffort,fastMode:t.launchFastMode,systemPrompt:t.launchSystemPrompt,allowedTools:t.launchAllowedTools?[...t.launchAllowedTools].sort():t.launchAllowedTools,resumeSessionId:t.launchResumeSessionId,resumedFromSessionName:t.launchResumedFromSessionName,resumeWorktreeFrom:t.launchResumeWorktreeFrom,sessionIdOverride:t.launchSessionIdOverride,clearedPersistedCodexResume:t.launchClearedPersistedCodexResume,forkSession:t.launchForkSession,forceNewSession:t.launchForceNewSession,permissionMode:t.launchPermissionMode,planApproval:t.launchPlanApproval,harness:t.launchHarness,worktreeStrategy:t.launchWorktreeStrategy,worktreeBaseBranch:t.launchWorktreeBaseBranch,worktreePrTargetRepo:t.launchWorktreePrTargetRepo,originAgentId:t.launchOriginAgentId})).digest("hex").slice(0,16)}var vi=class t{registry;sessions;maxSessions;maxPersistedSessions;lastWaitingEventTimestamps=new Map;lastTurnCompleteMarkers=new Map;lastTerminalWakeMarkers=new Map;mergeQueue=new ln;pendingAskUserQuestions=new Map;store;metrics;wakeDispatcher;interactions;notifications;worktrees;questions;lifecycle;restore;stateSync;references;worktreeStrategy;worktreeDecisions;runtimeBootstrap;worktreeMessages;maintenance;constructor(e=20,n=50,r={}){this.maxSessions=e,this.maxPersistedSessions=n;let o=t.createServiceBundle(this,r);this.registry=o.registry,this.sessions=o.sessions,this.store=o.store,this.metrics=o.metrics,this.wakeDispatcher=o.wakeDispatcher,this.interactions=o.interactions,this.notifications=o.notifications,this.worktrees=o.worktrees,this.questions=o.questions,this.lifecycle=o.lifecycle,this.restore=o.restore,this.stateSync=o.stateSync,this.references=o.references,this.worktreeStrategy=o.worktreeStrategy,this.worktreeDecisions=o.worktreeDecisions,this.runtimeBootstrap=o.runtimeBootstrap,this.worktreeMessages=o.worktreeMessages,this.maintenance=o.maintenance,this.reconcilePersistedTaskFlowMirrors()}static createServiceBundle(e,n){let r=new gi,o=r.sessions,i=new Yo(n.store),s=new Zo,a=new ni,d=new ri(i.actionTokenStore,ye),l=new Bo(o,i),u=new Lo({store:i,sessions:o,resolveSession:y=>l.resolveActive(y)}),f=new ai(a,(y,w)=>u.applySessionPatch(y,w),{getPersistedSession:y=>i.getPersistedSession(y)}),p=new di,k=new Wo(y=>i.getPersistedSession(y)),m=new yi,c=new jo({shouldRunWorktreeStrategy:y=>e.shouldRunWorktreeStrategy(y),isAlreadyMerged:y=>e.isAlreadyMerged(y),resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),getWorktreeCompletionState:(y,w,L,K)=>e.getWorktreeCompletionState(y,w,L,K),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),getPersistedSession:y=>i.getPersistedSession(y),dispatchSessionNotification:(y,w)=>e.dispatchSessionNotification(y,w),getOutputPreview:(y,w)=>e.getOutputPreview(y,w),originThreadLine:y=>e.originThreadLine(y),getWorktreeDecisionButtons:y=>e.getWorktreeDecisionButtons(y),getPolicyAwareWorktreeDecisionButtons:(y,w,L)=>e.getWorktreeDecisionButtons(y,w,L),makeOpenPrButton:y=>e.makeActionButton(y,"worktree-create-pr","Open PR"),isPrAvailable:y=>e.resolveRepoPolicy(y).prAvailable,hasOpenPrForBranch:(y,w,L)=>{let K=Re(y,w,L);return K.exists&&K.state==="open"},getPrStatusForBranch:(y,w,L)=>Re(y,w,L),getPrStatusForUrl:(y,w,L)=>Ye(y,w,L),resolveRepoPolicy:y=>e.resolveRepoPolicy(y),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:m,enqueueMerge:(y,w,L)=>e.enqueueMerge(y,w,L),mergeBranch:Yr,spawnConflictResolver:async({session:y,worktreePath:w,prompt:L})=>e.spawn({prompt:L,workdir:w,name:`${y.name}-conflict-resolver`,harness:y.harnessName||fe(),model:y.model,reasoningEffort:y.reasoningEffort,fastMode:y.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:y.id,route:y.route,originChannel:y.originChannel,originThreadId:y.originThreadId,originAgentId:y.originAgentId,originSessionKey:y.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(y,w)=>{let{makeAgentPrTool:L}=await Promise.resolve().then(()=>(Po(),Xl));return{success:(await L().execute("auto-pr",{session:y.id,base_branch:w}))?.meta?.success===!0}}}),h=new li(e.pendingAskUserQuestions,(y,w)=>e.dispatchSessionNotification(y,w),y=>{e.clearWaitingTimestampsForSession(y)},(y,w,L)=>d.getQuestionButtons(y,w,L)),S=new ui(y=>e.buildRoutingProxy(y),(y,w)=>f.dispatch(y,w),(y,w)=>e.updatePersistedSession(y,w),(y,w)=>e.getPolicyAwareWorktreeDecisionButtons(y,{},void 0,w)),b=new Si({store:i,sessions:o,reminders:S,removeRuntimeSession:(y,w)=>r.remove(y,w),persistSession:(y,w)=>e.persistSession(y,w),clearRuntimeSessionState:y=>{e.clearWaitingTimestampsForSession(y),e.lastTurnCompleteMarkers.delete(y),e.lastTerminalWakeMarkers.delete(y)},resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let x=new mi({persistSession:y=>e.persistSession(y),clearWaitingTimestamp:y=>{e.clearWaitingTimestampsForSession(y)},handleWorktreeStrategy:y=>e.handleWorktreeStrategy(y),resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),dispatchSessionNotification:(y,w)=>e.dispatchSessionNotification(y,w),notifySession:(y,w,L,K)=>e.notifySession(y,w,L,K),clearRetryTimersForSession:y=>a.clearRetryTimersForSession(y),hasTurnCompleteWakeMarker:y=>e.lastTurnCompleteMarkers.has(y),shouldEmitTurnCompleteWake:y=>e.shouldEmitTurnCompleteWake(y),shouldEmitTerminalWake:y=>e.shouldEmitTerminalWake(y),resolvePlanApprovalMode:y=>e.resolvePlanApprovalMode(y),getPlanApprovalButtons:(y,w)=>d.getPlanApprovalButtons(y,w),getResumeButtons:(y,w)=>d.getResumeButtons(y,w),getQuestionButtons:(y,w,L)=>d.getQuestionButtons(y,w,L),extractLastOutputLine:y=>e.extractLastOutputLine(y),getOutputPreview:(y,w)=>e.getOutputPreview(y,w),originThreadLine:y=>e.originThreadLine(y),debounceWaitingEvent:(y,w)=>e.debounceWaitingEvent(y,w),isAlreadyMerged:y=>e.isAlreadyMerged(y),questionContextSummaryProvider:n.questionContextSummaryProvider??Dc()}),T=new fi({getPersistedSession:y=>i.getPersistedSession(y),resolveActiveSession:y=>l.resolveActive(y),resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),dispatchNotification:(y,w)=>f.dispatch(y,w),buildRoutingProxy:y=>e.buildRoutingProxy(y)}),A=new hi({hydrateSpawnedSession:(y,w,L)=>{k.hydrateSpawnedSession(y,w,L)},markRunning:y=>{i.markRunning(y),e.onPersistedSessionChanged(i.getPersistedSession(y.id))},handleTerminal:async y=>e.onSessionTerminal(y),handleTurnEnd:(y,w)=>x.handleTurnEnd(y,w),formatLaunchWorkdirLabel:y=>e.formatLaunchWorkdirLabel(y),notifySession:(y,w,L,K)=>e.notifySession(y,w,L,K)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:a,interactions:d,notifications:f,worktrees:p,questions:h,lifecycle:x,restore:k,stateSync:u,references:l,worktreeStrategy:c,worktreeDecisions:T,runtimeBootstrap:A,worktreeMessages:m,maintenance:b}}get persisted(){return this.store.persisted}get idIndex(){return this.store.idIndex}get nameIndex(){return this.store.nameIndex}uniqueName(e){return this.registry.uniqueName(e)}syncRuntimeGcDeadline(e){this.maintenance.syncRuntimeGcDeadline(e)}onPersistedSessionChanged(e){e&&(this.syncPersistedSessionMaintenance(e),this.enforcePersistedRetention())}syncPersistedSessionMaintenance(e){this.maintenance.syncPersistedSessionMaintenance(e)}syncActionTokenExpiryDeadline(){this.maintenance.syncActionTokenExpiryDeadline()}syncTmpOutputCleanupDeadline(e=Date.now()){this.maintenance.syncTmpOutputCleanupDeadline(e)}enforcePersistedRetention(){this.maintenance.enforcePersistedRetention()}bootstrapMaintenanceSchedules(){this.maintenance.bootstrapMaintenanceSchedules()}disposeMaintenance(){this.maintenance.dispose()}spawn(e,n={}){if(this.registry.activeSessionCount()>=this.maxSessions)throw new Error(`Max sessions reached (${this.maxSessions}). Use agent_sessions to list active sessions and agent_kill to end one.`);if(e.sessionIdOverride){let k=this.registry.get(e.sessionIdOverride);if(k?.status==="starting"||k?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${k.status}.`);k&&this.registry.remove(k.id,"session-id-override-replacement"),this.clearWaitingTimestampsForSession(e.sessionIdOverride),this.lastTurnCompleteMarkers.delete(e.sessionIdOverride),this.lastTerminalWakeMarkers.delete(e.sessionIdOverride),this.maintenance.cancelRuntimeGc(e.sessionIdOverride)}let o=e.name||_d(e.prompt),i=this.uniqueName(o);i!==o&&`${o}${i}`;let s=this.checkRepoPolicyForLaunch(e.workdir,e.worktreeStrategy);if(!s.ok){let k=s;throw new Error(k.text)}e.repoIntegrationPolicy=s.resolution.policy,e.repoIntegrationPolicySource=s.resolution.source==="none"?void 0:s.resolution.source,e.repoProvider=s.resolution.provider;let a=this.restore.prepareSpawn(e,i);if(!e.route?.provider||!e.route.target)throw new Error(`Cannot launch session "${i}": missing explicit route metadata.`);let d=e.harness??"claude-code",l=this,u,f=d==="claude-code"&&!e.canUseTool?async(k,m)=>{if(!u)throw new Error("canUseTool called before session ID was set");return l.handleAskUserQuestion(u,m)}:e.canUseTool,p=new Xr({...e,workdir:a.actualWorkdir,systemPrompt:a.effectiveSystemPrompt,canUseTool:f},i);return u=p.id,this.registry.add(p),this.metrics.incrementLaunched(),this.runtimeBootstrap.initializeSession(p,a,e,n)}async spawnAndAwaitRunning(e,n={}){let r=this.spawn(e,n);return await this.waitForRunningSession(r),r}async waitForRunningSession(e){if(e.status==="running")return;if(jc.has(e.status))throw new Error(this.describeLaunchFailure(e));let n=e.on?.bind(e),r=e.off?.bind(e)??e.removeListener?.bind(e);if(!n||!r)throw new Error(`Session ${e.name} [${e.id}] did not expose lifecycle events during startup.`);await new Promise((o,i)=>{let s=(d,l)=>{if(l==="running"){a(),o();return}jc.has(l)&&(a(),i(new Error(this.describeLaunchFailure(e))))},a=()=>{r("statusChange",s)};n("statusChange",s)})}describeLaunchFailure(e){let n=e.killReason?` (reason: ${e.killReason})`:"",r=e.error||e.result?.result||`status=${e.status}${n}`;return`Session ${e.name} [${e.id}] failed to start: ${r}`}formatLaunchResult(e,n){return ar({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??D.permissionMode,planApproval:e.planApproval,resumeSessionId:e.resumeSessionId,resumeSessionName:e.resumeSessionName,forkSession:e.forkSession,forceNewSession:e.forceNewSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},n)}shouldRunWorktreeStrategy(e){let n=e.lifecycle;return!(n==="starting"||n==="awaiting_plan_decision"||n==="awaiting_user_input"||e.pendingPlanApproval)}resolveRepoPolicy(e){let n=On(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"&&ye(),record:r};let o=Ol(n);if(o){let i=xs(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:Ts({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:Ts({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:Cs(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=On(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=On(e);if(r)return this.store.setRepoPolicy(xs(r,n,"stored"))}resetRepoPolicy(e){let n=On(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=Cs(r.identity,n,r.prAvailable);if(!e.route?.provider||!e.route.target)return o;let i=`repo-policy:${r.identity.key}`,s=this.interactions.getRepoPolicyChoiceButtons({choiceId:i,route:e.route,repoRoot:r.identity.repoRoot,launchPrompt:e.prompt,launchWorkdir:e.workdir,launchName:e.name,launchModel:e.model,launchReasoningEffort:e.reasoningEffort,launchFastMode:e.fastMode,launchSystemPrompt:e.systemPrompt,launchAllowedTools:e.allowedTools,launchResumeSessionId:e.resumeSessionId,launchResumedFromSessionName:e.resumedFromSessionName,launchResumeWorktreeFrom:e.resumeWorktreeFrom,launchSessionIdOverride:e.sessionIdOverride,launchClearedPersistedCodexResume:e.clearedPersistedCodexResume,launchForkSession:e.forkSession,launchForceNewSession:e.forceNewSession,launchPermissionMode:e.permissionMode,launchPlanApproval:e.planApproval,launchHarness:e.harness,launchWorktreeStrategy:n,launchWorktreeBaseBranch:e.worktreeBaseBranch,launchWorktreePrTargetRepo:e.worktreePrTargetRepo,launchOriginAgentId:e.originAgentId,prAvailable:r.prAvailable}),a=mv(e,n);return this.notifications.dispatch(this.buildRoutingProxy({id:i,name:"repo-policy",route:e.route}),{label:"repo-policy-choice",idempotencyKey:`repo-policy-choice:${r.identity.key}:${n}:${a}`,userMessage:[o,"","After you choose a policy, OCA will continue this launch automatically."].join(`
282
+ `)?n:void 0}ke();Ae();ae();import{unlinkSync as av}from"fs";var ki=class t{timers=new Map;disposed=!1;static MAX_DELAY_MS=2147483647;schedule(e,n,r){if(this.disposed||(this.cancel(e),!Number.isFinite(n)))return;let o=Math.max(0,n-Date.now()),i=setTimeout(()=>{if(this.timers.delete(e),!this.disposed){if(n-Date.now()>0){this.schedule(e,n,r);return}r()}},Math.min(o,t.MAX_DELAY_MS));i.unref?.(),this.timers.set(e,i)}cancel(e){let n=this.timers.get(e);n&&(clearTimeout(n),this.timers.delete(e))}cancelPrefix(e){for(let n of this.timers.keys())n.startsWith(e)&&this.cancel(n)}dispose(){this.disposed=!0;for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}};ne();$n();Ae();var Kc=10080*60*1e3,dv=300*1e3,Vc="tmp-output:cleanup",lv=60*1e3;function uv(t){return t instanceof Error?t.message:String(t)}var Si=class{constructor(e){this.deps=e}deps;scheduler=new ki;lastTmpOutputCleanupAttemptAt;schedule(e,n,r){this.scheduler.schedule(e,n,r)}cancel(e){this.scheduler.cancel(e)}cancelPrefix(e){this.scheduler.cancelPrefix(e)}bootstrapMaintenanceSchedules(){let e=Date.now();this.runTmpOutputCleanup(e);for(let n of this.deps.store.listPersistedSessions())this.syncPersistedSessionMaintenance(n);this.syncActionTokenExpiryDeadline(),this.deps.store.cleanupOrphanOutputFiles(),this.syncTmpOutputCleanupDeadline(e)}syncRuntimeGcDeadline(e){if(!e.completedAt)return;let n=this.runtimeGcKey(e.id);this.schedule(n,e.completedAt+this.runtimeGcMaxAgeMs(),()=>{let r=this.deps.sessions.get(e.id);if(!r||!r.completedAt)return;let o=this.runtimeGcMaxAgeMs();if(!this.deps.store.shouldGcActiveSession(r,Date.now(),o)){this.syncRuntimeGcDeadline(r);return}this.deps.removeRuntimeSession(e.id,"runtime-gc"),this.deps.persistSession(r,{scheduleRuntimeGc:!1}),this.deps.clearRuntimeSessionState(e.id)})}cancelRuntimeGc(e){this.cancel(this.runtimeGcKey(e))}cancelPersistedMaintenance(e){let n=this.persistedMaintenanceRef(e);n&&this.cancelPrefix(`persisted:${n}:`)}syncPersistedSessionMaintenance(e){let n=this.persistedMaintenanceRef(e);if(!n)return;this.cancel(this.persistedMaintenanceKey(n,"worktree-reminder"));let r=this.deps.reminders.getNextReminderAt(e);r!=null?this.schedulePersistedWorktreeReminder(n,r):this.deps.reminders.clearResolvedReminderState(e),this.cancel(this.persistedMaintenanceKey(n,"worktree-retention"));let o=pt(e,{activeSession:!1,includePrSync:e.worktreeLifecycle?.state==="pr_open"||!!e.worktreePrUrl}),i=this.resolvedAtIso(e),s=this.isLegacyResolvedWorktree(e);if((o.cleanupSafe||s)&&typeof i=="string"){let a=new Date(i).getTime();Number.isFinite(a)&&this.schedule(this.persistedMaintenanceKey(n,"worktree-retention"),a+Kc,()=>{let d=this.deps.store.getPersistedSession(n);d&&this.reconcileResolvedWorktreeRetention(d,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=pt(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<Kc))try{if(!e.worktreePath&&!ue(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let d=ue(e)?!1:pe(a,e.worktreePath);if(!ue(e)&&!d)return;for(let l of ge(e))this.deps.updatePersistedSession(l,{worktreePath:void 0,worktreeBranch:void 0,worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{...e.worktreeLifecycle??r.lifecycle,state:r.cleanupSafe?r.derivedState:s??r.derivedState,updatedAt:new Date(n).toISOString(),resolvedAt:e.worktreeLifecycle?.resolvedAt??o,resolutionSource:e.worktreeLifecycle?.resolutionSource??"maintenance",notes:r.reasons}})}catch(a){`${e.worktreePath}${uv(a)}`}}syncActionTokenExpiryDeadline(){let e="tokens:expiry";this.cancel(e);let n=this.deps.store.getNextActionTokenExpiry();n!=null&&this.schedule(e,n,()=>{this.deps.store.purgeExpiredActionTokens(Date.now())||this.syncActionTokenExpiryDeadline()})}syncTmpOutputCleanupDeadline(e=Date.now()){this.cancel(Vc);let n=this.deps.store.getNextTmpOutputCleanupAt(e);if(n==null){this.lastTmpOutputCleanupAttemptAt=void 0;return}n>e&&(this.lastTmpOutputCleanupAttemptAt=void 0),this.schedule(Vc,this.getTmpOutputCleanupScheduleAt(n,e),()=>{let r=Date.now();this.runTmpOutputCleanup(r),this.syncTmpOutputCleanupDeadline(r)})}enforcePersistedRetention(){let e=this.deps.store.evictOldestPersisted(this.deps.getMaxPersistedSessions());for(let n of e)this.cancelPersistedMaintenance(n),n.sessionId&&this.cancelRuntimeGc(n.sessionId),this.cleanupOutputPathIfUnreferenced(n.outputPath)}dispose(){this.scheduler.dispose()}persistedMaintenanceRef(e){return e.sessionId??O(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(D.sessionGcAgeMinutes??1440)*6e4}runTmpOutputCleanup(e){this.lastTmpOutputCleanupAttemptAt=e,this.deps.store.cleanupTmpOutputFiles(e)}getTmpOutputCleanupScheduleAt(e,n){if(e>n||this.lastTmpOutputCleanupAttemptAt==null)return e;let r=this.lastTmpOutputCleanupAttemptAt+lv;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()+dv))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{av(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"}};Wn();var jc=new Set(["completed","failed","killed"]),cv=new Set(["starting","running"]),pv=5e3;function mv(t,e){return Gc("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.prompt,workdir:t.workdir,name:t.name,model:t.model,reasoningEffort:t.reasoningEffort,fastMode:t.fastMode,systemPrompt:t.systemPrompt,allowedTools:t.allowedTools?[...t.allowedTools].sort():t.allowedTools,resumeSessionId:t.resumeSessionId,resumedFromSessionName:t.resumedFromSessionName,resumeWorktreeFrom:t.resumeWorktreeFrom,sessionIdOverride:t.sessionIdOverride,clearedPersistedCodexResume:t.clearedPersistedCodexResume,forkSession:t.forkSession,forceNewSession:t.forceNewSession,permissionMode:t.permissionMode,planApproval:t.planApproval,harness:t.harness,worktreeStrategy:t.worktreeStrategy,effectiveWorktreeStrategy:e,worktreeBaseBranch:t.worktreeBaseBranch,worktreePrTargetRepo:t.worktreePrTargetRepo,originAgentId:t.originAgentId})).digest("hex").slice(0,16)}function fv(t){return Gc("sha256").update(JSON.stringify({route:t.route?{provider:t.route.provider,target:t.route.target,accountId:t.route.accountId,threadId:t.route.threadId,sessionKey:t.route.sessionKey}:void 0,prompt:t.launchPrompt,workdir:t.launchWorkdir,name:t.launchName,model:t.launchModel,reasoningEffort:t.launchReasoningEffort,fastMode:t.launchFastMode,systemPrompt:t.launchSystemPrompt,allowedTools:t.launchAllowedTools?[...t.launchAllowedTools].sort():t.launchAllowedTools,resumeSessionId:t.launchResumeSessionId,resumedFromSessionName:t.launchResumedFromSessionName,resumeWorktreeFrom:t.launchResumeWorktreeFrom,sessionIdOverride:t.launchSessionIdOverride,clearedPersistedCodexResume:t.launchClearedPersistedCodexResume,forkSession:t.launchForkSession,forceNewSession:t.launchForceNewSession,permissionMode:t.launchPermissionMode,planApproval:t.launchPlanApproval,harness:t.launchHarness,worktreeStrategy:t.launchWorktreeStrategy,worktreeBaseBranch:t.launchWorktreeBaseBranch,worktreePrTargetRepo:t.launchWorktreePrTargetRepo,originAgentId:t.launchOriginAgentId})).digest("hex").slice(0,16)}var vi=class t{registry;sessions;maxSessions;maxPersistedSessions;lastWaitingEventTimestamps=new Map;lastTurnCompleteMarkers=new Map;lastTerminalWakeMarkers=new Map;mergeQueue=new ln;pendingAskUserQuestions=new Map;store;metrics;wakeDispatcher;interactions;notifications;worktrees;questions;lifecycle;restore;stateSync;references;worktreeStrategy;worktreeDecisions;runtimeBootstrap;worktreeMessages;maintenance;constructor(e=20,n=50,r={}){this.maxSessions=e,this.maxPersistedSessions=n;let o=t.createServiceBundle(this,r);this.registry=o.registry,this.sessions=o.sessions,this.store=o.store,this.metrics=o.metrics,this.wakeDispatcher=o.wakeDispatcher,this.interactions=o.interactions,this.notifications=o.notifications,this.worktrees=o.worktrees,this.questions=o.questions,this.lifecycle=o.lifecycle,this.restore=o.restore,this.stateSync=o.stateSync,this.references=o.references,this.worktreeStrategy=o.worktreeStrategy,this.worktreeDecisions=o.worktreeDecisions,this.runtimeBootstrap=o.runtimeBootstrap,this.worktreeMessages=o.worktreeMessages,this.maintenance=o.maintenance,this.reconcilePersistedTaskFlowMirrors()}static createServiceBundle(e,n){let r=new gi,o=r.sessions,i=new Yo(n.store),s=new Zo,a=new ni,d=new ri(i.actionTokenStore,ye),l=new Bo(o,i),u=new Lo({store:i,sessions:o,resolveSession:y=>l.resolveActive(y)}),f=new ai(a,(y,w)=>u.applySessionPatch(y,w),{getPersistedSession:y=>i.getPersistedSession(y)}),p=new di,k=new Wo(y=>i.getPersistedSession(y)),m=new yi,c=new jo({shouldRunWorktreeStrategy:y=>e.shouldRunWorktreeStrategy(y),isAlreadyMerged:y=>e.isAlreadyMerged(y),resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),getWorktreeCompletionState:(y,w,L,K)=>e.getWorktreeCompletionState(y,w,L,K),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),getPersistedSession:y=>i.getPersistedSession(y),dispatchSessionNotification:(y,w)=>e.dispatchSessionNotification(y,w),getOutputPreview:(y,w)=>e.getOutputPreview(y,w),originThreadLine:y=>e.originThreadLine(y),getWorktreeDecisionButtons:y=>e.getWorktreeDecisionButtons(y),getPolicyAwareWorktreeDecisionButtons:(y,w,L)=>e.getWorktreeDecisionButtons(y,w,L),makeOpenPrButton:y=>e.makeActionButton(y,"worktree-create-pr","Open PR"),isPrAvailable:y=>e.resolveRepoPolicy(y).prAvailable,hasOpenPrForBranch:(y,w,L)=>{let K=Re(y,w,L);return K.exists&&K.state==="open"},getPrStatusForBranch:(y,w,L)=>Re(y,w,L),getPrStatusForUrl:(y,w,L)=>Ye(y,w,L),resolveRepoPolicy:y=>e.resolveRepoPolicy(y),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:m,enqueueMerge:(y,w,L)=>e.enqueueMerge(y,w,L),mergeBranch:Yr,spawnConflictResolver:async({session:y,worktreePath:w,prompt:L})=>e.spawn({prompt:L,workdir:w,name:`${y.name}-conflict-resolver`,harness:y.harnessName||fe(),model:y.model,reasoningEffort:y.reasoningEffort,fastMode:y.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:y.id,route:y.route,originChannel:y.originChannel,originThreadId:y.originThreadId,originAgentId:y.originAgentId,originSessionKey:y.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(y,w)=>{let{makeAgentPrTool:L}=await Promise.resolve().then(()=>(Po(),Xl));return{success:(await L().execute("auto-pr",{session:y.id,base_branch:w}))?.meta?.success===!0}}}),h=new li(e.pendingAskUserQuestions,(y,w)=>e.dispatchSessionNotification(y,w),y=>{e.clearWaitingTimestampsForSession(y)},(y,w,L)=>d.getQuestionButtons(y,w,L)),S=new ui(y=>e.buildRoutingProxy(y),(y,w)=>f.dispatch(y,w),(y,w)=>e.updatePersistedSession(y,w),(y,w)=>e.getPolicyAwareWorktreeDecisionButtons(y,{},void 0,w)),P=new Si({store:i,sessions:o,reminders:S,removeRuntimeSession:(y,w)=>r.remove(y,w),persistSession:(y,w)=>e.persistSession(y,w),clearRuntimeSessionState:y=>{e.clearWaitingTimestampsForSession(y),e.lastTurnCompleteMarkers.delete(y),e.lastTerminalWakeMarkers.delete(y)},resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let x=new mi({persistSession:y=>e.persistSession(y),clearWaitingTimestamp:y=>{e.clearWaitingTimestampsForSession(y)},handleWorktreeStrategy:y=>e.handleWorktreeStrategy(y),resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),dispatchSessionNotification:(y,w)=>e.dispatchSessionNotification(y,w),notifySession:(y,w,L,K)=>e.notifySession(y,w,L,K),clearRetryTimersForSession:y=>a.clearRetryTimersForSession(y),hasTurnCompleteWakeMarker:y=>e.lastTurnCompleteMarkers.has(y),shouldEmitTurnCompleteWake:y=>e.shouldEmitTurnCompleteWake(y),shouldEmitTerminalWake:y=>e.shouldEmitTerminalWake(y),resolvePlanApprovalMode:y=>e.resolvePlanApprovalMode(y),getPlanApprovalButtons:(y,w)=>d.getPlanApprovalButtons(y,w),getResumeButtons:(y,w)=>d.getResumeButtons(y,w),getQuestionButtons:(y,w,L)=>d.getQuestionButtons(y,w,L),extractLastOutputLine:y=>e.extractLastOutputLine(y),getOutputPreview:(y,w)=>e.getOutputPreview(y,w),originThreadLine:y=>e.originThreadLine(y),debounceWaitingEvent:(y,w)=>e.debounceWaitingEvent(y,w),isAlreadyMerged:y=>e.isAlreadyMerged(y),questionContextSummaryProvider:n.questionContextSummaryProvider??Dc()}),C=new fi({getPersistedSession:y=>i.getPersistedSession(y),resolveActiveSession:y=>l.resolveActive(y),resolveWorktreeRepoDir:(y,w)=>e.resolveWorktreeRepoDir(y,w),updatePersistedSession:(y,w)=>e.updatePersistedSession(y,w),dispatchNotification:(y,w)=>f.dispatch(y,w),buildRoutingProxy:y=>e.buildRoutingProxy(y)}),A=new hi({hydrateSpawnedSession:(y,w,L)=>{k.hydrateSpawnedSession(y,w,L)},markRunning:y=>{i.markRunning(y),e.onPersistedSessionChanged(i.getPersistedSession(y.id))},handleTerminal:async y=>e.onSessionTerminal(y),handleTurnEnd:(y,w)=>x.handleTurnEnd(y,w),formatLaunchWorkdirLabel:y=>e.formatLaunchWorkdirLabel(y),notifySession:(y,w,L,K)=>e.notifySession(y,w,L,K)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:a,interactions:d,notifications:f,worktrees:p,questions:h,lifecycle:x,restore:k,stateSync:u,references:l,worktreeStrategy:c,worktreeDecisions:C,runtimeBootstrap:A,worktreeMessages:m,maintenance:P}}get persisted(){return this.store.persisted}get idIndex(){return this.store.idIndex}get nameIndex(){return this.store.nameIndex}uniqueName(e){return this.registry.uniqueName(e)}syncRuntimeGcDeadline(e){this.maintenance.syncRuntimeGcDeadline(e)}onPersistedSessionChanged(e){e&&(this.syncPersistedSessionMaintenance(e),this.enforcePersistedRetention())}syncPersistedSessionMaintenance(e){this.maintenance.syncPersistedSessionMaintenance(e)}syncActionTokenExpiryDeadline(){this.maintenance.syncActionTokenExpiryDeadline()}syncTmpOutputCleanupDeadline(e=Date.now()){this.maintenance.syncTmpOutputCleanupDeadline(e)}enforcePersistedRetention(){this.maintenance.enforcePersistedRetention()}bootstrapMaintenanceSchedules(){this.maintenance.bootstrapMaintenanceSchedules()}disposeMaintenance(){this.maintenance.dispose()}spawn(e,n={}){if(this.registry.activeSessionCount()>=this.maxSessions)throw new Error(`Max sessions reached (${this.maxSessions}). Use agent_sessions to list active sessions and agent_kill to end one.`);if(e.sessionIdOverride){let k=this.registry.get(e.sessionIdOverride);if(k?.status==="starting"||k?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${k.status}.`);k&&this.registry.remove(k.id,"session-id-override-replacement"),this.clearWaitingTimestampsForSession(e.sessionIdOverride),this.lastTurnCompleteMarkers.delete(e.sessionIdOverride),this.lastTerminalWakeMarkers.delete(e.sessionIdOverride),this.maintenance.cancelRuntimeGc(e.sessionIdOverride)}let o=e.name||_d(e.prompt),i=this.uniqueName(o);i!==o&&`${o}${i}`;let s=this.checkRepoPolicyForLaunch(e.workdir,e.worktreeStrategy);if(!s.ok){let k=s;throw new Error(k.text)}e.repoIntegrationPolicy=s.resolution.policy,e.repoIntegrationPolicySource=s.resolution.source==="none"?void 0:s.resolution.source,e.repoProvider=s.resolution.provider;let a=this.restore.prepareSpawn(e,i);if(!e.route?.provider||!e.route.target)throw new Error(`Cannot launch session "${i}": missing explicit route metadata.`);let d=e.harness??"claude-code",l=this,u,f=d==="claude-code"&&!e.canUseTool?async(k,m)=>{if(!u)throw new Error("canUseTool called before session ID was set");return l.handleAskUserQuestion(u,m)}:e.canUseTool,p=new Xr({...e,workdir:a.actualWorkdir,systemPrompt:a.effectiveSystemPrompt,canUseTool:f},i);return u=p.id,this.registry.add(p),this.metrics.incrementLaunched(),this.runtimeBootstrap.initializeSession(p,a,e,n)}async spawnAndAwaitRunning(e,n={}){let r=this.spawn(e,n);return await this.waitForRunningSession(r),r}async waitForRunningSession(e){if(e.status==="running")return;if(jc.has(e.status))throw new Error(this.describeLaunchFailure(e));let n=e.on?.bind(e),r=e.off?.bind(e)??e.removeListener?.bind(e);if(!n||!r)throw new Error(`Session ${e.name} [${e.id}] did not expose lifecycle events during startup.`);await new Promise((o,i)=>{let s=(d,l)=>{if(l==="running"){a(),o();return}jc.has(l)&&(a(),i(new Error(this.describeLaunchFailure(e))))},a=()=>{r("statusChange",s)};n("statusChange",s)})}describeLaunchFailure(e){let n=e.killReason?` (reason: ${e.killReason})`:"",r=e.error||e.result?.result||`status=${e.status}${n}`;return`Session ${e.name} [${e.id}] failed to start: ${r}`}formatLaunchResult(e,n){return ar({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??D.permissionMode,planApproval:e.planApproval,resumeSessionId:e.resumeSessionId,resumeSessionName:e.resumeSessionName,forkSession:e.forkSession,forceNewSession:e.forceNewSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},n)}shouldRunWorktreeStrategy(e){let n=e.lifecycle;return!(n==="starting"||n==="awaiting_plan_decision"||n==="awaiting_user_input"||e.pendingPlanApproval)}resolveRepoPolicy(e){let n=On(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"&&ye(),record:r};let o=Ol(n);if(o){let i=xs(n,o,"seeded");return{identity:n,policy:o,source:"seeded",provider:n.provider,prAvailable:Ts({provider:n.provider}),record:i}}return{identity:n,source:"unknown",provider:n.provider,prAvailable:Ts({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:Cs(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=On(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=On(e);if(r)return this.store.setRepoPolicy(xs(r,n,"stored"))}resetRepoPolicy(e){let n=On(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=Cs(r.identity,n,r.prAvailable);if(!e.route?.provider||!e.route.target)return o;let i=`repo-policy:${r.identity.key}`,s=this.interactions.getRepoPolicyChoiceButtons({choiceId:i,route:e.route,repoRoot:r.identity.repoRoot,launchPrompt:e.prompt,launchWorkdir:e.workdir,launchName:e.name,launchModel:e.model,launchReasoningEffort:e.reasoningEffort,launchFastMode:e.fastMode,launchSystemPrompt:e.systemPrompt,launchAllowedTools:e.allowedTools,launchResumeSessionId:e.resumeSessionId,launchResumedFromSessionName:e.resumedFromSessionName,launchResumeWorktreeFrom:e.resumeWorktreeFrom,launchSessionIdOverride:e.sessionIdOverride,launchClearedPersistedCodexResume:e.clearedPersistedCodexResume,launchForkSession:e.forkSession,launchForceNewSession:e.forceNewSession,launchPermissionMode:e.permissionMode,launchPlanApproval:e.planApproval,launchHarness:e.harness,launchWorktreeStrategy:n,launchWorktreeBaseBranch:e.worktreeBaseBranch,launchWorktreePrTargetRepo:e.worktreePrTargetRepo,launchOriginAgentId:e.originAgentId,prAvailable:r.prAvailable}),a=mv(e,n);return this.notifications.dispatch(this.buildRoutingProxy({id:i,name:"repo-policy",route:e.route}),{label:"repo-policy-choice",idempotencyKey:`repo-policy-choice:${r.identity.key}:${n}:${a}`,userMessage:[o,"","After you choose a policy, OCA will continue this launch automatically."].join(`
283
283
  `),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(`
284
284
  `),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??fe(),o=e.permissionMode??D.permissionMode,i=e.planApproval??D.planApproval,s=this.spawn({prompt:e.prompt,workdir:e.workdir,sessionIdOverride:e.sessionIdOverride,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,allowedTools:e.allowedTools,resumeSessionId:e.resumeSessionId,resumedFromSessionName:e.resumedFromSessionName,resumeWorktreeFrom:e.resumeWorktreeFrom,forkSession:e.resumeSessionId?e.forkSession:!1,multiTurn:!0,permissionMode:o,planApproval:i,codexApprovalPolicy:r==="codex"?"never":void 0,originChannel:this.originChannelFromRoute(n),originThreadId:n.threadId,originAgentId:e.originAgentId,originSessionKey:n.sessionKey,route:n,harness:r,worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo});return{session:s,text:this.formatLaunchResult({prompt:e.prompt,workdir:e.workdir,harness:r,permissionMode:o,planApproval:i,forceNewSession:e.forceNewSession,resumeSessionId:e.resumeSessionId,resumeSessionName:e.resumedFromSessionName,forkSession:e.forkSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},s)}}continueLaunchAfterManualRepoPolicy(e,n){let r=this.resolveRepoPolicy(e);if(!r.identity)return{kind:"none"};let o=this.interactions.listActiveActionTokens("repo-policy-set").filter(u=>u.repoPolicyWorkdir===r.identity?.repoRoot),i=()=>{for(let u of new Set(o.map(f=>f.sessionId)))this.clearRepoPolicyChoiceTokens(u)},s=o.filter(u=>u.repoPolicy===n&&!!u.launchPrompt&&!!u.launchWorkdir&&!!u.route?.provider&&!!u.route?.target);if(s.length===0)return i(),{kind:"none"};let a=new Map;for(let u of s){let f=fv(u);a.has(f)||a.set(f,u)}if(a.size>1)return i(),{kind:"ambiguous",count:a.size};let d=[...a.values()][0];if(!d.launchPrompt||!d.launchWorkdir)return{kind:"none"};let l=this.launchAfterRepoPolicyChoice({route:d.route,prompt:d.launchPrompt,workdir:d.launchWorkdir,name:d.launchName,model:d.launchModel,reasoningEffort:d.launchReasoningEffort,fastMode:d.launchFastMode,systemPrompt:d.launchSystemPrompt,allowedTools:d.launchAllowedTools,resumeSessionId:d.launchResumeSessionId,resumedFromSessionName:d.launchResumedFromSessionName,resumeWorktreeFrom:d.launchResumeWorktreeFrom,sessionIdOverride:d.launchSessionIdOverride,clearedPersistedCodexResume:d.launchClearedPersistedCodexResume,forkSession:d.launchForkSession,forceNewSession:d.launchForceNewSession,permissionMode:d.launchPermissionMode,planApproval:d.launchPlanApproval,harness:d.launchHarness,worktreeStrategy:d.launchWorktreeStrategy,worktreeBaseBranch:d.launchWorktreeBaseBranch,worktreePrTargetRepo:d.launchWorktreePrTargetRepo,originAgentId:d.launchOriginAgentId});return this.consumeActionToken(d.id),this.clearRepoPolicyChoiceTokens(d.sessionId),{kind:"launched",...l}}makeActionButton(e,n,r,o={}){return this.interactions.makeActionButton(e,n,r,o)}makePluginActionButton(e,n,r,o={}){return this.makeActionButton(e,n,r,o)}consumeActionToken(e){return this.interactions.consumeActionToken(e)}getActionToken(e){return this.interactions.getActionToken(e)}clearRepoPolicyChoiceTokens(e){this.interactions.clearRepoPolicyChoiceTokens(e)}clearPlanDecisionTokens(e,n){this.interactions.clearPlanDecisionTokens(e,n)}isCurrentPendingPlanDecision(e,n){let r=this.resolve(e)??this.getPersistedSession(e);return er(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:Qn({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:un(e,n,!0),wakeMessageOnNotifyFailed:ci({session:e,planDecisionVersion:n})})}getWorktreeDecisionButtons(e,n={},r={merge:!0,pr:!0}){let o=this.resolve(e)??this.getPersistedSession(e);if(!(!o||o.worktreeStrategy==="delegate"&&n.allowDelegate!==!0))return this.interactions.getWorktreeDecisionButtons(e,o,r)}getPolicyAwareWorktreeDecisionButtons(e,n={},r,o){let i=r??this.resolve(e),s=o??this.getPersistedSession(e),a=this.resolveWorktreeRepoDir(i?.originalWorkdir??s?.workdir,i?.worktreePath??s?.worktreePath),d=a?this.resolveRepoPolicy(a):void 0,l=i?.repoIntegrationPolicy??s?.repoIntegrationPolicy,u=l??d?.policy,f=d?.prAvailable??!!(l&&l!=="never-pr"&&l!=="manual"),p=u?Is({policy:u,prAvailable:f}):{merge:!0,pr:!0};return this.getWorktreeDecisionButtons(e,n,p)}getWorktreeCompletionState(e,n,r,o){return this.worktrees.getCompletionState(e,n,r,o)}notifyWorktreeOutcome(e,n,r){this.notifications.notifyWorktreeOutcome(e,n,r)}requestPlanApprovalFromUser(e,n){let r=n.trim();if(!r)return"Error: summary must not be empty.";let o=aa(r),i=this.resolve(e),s=i?void 0:this.getPersistedSession(e),a=i??s;if(!a)return`Error: Session "${e}" not found.`;if(!a.pendingPlanApproval)return`Error: Session "${e}" is not awaiting plan approval.`;let d=G(i??s??{id:e})??e;if(this.resolvePlanApprovalMode(a)!=="delegate")return`Error: Session "${e}" already uses direct user plan approval. Do not send a duplicate approval prompt.`;let l=a.actionablePlanDecisionVersion??a.planDecisionVersion;if(Xn(a,l))return[`An actionable plan review prompt already exists for session ${a.name} [${d}].`,"Wait for the user's Approve, Revise, or Reject response.","Do not send a separate plain-text approval message."].join(" ");if(a.deliveryState==="notifying")return[`A plan approval prompt is already being delivered for session ${a.name} [${d}].`,"Wait for delivery to finish before retrying."].join(" ");let u=this.interactions.getPlanApprovalButtons(d,{...a,planDecisionVersion:l}),f=[`📋 [${a.name}] Plan v${l??"?"} needs your decision:`,"","Why this was escalated:","",o,"","Choose Approve, Revise, or Reject below."].join(`
285
285
  `);return this.notifications.dispatch(this.buildRoutingProxy({id:d,name:a.name,sessionId:s?.sessionId,harnessSessionId:i?.harnessSessionId??s?.harnessSessionId,backendRef:i?.backendRef??s?.backendRef,route:i?.route??s?.route}),{label:"plan-approval",idempotencyKey:`plan-approval:${d}:v${l??"unknown"}:canonical`,userMessage:f,notifyUser:"always",buttons:u,hooks:{onNotifyStarted:()=>{this.updatePersistedSession(d,{approvalPromptRequiredVersion:l,approvalPromptStatus:"sending",approvalPromptVersion:l,approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.updatePersistedSession(d,{canonicalPlanPromptVersion:l,approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.updatePersistedSession(d,{approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>this.isCurrentPendingPlanDecision(d,l),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(this.buildRoutingProxy({id:d,name:a.name,sessionId:s?.sessionId,harnessSessionId:i?.harnessSessionId??s?.harnessSessionId,backendRef:i?.backendRef??s?.backendRef,route:i?.route??s?.route}),l,o),wakeMessageOnNotifySuccess:un({id:d,name:a.name},l)}),[`Canonical plan approval prompt sent for session ${a.name} [${d}].`,"Wait for the user's Approve, Revise, or Reject response.","Do not send a separate plain-text approval message."].join(" ")}requestWorktreeDecisionFromUser(e,n){let r=n.trim();if(!r)return"Error: summary must not be empty.";let o=this.resolve(e),i=this.getPersistedSession(e),s=o??i;if(!s)return`Error: Session "${e}" not found.`;if(s.worktreeStrategy!=="delegate")return`Error: Session "${e}" already uses direct user worktree decisions. Do not send a duplicate decision prompt.`;if(!(!!("pendingWorktreeDecisionSince"in s?s.pendingWorktreeDecisionSince:void 0)||s.worktreeState==="pending_decision"||s.worktreeLifecycle?.state==="pending_decision"))return`Error: Session "${e}" is not awaiting a delegated worktree decision.`;let l=G(o??i??{id:e})??e,u=o?.worktreePath??i?.worktreePath,f=o?.worktreeBranch??i?.worktreeBranch,p=this.resolveWorktreeRepoDir(o?.originalWorkdir??i?.workdir,u);if(!u)return`Error: Session "${e}" has no managed worktree path.`;if(!f)return`Error: Session "${e}" has no managed worktree branch.`;if(!p)return`Error: Session "${e}" has no resolvable repository root for worktree ${u}.`;let k=o?.worktreeBaseBranch??i?.worktreeBaseBranch??Fe(p),m=Qe(p,f,k);if(!m)return`Error: Could not compute worktree diff summary for session "${e}".`;let c=this.getPolicyAwareWorktreeDecisionButtons(l,{allowDelegate:!0},o,i);if(!c||c.length===0)return`Error: Could not create worktree decision buttons for session "${e}".`;let h=r.split(/\r?\n/).map(S=>S.replace(/^[-*]\s+/,"").trim()).filter(S=>S.length>0);return this.notifications.dispatch(this.buildRoutingProxy({id:l,name:s.name,sessionId:i?.sessionId,harnessSessionId:o?.harnessSessionId??i?.harnessSessionId,backendRef:o?.backendRef??i?.backendRef,route:o?.route??i?.route}),this.worktreeMessages.buildAskNotification({session:{id:l,name:s.name,worktreePrTargetRepo:o?.worktreePrTargetRepo??i?.worktreePrTargetRepo},branchName:f,baseBranch:k,diffSummary:m,summaryLines:h,buttons:c})),[`Canonical worktree decision prompt sent for session ${s.name} [${l}].`,"Wait for the user's Merge, Open PR, Later, or Discard response.","Do not send a separate plain-text worktree decision message."].join(" ")}buildRoutingProxy(e){return{id:G(e)??O(e)??e.harnessSessionId??"unknown-session",name:e.name,harnessSessionId:e.harnessSessionId,backendRef:e.backendRef?{...e.backendRef}:void 0,route:e.route}}resolveWorktreeRepoDir(e,n){return e&&(!n||!No(e,n))||!n?e:Vr(n)??e}formatLaunchWorkdirLabel(e){if(!e.worktreePath)return e.workdir;let n=this.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath);return!n||n===e.worktreePath?e.worktreePath:`${e.worktreePath} (worktree of ${n})`}async dismissWorktree(e){return this.worktreeDecisions.dismissWorktree(e)}snoozeWorktreeDecision(e,n){return this.worktreeDecisions.snoozeWorktreeDecision(e,n)}async handleWorktreeStrategy(e){return this.worktreeStrategy.handleWorktreeStrategy(e)}async onSessionTerminal(e){if(e.autoMergeParentSessionId){await this.handleAutoMergeResolverTerminal(e);return}return this.lifecycle.handleSessionTerminal(e)}async handleAutoMergeResolverTerminal(e){this.persistSession(e),this.clearWaitingTimestampsForSession(e.id),this.wakeDispatcher.clearRetryTimersForSession(e.id);let n=e.autoMergeParentSessionId;if(!n)return;let r=this.resolve(n),o=this.getPersistedSession(n),i=r??(o?this.buildRoutingProxy({id:o.sessionId,name:o.name,sessionId:o.sessionId,harnessSessionId:o.harnessSessionId,backendRef:o.backendRef,route:o.route}):void 0);if(!i){`${e.id}${n}`;return}if(e.status==="completed"&&r){this.updatePersistedSession(n,{autoMergeResolverSessionId:void 0}),await this.handleWorktreeStrategy(r);return}let s=r?.worktreeBranch??o?.worktreeBranch??"unknown",a=r?.worktreePath??o?.worktreePath??"(unknown worktree)",d=r?.worktreeBaseBranch??o?.worktreeBaseBranch,l=r?.worktreePrTargetRepo??o?.worktreePrTargetRepo,u=r?.worktreePushRemote??o?.worktreePushRemote;this.updatePersistedSession(n,lo({worktreeBaseBranch:d,worktreePrTargetRepo:l,worktreePushRemote:u},{clearResolverSessionId:!0,notes:[e.status==="completed"?"auto_merge_conflict_resolver_completed_without_retry_target":"auto_merge_conflict_resolver_failed"]})),this.dispatchSessionNotification(i,{label:"worktree-merge-conflict-resolver-failed",idempotencyKey:`worktree-merge-conflict-resolver-failed:${n}:${e.id}`,userMessage:[`⚠️ [${i.name}] Auto-merge conflict resolution did not complete successfully.`,`Branch \`${s}\` was preserved for manual follow-up in ${a}.`,e.status==="completed"?"The resolver finished, but the original session could not be resumed for the merge retry.":`Resolver session ${e.name} ended with status=${e.status}.`].join(`
286
286
  `),buttons:this.getPolicyAwareWorktreeDecisionButtons(n,{allowDelegate:!0},r,o)})}persistSession(e,n={}){let r=n.scheduleRuntimeGc??!0;this.store.hasRecordedSession(e.id)||this.metrics.recordSession(e),this.store.persistTerminal(e),r&&this.syncRuntimeGcDeadline(e),this.onPersistedSessionChanged(this.store.getPersistedSession(e.id)),this.syncTmpOutputCleanupDeadline()}reconcilePersistedTaskFlowMirrors(){let e=!1;for(let n of this.store.listPersistedSessions()){let r=Wd(n);r&&(n.taskFlowMirror=r,e=!0)}e&&this.store.saveIndex()}getMetrics(){return this.metrics.getMetrics()}notifySession(e,n,r="notification",o){this.dispatchSessionNotification(e,{label:r,idempotencyKey:r==="agent-respond"?void 0:o??`notify:${e.id}:${r}:${n}`,userMessage:n,notifyUser:"always"})}notifyResumedLaunch(e){if(!e.resumeSessionId)return;let n=this.formatLaunchWorkdirLabel(e),r=ut({harness:e.harnessName,model:e.model})??"default";this.notifySession(e,dr({sessionName:e.name,resumedFromSessionName:e.resumedFromSessionName,workdirLabel:n,harnessLabel:r}),"resumed-launch",`resumed-launch:${e.id}:${e.startedAt}:${e.resumeSessionId}`)}sendPlanOffer(e){let n=this.interactions.getPlanOfferButtons({offerId:e.offerId,route:e.route,planName:e.planName,planPrompt:e.planPrompt,planWorkdir:e.planWorkdir,planWorktreeStrategy:e.planWorktreeStrategy});this.dispatchSessionNotification(this.buildRoutingProxy({id:e.offerId,route:e.route}),{label:"plan-offer",idempotencyKey:`plan-offer:${e.offerId}`,userMessage:e.text,notifyUser:"always",buttons:n})}emitGoalTaskUpdate(e,n,r="goal-task"){let o=e.sessionId??e.id,i=this.buildRoutingProxy({id:o,name:e.sessionName??e.name,route:e.route});i.originChannel=e.originChannel,i.originThreadId=e.originThreadId,i.originSessionKey=e.originSessionKey;let s=r==="goal-task-succeeded",a=[`✅ [${e.name}] Goal task succeeded`,e.sessionId?`Session: ${e.sessionName??e.name} [${e.sessionId}]`:void 0].filter(l=>!!l).join(`
287
- `),d=l=>Xs({sessionId:o,sessionName:e.sessionName,taskName:e.name,summary:n,originThreadLine:hn(i),canonicalStatusDelivered:l});this.dispatchSessionNotification(i,{label:r,idempotencyKey:`goal:${e.id}:${r}:${s?"success":n}`,userMessage:s?a:n,notifyUser:"always",completionSummary:s?{required:!0,producer:"goal",outcomeKey:`goal:${e.id}`}:void 0,completionWakeSummaryRequired:s,completionWakeOutcomeKey:s?`goal:${e.id}`:void 0,wakeMessageOnNotifySuccess:s?d(!0):void 0,wakeMessageOnNotifyFailed:s?d(!1):void 0})}launchPlanOffer(e){let n=e.route??{provider:"system",target:"system"};return this.spawn({prompt:e.prompt,workdir:e.workdir,name:e.name,harness:fe(),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<pv?!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 hn(e)}extractLastOutputLine(e){return e.getOutput(3).filter(o=>o.trim()).pop()?.trim()||void 0}getOutputPreview(e,n=1e3){return qc(e,n)}resolvePlanApprovalMode(e){return e.planApproval??D.planApproval??"delegate"}shouldEmitTurnCompleteWake(e){let n=`${e.startedAt??0}|${e.result?.session_id??""}|${e.result?.num_turns??0}`;return this.lastTurnCompleteMarkers.get(e.id)===n?(`${e.id}${n}`,!1):(this.lastTurnCompleteMarkers.set(e.id,n),!0)}shouldEmitTerminalWake(e){let n=`${e.status}|${e.startedAt??0}|${e.result?.session_id??""}|${e.result?.num_turns??0}|${e.killReason}`;return this.lastTerminalWakeMarkers.get(e.id)===n?!1:(this.lastTerminalWakeMarkers.set(e.id,n),!0)}resolve(e){return this.references.resolveActive(e)}get(e){return this.registry.get(e)}list(e){let n=this.registry.list();return e&&e!=="all"&&(n=n.filter(r=>r.status===e)),n.sort((r,o)=>o.startedAt-r.startedAt)}kill(e,n){let r=this.registry.get(e);if(!r)return!1;if(r.pendingPlanApproval){this.clearPlanDecisionTokens(r.id);let o={lifecycle:"terminal",runtimeState:"stopped",pendingPlanApproval:!1,planApprovalContext:void 0,approvalState:r.approvalState==="pending"?"rejected":r.approvalState,planDecisionVersion:(r.planDecisionVersion??0)+1,actionablePlanDecisionVersion:void 0,canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:void 0,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",approvalPromptTransport:"none",approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:void 0};r.applyControlPatch(o),Object.assign(r,o),this.updatePersistedSession(r.id,o)}return r.kill(n??"user"),!0}killAll(e="user"){for(let n of this.sessions.values())cv.has(n.status)&&this.kill(n.id,e)}resolveBackendConversationId(e){return this.references.resolveBackendConversationId(e)}resolveHarnessSessionId(e){return this.resolveBackendConversationId(e)}getPersistedSession(e){return this.references.getPersistedSession(e)}isAlreadyMerged(e){if(!e)return!1;let n=this.store.getPersistedSession(e);return n?.worktreeMerged===!0||n?.worktreeLifecycle?.state==="merged"||n?.worktreeLifecycle?.state==="released"}async enqueueMerge(e,n,r){return this.mergeQueue.enqueue(e,n,r)}updatePersistedSession(e,n){let r=this.stateSync.applySessionPatch(e,n);return r&&this.onPersistedSessionChanged(this.store.getPersistedSession(e)),r}listPersistedSessions(){return this.store.listPersistedSessions()}async handleAskUserQuestion(e,n){let r=this.sessions.get(e);if(!r)throw new Error(`Session "${e}" not found for AskUserQuestion intercept`);return this.questions.handleAskUserQuestion(r,n)}resolveAskUserQuestion(e,n,r={}){return this.questions.resolveAskUserQuestion(e,n,r)}async resolvePendingInputOption(e,n,r={}){let o=this.sessions.get(e);return o?.canSubmitPendingInputOption?.()?await o.submitPendingInputOption(n,r)?(this.clearWaitingTimestampsForSession(e),!0):!1:this.questions.resolveAskUserQuestion(e,n,r)}canSubmitPendingInputOption(e){return this.sessions.get(e)?.canSubmitPendingInputOption?.()===!0}consumeQuestionAnswerTokens(e,n){return this.interactions.consumeQuestionAnswerTokens(e,n)}dispose(){this.disposeMaintenance(),this.questions.dispose(),this.notifications.dispose()}};V();yt();ae();ke();import{definePluginEntry as Hc}from"openclaw/plugin-sdk/plugin-entry";function Sv(t){let e=parseInt(process.env.OPENCLAW_WORKTREE_CLEANUP_AGE_HOURS??"168",10)||168,n=e*60*60*1e3,r=Date.now()-n,o=new Set(t.listPersistedSessions().map(d=>d.worktreePath).filter(d=>typeof d=="string"&&d.length>0)),i=new Set,s=process.env.OPENCLAW_WORKTREE_DIR??D.worktreeDir;if(s)i.add(s);else for(let d of t.listPersistedSessions())if(d.workdir)try{let l=kv("git",["rev-parse","--show-toplevel"],{cwd:d.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();l&&i.add(va(l,".worktrees"))}catch{}if(i.size===0)return;let a=0;for(let d of i)try{let l=gv(d);for(let u of l){if(!u.startsWith("openclaw-worktree-"))continue;let f=va(d,u);try{let p=hv(f);if(!p.isDirectory()||p.mtimeMs>r||o.has(f))continue;yv(f,{recursive:!0,force:!0}),a++}catch(p){`${f}${p instanceof Error?p.message:String(p)}`}}}catch{}a>0&&`${a}${e}`}function vv(t){if(!t||typeof t!="object")return;let e=t,n=e.channel?.trim().toLowerCase();if(!n)return;let r=n==="telegram"?e.callback?.chatId??e.parentConversationId??e.conversationId:e.parentConversationId??e.conversationId??e.callback?.chatId;if(r)return _e(e.accountId?`${n}|${e.accountId}|${r}`:`${n}|${r}`,e.threadId,e.sessionKey)}function wv(t){let e=null,n=null,r=null,o=!1,i=!1,s=t.registerTool;Ot(t.runtime);let a=()=>va(zo(process.env),"plugin-state","openclaw-code-agent"),d=c=>{let h=c.deliveryContext;return h?.channel&&h.to?_e(h.accountId?`${h.channel}|${h.accountId}|${h.to}`:`${h.channel}|${h.to}`,h.threadId,c.sessionKey):_e(c.messageChannel,void 0,c.sessionKey)},l=c=>{r?.maybeCheckForUpdate({route:c})},u=c=>{if(o){c&&!i&&(Ot(t.runtime,c.config),i=!0);return}let h=t.pluginConfig??{};Ba(h),c?(Ot(t.runtime,c.config),i=!0):(Ot(t.runtime),i=!1),e=new vi(D.maxSessions,D.maxPersistedSessions,{worktreeSummaryProvider:oc()}),n=new Oo(e),r=new sr({stateDir:c?.stateDir??a(),currentVersion:t.version??ba.version??"0.0.0",actionButtonFactory:(S,b,x,T)=>e.makePluginActionButton(S,b,x,T)}),Ui(e),Ki(n),Vi(r),n.start(),Sv(e),e.bootstrapMaintenanceSchedules(),o=!0,l()},f=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=null,o=!1,i=!1,Ot(void 0),Ki(null),Ui(null),Vi(null)},p=(c,h)=>{s(S=>(u(),l(d(S)),c(S)),h)},k={...t,registerCommand(c){t.registerCommand({...c,handler:h=>(u(),l(d(h)),c.handler(h))})}},m=c=>{let h=mu(c);t.registerInteractiveHandler({...h,handler:async S=>(u(),l(vv(S)),h.handler(S))})};p(c=>Bd(c),{optional:!1,name:"agent_launch"}),p(c=>Sl(c),{optional:!1,name:"agent_sessions"}),p(c=>vl(c),{optional:!1,name:"agent_kill"}),p(c=>oo(c),{optional:!1,name:"agent_output"}),p(c=>Il(c),{optional:!1,name:"agent_respond"}),p(c=>xl(c),{optional:!1,name:"agent_request_plan_approval"}),p(c=>Tl(c),{optional:!1,name:"agent_request_worktree_decision"}),p(c=>_l(c),{optional:!1,name:"agent_send_plan_offer"}),p(c=>$l(c),{optional:!1,name:"agent_stats"}),p(c=>Wl(c),{optional:!1,name:"agent_repo_policy"}),p(c=>go(c),{optional:!1,name:"agent_merge"}),p(c=>jn(c),{optional:!1,name:"agent_pr"}),p(c=>eu(c),{optional:!1,name:"agent_worktree_cleanup"}),p(c=>tu(c),{optional:!1,name:"agent_worktree_status"}),p(c=>nu(c),{optional:!1,name:"agent_goal_launch"}),p(c=>ou(c),{optional:!1,name:"agent_goal_status"}),p(c=>iu(c),{optional:!1,name:"agent_goal_stop"}),p(c=>su(c),{optional:!1,name:"agent_goal_edit"}),m("telegram"),m("discord"),gu(k),hu(k),yu(k),ku(k),Su(k),vu(k),wu(k),bu(k),Ru(k),Au(k),xu(k),t.registerService({id:"openclaw-code-agent",start:u,stop:f})}var WM=Hc({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:wv});export{WM as default,wv as register,vv as routeFromInteractiveContext};
287
+ `),d=l=>Xs({sessionId:o,sessionName:e.sessionName,taskName:e.name,summary:n,originThreadLine:hn(i),canonicalStatusDelivered:l});this.dispatchSessionNotification(i,{label:r,idempotencyKey:`goal:${e.id}:${r}:${s?"success":n}`,userMessage:s?a:n,notifyUser:"always",completionSummary:s?{required:!0,producer:"goal",outcomeKey:`goal:${e.id}`}:void 0,completionWakeSummaryRequired:s,completionWakeOutcomeKey:s?`goal:${e.id}`:void 0,wakeMessageOnNotifySuccess:s?d(!0):void 0,wakeMessageOnNotifyFailed:s?d(!1):void 0})}launchPlanOffer(e){let n=e.route??{provider:"system",target:"system"};return this.spawn({prompt:e.prompt,workdir:e.workdir,name:e.name,harness:fe(),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<pv?!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 hn(e)}extractLastOutputLine(e){return e.getOutput(3).filter(o=>o.trim()).pop()?.trim()||void 0}getOutputPreview(e,n=1e3){return qc(e,n)}resolvePlanApprovalMode(e){return e.planApproval??D.planApproval??"delegate"}shouldEmitTurnCompleteWake(e){let n=`${e.startedAt??0}|${e.result?.session_id??""}|${e.result?.num_turns??0}`;return this.lastTurnCompleteMarkers.get(e.id)===n?(`${e.id}${n}`,!1):(this.lastTurnCompleteMarkers.set(e.id,n),!0)}shouldEmitTerminalWake(e){let n=`${e.status}|${e.startedAt??0}|${e.result?.session_id??""}|${e.result?.num_turns??0}|${e.killReason}`;return this.lastTerminalWakeMarkers.get(e.id)===n?!1:(this.lastTerminalWakeMarkers.set(e.id,n),!0)}resolve(e){return this.references.resolveActive(e)}get(e){return this.registry.get(e)}list(e){let n=this.registry.list();return e&&e!=="all"&&(n=n.filter(r=>r.status===e)),n.sort((r,o)=>o.startedAt-r.startedAt)}kill(e,n){let r=this.registry.get(e);if(!r)return!1;if(r.pendingPlanApproval){this.clearPlanDecisionTokens(r.id);let o={lifecycle:"terminal",runtimeState:"stopped",pendingPlanApproval:!1,planApprovalContext:void 0,approvalState:r.approvalState==="pending"?"rejected":r.approvalState,planDecisionVersion:(r.planDecisionVersion??0)+1,actionablePlanDecisionVersion:void 0,canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:void 0,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",approvalPromptTransport:"none",approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:void 0};r.applyControlPatch(o),Object.assign(r,o),this.updatePersistedSession(r.id,o)}return r.kill(n??"user"),!0}killAll(e="user"){for(let n of this.sessions.values())cv.has(n.status)&&this.kill(n.id,e)}resolveBackendConversationId(e){return this.references.resolveBackendConversationId(e)}resolveHarnessSessionId(e){return this.resolveBackendConversationId(e)}getPersistedSession(e){return this.references.getPersistedSession(e)}isAlreadyMerged(e){if(!e)return!1;let n=this.store.getPersistedSession(e);return n?.worktreeMerged===!0||n?.worktreeLifecycle?.state==="merged"||n?.worktreeLifecycle?.state==="released"}async enqueueMerge(e,n,r){return this.mergeQueue.enqueue(e,n,r)}updatePersistedSession(e,n){let r=this.stateSync.applySessionPatch(e,n);return r&&this.onPersistedSessionChanged(this.store.getPersistedSession(e)),r}listPersistedSessions(){return this.store.listPersistedSessions()}async handleAskUserQuestion(e,n){let r=this.sessions.get(e);if(!r)throw new Error(`Session "${e}" not found for AskUserQuestion intercept`);return this.questions.handleAskUserQuestion(r,n)}resolveAskUserQuestion(e,n,r={}){return this.questions.resolveAskUserQuestion(e,n,r)}async resolvePendingInputOption(e,n,r={}){let o=this.sessions.get(e);return o?.canSubmitPendingInputOption?.()?await o.submitPendingInputOption(n,r)?(this.clearWaitingTimestampsForSession(e),!0):!1:this.questions.resolveAskUserQuestion(e,n,r)}canSubmitPendingInputOption(e){return this.sessions.get(e)?.canSubmitPendingInputOption?.()===!0}pendingInputSubmissionRequiresMore(e){return this.sessions.get(e)?.pendingInputSubmissionRequiresMore()===!0}consumeQuestionAnswerTokens(e,n,r){return this.interactions.consumeQuestionAnswerTokens(e,n,r)}dispose(){this.disposeMaintenance(),this.questions.dispose(),this.notifications.dispose()}};V();yt();ae();ke();import{definePluginEntry as Hc}from"openclaw/plugin-sdk/plugin-entry";function Sv(t){let e=parseInt(process.env.OPENCLAW_WORKTREE_CLEANUP_AGE_HOURS??"168",10)||168,n=e*60*60*1e3,r=Date.now()-n,o=new Set(t.listPersistedSessions().map(d=>d.worktreePath).filter(d=>typeof d=="string"&&d.length>0)),i=new Set,s=process.env.OPENCLAW_WORKTREE_DIR??D.worktreeDir;if(s)i.add(s);else for(let d of t.listPersistedSessions())if(d.workdir)try{let l=kv("git",["rev-parse","--show-toplevel"],{cwd:d.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();l&&i.add(va(l,".worktrees"))}catch{}if(i.size===0)return;let a=0;for(let d of i)try{let l=gv(d);for(let u of l){if(!u.startsWith("openclaw-worktree-"))continue;let f=va(d,u);try{let p=hv(f);if(!p.isDirectory()||p.mtimeMs>r||o.has(f))continue;yv(f,{recursive:!0,force:!0}),a++}catch(p){`${f}${p instanceof Error?p.message:String(p)}`}}}catch{}a>0&&`${a}${e}`}function vv(t){if(!t||typeof t!="object")return;let e=t,n=e.channel?.trim().toLowerCase();if(!n)return;let r=n==="telegram"?e.callback?.chatId??e.parentConversationId??e.conversationId:e.parentConversationId??e.conversationId??e.callback?.chatId;if(r)return _e(e.accountId?`${n}|${e.accountId}|${r}`:`${n}|${r}`,e.threadId,e.sessionKey)}function wv(t){let e=null,n=null,r=null,o=!1,i=!1,s=t.registerTool;Ot(t.runtime);let a=()=>va(zo(process.env),"plugin-state","openclaw-code-agent"),d=c=>{let h=c.deliveryContext;return h?.channel&&h.to?_e(h.accountId?`${h.channel}|${h.accountId}|${h.to}`:`${h.channel}|${h.to}`,h.threadId,c.sessionKey):_e(c.messageChannel,void 0,c.sessionKey)},l=c=>{r?.maybeCheckForUpdate({route:c})},u=c=>{if(o){c&&!i&&(Ot(t.runtime,c.config),i=!0);return}let h=t.pluginConfig??{};Ba(h),c?(Ot(t.runtime,c.config),i=!0):(Ot(t.runtime),i=!1),e=new vi(D.maxSessions,D.maxPersistedSessions,{worktreeSummaryProvider:oc()}),n=new Oo(e),r=new sr({stateDir:c?.stateDir??a(),currentVersion:t.version??ba.version??"0.0.0",actionButtonFactory:(S,P,x,C)=>e.makePluginActionButton(S,P,x,C)}),Ui(e),Ki(n),Vi(r),n.start(),Sv(e),e.bootstrapMaintenanceSchedules(),o=!0,l()},f=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=null,o=!1,i=!1,Ot(void 0),Ki(null),Ui(null),Vi(null)},p=(c,h)=>{s(S=>(u(),l(d(S)),c(S)),h)},k={...t,registerCommand(c){t.registerCommand({...c,handler:h=>(u(),l(d(h)),c.handler(h))})}},m=c=>{let h=mu(c);t.registerInteractiveHandler({...h,handler:async S=>(u(),l(vv(S)),h.handler(S))})};p(c=>Bd(c),{optional:!1,name:"agent_launch"}),p(c=>Sl(c),{optional:!1,name:"agent_sessions"}),p(c=>vl(c),{optional:!1,name:"agent_kill"}),p(c=>oo(c),{optional:!1,name:"agent_output"}),p(c=>Il(c),{optional:!1,name:"agent_respond"}),p(c=>xl(c),{optional:!1,name:"agent_request_plan_approval"}),p(c=>Tl(c),{optional:!1,name:"agent_request_worktree_decision"}),p(c=>_l(c),{optional:!1,name:"agent_send_plan_offer"}),p(c=>$l(c),{optional:!1,name:"agent_stats"}),p(c=>Wl(c),{optional:!1,name:"agent_repo_policy"}),p(c=>go(c),{optional:!1,name:"agent_merge"}),p(c=>jn(c),{optional:!1,name:"agent_pr"}),p(c=>eu(c),{optional:!1,name:"agent_worktree_cleanup"}),p(c=>tu(c),{optional:!1,name:"agent_worktree_status"}),p(c=>nu(c),{optional:!1,name:"agent_goal_launch"}),p(c=>ou(c),{optional:!1,name:"agent_goal_status"}),p(c=>iu(c),{optional:!1,name:"agent_goal_stop"}),p(c=>su(c),{optional:!1,name:"agent_goal_edit"}),m("telegram"),m("discord"),gu(k),hu(k),yu(k),ku(k),Su(k),vu(k),wu(k),bu(k),Ru(k),Au(k),xu(k),t.registerService({id:"openclaw-code-agent",start:u,stop:f})}var WM=Hc({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:wv});export{WM as default,wv as register,vv as routeFromInteractiveContext};