From d9b4c73b31bd5c2d277af84872336b80385388f5 Mon Sep 17 00:00:00 2001 From: "Marcus R. Brown" Date: Sat, 28 Mar 2026 06:15:11 -0700 Subject: [PATCH 1/2] fix(session): preserve logical thread continuity --- dist/main.js | 68 +++---- ...3-28-session-continuity-post-ship-audit.md | 188 ++++++++++++++++++ src/features/agent/execution.ts | 23 +-- src/features/agent/opencode.test.ts | 65 ++++++ src/features/agent/prompt.test.ts | 50 +++++ src/features/agent/prompt.ts | 11 +- src/harness/phases/execute.ts | 3 + src/services/session/title-reassert.ts | 34 ++++ 8 files changed, 393 insertions(+), 49 deletions(-) create mode 100644 docs/audits/2026-03-28-session-continuity-post-ship-audit.md create mode 100644 src/services/session/title-reassert.ts diff --git a/dist/main.js b/dist/main.js index e6ac94b0..1ac65dc2 100644 --- a/dist/main.js +++ b/dist/main.js @@ -123,31 +123,31 @@ import{A as e,B as t,C as n,D as r,E as i,F as a,G as o,H as s,I as c,J as l,K a `);o=c.pop()??``;for(let e of c){let i=e.split(` `),a=[],o;for(let e of i)if(e.startsWith(`data:`))a.push(e.replace(/^data:\s*/,``));else if(e.startsWith(`event:`))o=e.replace(/^event:\s*/,``);else if(e.startsWith(`id:`))u=e.replace(/^id:\s*/,``);else if(e.startsWith(`retry:`)){let t=Number.parseInt(e.replace(/^retry:\s*/,``),10);Number.isNaN(t)||(s=t)}let c,l=!1;if(a.length){let e=a.join(` -`);try{c=JSON.parse(e),l=!0}catch{c=e}}l&&(r&&await r(c),n&&(c=await n(c))),t?.({data:c,event:o,id:u,retry:s}),a.length&&(yield c)}}}finally{p.removeEventListener(`abort`,d),a.releaseLock()}break}catch(t){if(e?.(t),a!==void 0&&f>=a)break;await d(Math.min(s*2**(f-1),o??3e4))}}}()}},gt=async(e,t)=>{let n=typeof t==`function`?await t(e):t;if(n)return e.scheme===`bearer`?`Bearer ${n}`:e.scheme===`basic`?`Basic ${btoa(n)}`:n},_t={bodySerializer:e=>JSON.stringify(e,(e,t)=>typeof t==`bigint`?t.toString():t)},vt=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},yt=e=>{switch(e){case`form`:return`,`;case`pipeDelimited`:return`|`;case`spaceDelimited`:return`%20`;default:return`,`}},bt=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},xt=({allowReserved:e,explode:t,name:n,style:r,value:i})=>{if(!t){let t=(e?i:i.map(e=>encodeURIComponent(e))).join(yt(r));switch(r){case`label`:return`.${t}`;case`matrix`:return`;${n}=${t}`;case`simple`:return t;default:return`${n}=${t}`}}let a=vt(r),o=i.map(t=>r===`label`||r===`simple`?e?t:encodeURIComponent(t):B({allowReserved:e,name:n,value:t})).join(a);return r===`label`||r===`matrix`?a+o:o},B=({allowReserved:e,name:t,value:n})=>{if(n==null)return``;if(typeof n==`object`)throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${t}=${e?n:encodeURIComponent(n)}`},St=({allowReserved:e,explode:t,name:n,style:r,value:i,valueOnly:a})=>{if(i instanceof Date)return a?i.toISOString():`${n}=${i.toISOString()}`;if(r!==`deepObject`&&!t){let t=[];Object.entries(i).forEach(([n,r])=>{t=[...t,n,e?r:encodeURIComponent(r)]});let a=t.join(`,`);switch(r){case`form`:return`${n}=${a}`;case`label`:return`.${a}`;case`matrix`:return`;${n}=${a}`;default:return a}}let o=bt(r),s=Object.entries(i).map(([t,i])=>B({allowReserved:e,name:r===`deepObject`?`${n}[${t}]`:t,value:i})).join(o);return r===`label`||r===`matrix`?o+s:s},Ct=/\{[^{}]+\}/g,wt=({path:e,url:t})=>{let n=t,r=t.match(Ct);if(r)for(let t of r){let r=!1,i=t.substring(1,t.length-1),a=`simple`;i.endsWith(`*`)&&(r=!0,i=i.substring(0,i.length-1)),i.startsWith(`.`)?(i=i.substring(1),a=`label`):i.startsWith(`;`)&&(i=i.substring(1),a=`matrix`);let o=e[i];if(o==null)continue;if(Array.isArray(o)){n=n.replace(t,xt({explode:r,name:i,style:a,value:o}));continue}if(typeof o==`object`){n=n.replace(t,St({explode:r,name:i,style:a,value:o,valueOnly:!0}));continue}if(a===`matrix`){n=n.replace(t,`;${B({name:i,value:o})}`);continue}let s=encodeURIComponent(a===`label`?`.${o}`:o);n=n.replace(t,s)}return n},Tt=({baseUrl:e,path:t,query:n,querySerializer:r,url:i})=>{let a=i.startsWith(`/`)?i:`/${i}`,o=(e??``)+a;t&&(o=wt({path:t,url:o}));let s=n?r(n):``;return s.startsWith(`?`)&&(s=s.substring(1)),s&&(o+=`?${s}`),o},Et=({allowReserved:e,array:t,object:n}={})=>r=>{let i=[];if(r&&typeof r==`object`)for(let a in r){let o=r[a];if(o!=null)if(Array.isArray(o)){let n=xt({allowReserved:e,explode:!0,name:a,style:`form`,value:o,...t});n&&i.push(n)}else if(typeof o==`object`){let t=St({allowReserved:e,explode:!0,name:a,style:`deepObject`,value:o,...n});t&&i.push(t)}else{let t=B({allowReserved:e,name:a,value:o});t&&i.push(t)}}return i.join(`&`)},Dt=e=>{if(!e)return`stream`;let t=e.split(`;`)[0]?.trim();if(t){if(t.startsWith(`application/json`)||t.endsWith(`+json`))return`json`;if(t===`multipart/form-data`)return`formData`;if([`application/`,`audio/`,`image/`,`video/`].some(e=>t.startsWith(e)))return`blob`;if(t.startsWith(`text/`))return`text`}},Ot=(e,t)=>t?!!(e.headers.has(t)||e.query?.[t]||e.headers.get(`Cookie`)?.includes(`${t}=`)):!1,kt=async({security:e,...t})=>{for(let n of e){if(Ot(t,n.name))continue;let e=await gt(n,t.auth);if(!e)continue;let r=n.name??`Authorization`;switch(n.in){case`query`:t.query||={},t.query[r]=e;break;case`cookie`:t.headers.append(`Cookie`,`${r}=${e}`);break;default:t.headers.set(r,e);break}}},At=e=>Tt({baseUrl:e.baseUrl,path:e.path,query:e.query,querySerializer:typeof e.querySerializer==`function`?e.querySerializer:Et(e.querySerializer),url:e.url}),jt=(e,t)=>{let n={...e,...t};return n.baseUrl?.endsWith(`/`)&&(n.baseUrl=n.baseUrl.substring(0,n.baseUrl.length-1)),n.headers=Mt(e.headers,t.headers),n},Mt=(...e)=>{let t=new Headers;for(let n of e){if(!n||typeof n!=`object`)continue;let e=n instanceof Headers?n.entries():Object.entries(n);for(let[n,r]of e)if(r===null)t.delete(n);else if(Array.isArray(r))for(let e of r)t.append(n,e);else r!==void 0&&t.set(n,typeof r==`object`?JSON.stringify(r):r)}return t};var Nt=class{_fns;constructor(){this._fns=[]}clear(){this._fns=[]}getInterceptorIndex(e){return typeof e==`number`?this._fns[e]?e:-1:this._fns.indexOf(e)}exists(e){let t=this.getInterceptorIndex(e);return!!this._fns[t]}eject(e){let t=this.getInterceptorIndex(e);this._fns[t]&&(this._fns[t]=null)}update(e,t){let n=this.getInterceptorIndex(e);return this._fns[n]?(this._fns[n]=t,e):!1}use(e){return this._fns=[...this._fns,e],this._fns.length-1}};const Pt=()=>({error:new Nt,request:new Nt,response:new Nt}),Ft=Et({allowReserved:!1,array:{explode:!0,style:`form`},object:{explode:!0,style:`deepObject`}}),It={"Content-Type":`application/json`},Lt=(e={})=>({..._t,headers:It,parseAs:`auto`,querySerializer:Ft,...e}),Rt=(e={})=>{let t=jt(Lt(),e),n=()=>({...t}),r=e=>(t=jt(t,e),n()),i=Pt(),a=async e=>{let n={...t,...e,fetch:e.fetch??t.fetch??globalThis.fetch,headers:Mt(t.headers,e.headers),serializedBody:void 0};return n.security&&await kt({...n,security:n.security}),n.requestValidator&&await n.requestValidator(n),n.body&&n.bodySerializer&&(n.serializedBody=n.bodySerializer(n.body)),(n.serializedBody===void 0||n.serializedBody===``)&&n.headers.delete(`Content-Type`),{opts:n,url:At(n)}},o=async e=>{let{opts:t,url:n}=await a(e),r={redirect:`follow`,...t,body:t.serializedBody},o=new Request(n,r);for(let e of i.request._fns)e&&(o=await e(o,t));let s=t.fetch,c=await s(o);for(let e of i.response._fns)e&&(c=await e(c,o,t));let l={request:o,response:c};if(c.ok){if(c.status===204||c.headers.get(`Content-Length`)===`0`)return t.responseStyle===`data`?{}:{data:{},...l};let e=(t.parseAs===`auto`?Dt(c.headers.get(`Content-Type`)):t.parseAs)??`json`,n;switch(e){case`arrayBuffer`:case`blob`:case`formData`:case`json`:case`text`:n=await c[e]();break;case`stream`:return t.responseStyle===`data`?c.body:{data:c.body,...l}}return e===`json`&&(t.responseValidator&&await t.responseValidator(n),t.responseTransformer&&(n=await t.responseTransformer(n))),t.responseStyle===`data`?n:{data:n,...l}}let u=await c.text(),d;try{d=JSON.parse(u)}catch{}let f=d??u,p=f;for(let e of i.error._fns)e&&(p=await e(f,c,o,t));if(p||={},t.throwOnError)throw p;return t.responseStyle===`data`?void 0:{error:p,...l}},s=e=>{let t=t=>o({...t,method:e});return t.sse=async t=>{let{opts:n,url:r}=await a(t);return ht({...n,body:n.body,headers:n.headers,method:e,url:r})},t};return{buildUrl:At,connect:s(`CONNECT`),delete:s(`DELETE`),get:s(`GET`),getConfig:n,head:s(`HEAD`),interceptors:i,options:s(`OPTIONS`),patch:s(`PATCH`),post:s(`POST`),put:s(`PUT`),request:o,setConfig:r,trace:s(`TRACE`)}};Object.entries({$body_:`body`,$headers_:`headers`,$path_:`path`,$query_:`query`});const zt=Rt(Lt({baseUrl:`http://localhost:4096`}));var V=class{_client=zt;constructor(e){e?.client&&(this._client=e.client)}},Bt=class extends V{event(e){return(e?.client??this._client).get.sse({url:`/global/event`,...e})}},Vt=class extends V{list(e){return(e?.client??this._client).get({url:`/project`,...e})}current(e){return(e?.client??this._client).get({url:`/project/current`,...e})}},Ht=class extends V{list(e){return(e?.client??this._client).get({url:`/pty`,...e})}create(e){return(e?.client??this._client).post({url:`/pty`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}remove(e){return(e.client??this._client).delete({url:`/pty/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/pty/{id}`,...e})}update(e){return(e.client??this._client).put({url:`/pty/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}connect(e){return(e.client??this._client).get({url:`/pty/{id}/connect`,...e})}},Ut=class extends V{get(e){return(e?.client??this._client).get({url:`/config`,...e})}update(e){return(e?.client??this._client).patch({url:`/config`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}providers(e){return(e?.client??this._client).get({url:`/config/providers`,...e})}},Wt=class extends V{ids(e){return(e?.client??this._client).get({url:`/experimental/tool/ids`,...e})}list(e){return(e.client??this._client).get({url:`/experimental/tool`,...e})}},Gt=class extends V{dispose(e){return(e?.client??this._client).post({url:`/instance/dispose`,...e})}},Kt=class extends V{get(e){return(e?.client??this._client).get({url:`/path`,...e})}},qt=class extends V{get(e){return(e?.client??this._client).get({url:`/vcs`,...e})}},Jt=class extends V{list(e){return(e?.client??this._client).get({url:`/session`,...e})}create(e){return(e?.client??this._client).post({url:`/session`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}status(e){return(e?.client??this._client).get({url:`/session/status`,...e})}delete(e){return(e.client??this._client).delete({url:`/session/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/session/{id}`,...e})}update(e){return(e.client??this._client).patch({url:`/session/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}children(e){return(e.client??this._client).get({url:`/session/{id}/children`,...e})}todo(e){return(e.client??this._client).get({url:`/session/{id}/todo`,...e})}init(e){return(e.client??this._client).post({url:`/session/{id}/init`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}fork(e){return(e.client??this._client).post({url:`/session/{id}/fork`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}abort(e){return(e.client??this._client).post({url:`/session/{id}/abort`,...e})}unshare(e){return(e.client??this._client).delete({url:`/session/{id}/share`,...e})}share(e){return(e.client??this._client).post({url:`/session/{id}/share`,...e})}diff(e){return(e.client??this._client).get({url:`/session/{id}/diff`,...e})}summarize(e){return(e.client??this._client).post({url:`/session/{id}/summarize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}messages(e){return(e.client??this._client).get({url:`/session/{id}/message`,...e})}prompt(e){return(e.client??this._client).post({url:`/session/{id}/message`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}message(e){return(e.client??this._client).get({url:`/session/{id}/message/{messageID}`,...e})}promptAsync(e){return(e.client??this._client).post({url:`/session/{id}/prompt_async`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}command(e){return(e.client??this._client).post({url:`/session/{id}/command`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}shell(e){return(e.client??this._client).post({url:`/session/{id}/shell`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}revert(e){return(e.client??this._client).post({url:`/session/{id}/revert`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}unrevert(e){return(e.client??this._client).post({url:`/session/{id}/unrevert`,...e})}},Yt=class extends V{list(e){return(e?.client??this._client).get({url:`/command`,...e})}},Xt=class extends V{authorize(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/authorize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}callback(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Zt=class extends V{list(e){return(e?.client??this._client).get({url:`/provider`,...e})}auth(e){return(e?.client??this._client).get({url:`/provider/auth`,...e})}oauth=new Xt({client:this._client})},Qt=class extends V{text(e){return(e.client??this._client).get({url:`/find`,...e})}files(e){return(e.client??this._client).get({url:`/find/file`,...e})}symbols(e){return(e.client??this._client).get({url:`/find/symbol`,...e})}},$t=class extends V{list(e){return(e.client??this._client).get({url:`/file`,...e})}read(e){return(e.client??this._client).get({url:`/file/content`,...e})}status(e){return(e?.client??this._client).get({url:`/file/status`,...e})}},en=class extends V{log(e){return(e?.client??this._client).post({url:`/log`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}agents(e){return(e?.client??this._client).get({url:`/agent`,...e})}},tn=class extends V{remove(e){return(e.client??this._client).delete({url:`/mcp/{name}/auth`,...e})}start(e){return(e.client??this._client).post({url:`/mcp/{name}/auth`,...e})}callback(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}authenticate(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/authenticate`,...e})}set(e){return(e.client??this._client).put({url:`/auth/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},nn=class extends V{status(e){return(e?.client??this._client).get({url:`/mcp`,...e})}add(e){return(e?.client??this._client).post({url:`/mcp`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}connect(e){return(e.client??this._client).post({url:`/mcp/{name}/connect`,...e})}disconnect(e){return(e.client??this._client).post({url:`/mcp/{name}/disconnect`,...e})}auth=new tn({client:this._client})},rn=class extends V{status(e){return(e?.client??this._client).get({url:`/lsp`,...e})}},an=class extends V{status(e){return(e?.client??this._client).get({url:`/formatter`,...e})}},on=class extends V{next(e){return(e?.client??this._client).get({url:`/tui/control/next`,...e})}response(e){return(e?.client??this._client).post({url:`/tui/control/response`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}},sn=class extends V{appendPrompt(e){return(e?.client??this._client).post({url:`/tui/append-prompt`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}openHelp(e){return(e?.client??this._client).post({url:`/tui/open-help`,...e})}openSessions(e){return(e?.client??this._client).post({url:`/tui/open-sessions`,...e})}openThemes(e){return(e?.client??this._client).post({url:`/tui/open-themes`,...e})}openModels(e){return(e?.client??this._client).post({url:`/tui/open-models`,...e})}submitPrompt(e){return(e?.client??this._client).post({url:`/tui/submit-prompt`,...e})}clearPrompt(e){return(e?.client??this._client).post({url:`/tui/clear-prompt`,...e})}executeCommand(e){return(e?.client??this._client).post({url:`/tui/execute-command`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}showToast(e){return(e?.client??this._client).post({url:`/tui/show-toast`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}publish(e){return(e?.client??this._client).post({url:`/tui/publish`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}control=new on({client:this._client})},cn=class extends V{subscribe(e){return(e?.client??this._client).get.sse({url:`/event`,...e})}},ln=class extends V{postSessionIdPermissionsPermissionId(e){return(e.client??this._client).post({url:`/session/{id}/permissions/{permissionID}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}global=new Bt({client:this._client});project=new Vt({client:this._client});pty=new Ht({client:this._client});config=new Ut({client:this._client});tool=new Wt({client:this._client});instance=new Gt({client:this._client});path=new Kt({client:this._client});vcs=new qt({client:this._client});session=new Jt({client:this._client});command=new Yt({client:this._client});provider=new Zt({client:this._client});find=new Qt({client:this._client});file=new $t({client:this._client});app=new en({client:this._client});mcp=new nn({client:this._client});lsp=new rn({client:this._client});formatter=new an({client:this._client});tui=new sn({client:this._client});auth=new tn({client:this._client});event=new cn({client:this._client})};function un(e){if(!e?.fetch){let t=e=>(e.timeout=!1,fetch(e));e={...e,fetch:t}}return e?.directory&&(e.headers={...e.headers,"x-opencode-directory":encodeURIComponent(e.directory)}),new ln({client:Rt(e)})}async function dn(e){e=Object.assign({hostname:`127.0.0.1`,port:4096,timeout:5e3},e??{});let t=[`serve`,`--hostname=${e.hostname}`,`--port=${e.port}`];e.config?.logLevel&&t.push(`--log-level=${e.config.logLevel}`);let n=je(`opencode`,t,{signal:e.signal,env:{...process.env,OPENCODE_CONFIG_CONTENT:JSON.stringify(e.config??{})}});return{url:await new Promise((t,r)=>{let i=setTimeout(()=>{r(Error(`Timeout waiting for server to start after ${e.timeout}ms`))},e.timeout),a=``;n.stdout?.on(`data`,e=>{a+=e.toString();let n=a.split(` -`);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function fn(e){let t=await dn({...e});return{client:un({baseUrl:t.url}),server:t}}async function pn(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const mn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function hn(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function gn(e){let t=hn(e),n=mn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` -`)}function _n(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const vn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function yn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return vn.some(e=>e.test(t))}function bn(e,t){return _n(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function xn(e,t){return _n(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}async function Sn(e,t,i,a,o,s=n,c){let l=Date.now(),u=0;for(;!a.aborted;){if(await pn(500),a.aborted)return{completed:!1,error:`Aborted`};if(c?.sessionError==null)u=0;else{if(u++,u>=3)return o.error(`Session error persisted through grace period`,{sessionId:t,error:c.sessionError,graceCycles:u}),{completed:!1,error:`Session error: ${c.sessionError}`};continue}if(c?.sessionIdle===!0)return o.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let n=Date.now()-l;if(s>0&&n>=s)return o.warning(`Poll timeout reached`,{elapsedMs:n,maxPollTimeMs:s}),{completed:!1,error:`Poll timeout after ${n}ms`};try{let n=((await e.session.status({query:{directory:i}})).data??{})[t];if(n==null)o.debug(`Session status not found in poll response`,{sessionId:t});else if(n.type===`idle`)return o.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else o.debug(`Session status`,{sessionId:t,type:n.type});if(c!=null&&!c.firstMeaningfulEventReceived){let e=Date.now()-l;if(e>=9e4)return o.error(`No agent activity detected — server may have crashed during prompt processing`,{elapsedMs:e,sessionId:t}),{completed:!1,error:`No agent activity detected after ${e}ms — server may have crashed during prompt processing`}}}catch(e){o.debug(`Poll request failed`,{error:r(e)})}}return{completed:!1,error:`Aborted`}}async function Cn(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}function wn(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function Tn(e){try{let t=new URL(e);return t.hostname===`github.com`&&(t.pathname.startsWith(`/user-attachments/assets/`)||t.pathname.startsWith(`/user-attachments/files/`))}catch{return!1}}function En(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(wn)}function Dn(e){let t=/\[[\w-]+\s+([a-f0-9]{7,40})\]/g,n=[];for(let r of e.matchAll(t))r[1]!=null&&n.push(r[1]);return[...new Set(n)]}const On={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},kn=`\x1B[0m`;function An(){return N.env.NO_COLOR==null}function jn(e,t){let[n,r]=On[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);An()?N.stdout.write(`\n${r}|${kn} ${i} ${kn}${t}\n`):N.stdout.write(`\n| ${i} ${t}\n`)}function Mn(e){N.stdout.write(`\n${e}\n`)}function Nn(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function Pn(e,t,n,r,i){let a=En(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=Dn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function Fn(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(Nn(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(Mn(a),a=``)}else if(e.type===`tool`){let t=e.state;t.status===`completed`&&(jn(e.tool,t.title),e.tool.toLowerCase()===`bash`&&Pn(String(t.input.command??t.input.cmd??``),String(t.output),l,u,()=>{d++}))}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error,t=typeof e==`string`?e:String(e);r.error(`Session error`,{error:e}),f=yn(e)?bn(t,s??void 0):xn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(Mn(a),a=``))}return a.length>0&&Mn(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}const In=5e3;async function Ln(e,t,n,r,i){let a=new AbortController,o={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},s=await e.event.subscribe(),c={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},l=Fn(s.stream,t,a.signal,i,o).then(e=>{c=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&i.debug(`Event stream error`,{error:e.message})}),u=async()=>{a.abort(),await Cn(l)};try{let s=await Sn(e,t,n,a.signal,i,r,o);if(await u(),!s.completed){let e=s.error??`Session did not reach idle state`;return i.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:c.llmError,shouldRetry:c.llmError!=null,eventStreamResult:c}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:c}}finally{a.abort(),await Cn(l)}}const Rn=e=>{if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!(e!=null&&Object.values(e.omoProviders).some(e=>e!==`no`)))return{providerID:E.providerID,modelID:E.modelID}};async function zn(e,t,n,r,i,a,o){let s={parts:[{type:`text`,text:n},...r??[]]},c=Rn(a);c!=null&&(s.model=c);let l=a?.agent??`sisyphus`;l!==`sisyphus`&&(s.agent=l);let u=await e.session.promptAsync({path:{id:t},body:s,query:{directory:i}});if(u.error!=null){let e=String(u.error),t=yn(u.error)?bn(e):null;return{success:!1,error:e,llmError:t,shouldRetry:t!=null,eventStreamResult:{tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:t}}}return Ln(e,t,i,a?.timeoutMs??18e5,o)}function Bn(){return[`## Critical Rules (NON-NEGOTIABLE)`,`- You are a NON-INTERACTIVE CI agent. Do NOT ask questions. Make decisions autonomously.`,`- Post EXACTLY ONE comment or review per invocation. Never multiple.`,`- Include the Run Summary marker block in your comment.`,"- Use `gh` CLI for all GitHub operations. Do not use the GitHub API directly.",`- Mark your comment with the bot identification marker.`].join(` -`)}function Vn(e,t,n){if(e==null)return``;let r=[`## Thread Identity`];return r.push(`**Logical Thread**: \`${e.key}\` (${e.entityType} #${e.entityId})`),t?(r.push(`**Status**: Continuing previous conversation thread.`),n!=null&&n.length>0&&(r.push(``),r.push(`**Thread Summary**:`),r.push(n))):r.push(`**Status**: Fresh conversation — no prior thread found for this entity.`),r.join(` -`)}function Hn(e){return e==null||e.length===0?``:[`## Current Thread Context`,`This is work from your PREVIOUS runs on this same entity:`,``,e].join(` -`)}function Un(){return[`## Reminder: Critical Rules`,"- ONE comment/review only. Include Run Summary marker. Use `gh` CLI only."].join(` -`)}function Wn(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` -`),appendMode:!0};case`pull_request_review_comment`:return{directive:Gn(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function Gn(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` -`)}function Kn(e,t){let{directive:n,appendMode:r}=Wn(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` -`)}function qn(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a,logicalKey:o,isContinuation:s,currentThreadSessionId:c}=e,l=[],u=s===!0;l.push(Bn());let d=Vn(o??null,u,null);d.length>0&&l.push(d);let f=a!=null&&u&&c!=null?Xn(a.priorWorkContext,c):null;e.triggerContext==null?n.commentBody==null?l.push(`## Task +`);try{c=JSON.parse(e),l=!0}catch{c=e}}l&&(r&&await r(c),n&&(c=await n(c))),t?.({data:c,event:o,id:u,retry:s}),a.length&&(yield c)}}}finally{p.removeEventListener(`abort`,d),a.releaseLock()}break}catch(t){if(e?.(t),a!==void 0&&f>=a)break;await d(Math.min(s*2**(f-1),o??3e4))}}}()}},gt=async(e,t)=>{let n=typeof t==`function`?await t(e):t;if(n)return e.scheme===`bearer`?`Bearer ${n}`:e.scheme===`basic`?`Basic ${btoa(n)}`:n},_t={bodySerializer:e=>JSON.stringify(e,(e,t)=>typeof t==`bigint`?t.toString():t)},vt=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},yt=e=>{switch(e){case`form`:return`,`;case`pipeDelimited`:return`|`;case`spaceDelimited`:return`%20`;default:return`,`}},bt=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},xt=({allowReserved:e,explode:t,name:n,style:r,value:i})=>{if(!t){let t=(e?i:i.map(e=>encodeURIComponent(e))).join(yt(r));switch(r){case`label`:return`.${t}`;case`matrix`:return`;${n}=${t}`;case`simple`:return t;default:return`${n}=${t}`}}let a=vt(r),o=i.map(t=>r===`label`||r===`simple`?e?t:encodeURIComponent(t):St({allowReserved:e,name:n,value:t})).join(a);return r===`label`||r===`matrix`?a+o:o},St=({allowReserved:e,name:t,value:n})=>{if(n==null)return``;if(typeof n==`object`)throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${t}=${e?n:encodeURIComponent(n)}`},Ct=({allowReserved:e,explode:t,name:n,style:r,value:i,valueOnly:a})=>{if(i instanceof Date)return a?i.toISOString():`${n}=${i.toISOString()}`;if(r!==`deepObject`&&!t){let t=[];Object.entries(i).forEach(([n,r])=>{t=[...t,n,e?r:encodeURIComponent(r)]});let a=t.join(`,`);switch(r){case`form`:return`${n}=${a}`;case`label`:return`.${a}`;case`matrix`:return`;${n}=${a}`;default:return a}}let o=bt(r),s=Object.entries(i).map(([t,i])=>St({allowReserved:e,name:r===`deepObject`?`${n}[${t}]`:t,value:i})).join(o);return r===`label`||r===`matrix`?o+s:s},wt=/\{[^{}]+\}/g,Tt=({path:e,url:t})=>{let n=t,r=t.match(wt);if(r)for(let t of r){let r=!1,i=t.substring(1,t.length-1),a=`simple`;i.endsWith(`*`)&&(r=!0,i=i.substring(0,i.length-1)),i.startsWith(`.`)?(i=i.substring(1),a=`label`):i.startsWith(`;`)&&(i=i.substring(1),a=`matrix`);let o=e[i];if(o==null)continue;if(Array.isArray(o)){n=n.replace(t,xt({explode:r,name:i,style:a,value:o}));continue}if(typeof o==`object`){n=n.replace(t,Ct({explode:r,name:i,style:a,value:o,valueOnly:!0}));continue}if(a===`matrix`){n=n.replace(t,`;${St({name:i,value:o})}`);continue}let s=encodeURIComponent(a===`label`?`.${o}`:o);n=n.replace(t,s)}return n},Et=({baseUrl:e,path:t,query:n,querySerializer:r,url:i})=>{let a=i.startsWith(`/`)?i:`/${i}`,o=(e??``)+a;t&&(o=Tt({path:t,url:o}));let s=n?r(n):``;return s.startsWith(`?`)&&(s=s.substring(1)),s&&(o+=`?${s}`),o},Dt=({allowReserved:e,array:t,object:n}={})=>r=>{let i=[];if(r&&typeof r==`object`)for(let a in r){let o=r[a];if(o!=null)if(Array.isArray(o)){let n=xt({allowReserved:e,explode:!0,name:a,style:`form`,value:o,...t});n&&i.push(n)}else if(typeof o==`object`){let t=Ct({allowReserved:e,explode:!0,name:a,style:`deepObject`,value:o,...n});t&&i.push(t)}else{let t=St({allowReserved:e,name:a,value:o});t&&i.push(t)}}return i.join(`&`)},Ot=e=>{if(!e)return`stream`;let t=e.split(`;`)[0]?.trim();if(t){if(t.startsWith(`application/json`)||t.endsWith(`+json`))return`json`;if(t===`multipart/form-data`)return`formData`;if([`application/`,`audio/`,`image/`,`video/`].some(e=>t.startsWith(e)))return`blob`;if(t.startsWith(`text/`))return`text`}},kt=(e,t)=>t?!!(e.headers.has(t)||e.query?.[t]||e.headers.get(`Cookie`)?.includes(`${t}=`)):!1,At=async({security:e,...t})=>{for(let n of e){if(kt(t,n.name))continue;let e=await gt(n,t.auth);if(!e)continue;let r=n.name??`Authorization`;switch(n.in){case`query`:t.query||={},t.query[r]=e;break;case`cookie`:t.headers.append(`Cookie`,`${r}=${e}`);break;default:t.headers.set(r,e);break}}},jt=e=>Et({baseUrl:e.baseUrl,path:e.path,query:e.query,querySerializer:typeof e.querySerializer==`function`?e.querySerializer:Dt(e.querySerializer),url:e.url}),Mt=(e,t)=>{let n={...e,...t};return n.baseUrl?.endsWith(`/`)&&(n.baseUrl=n.baseUrl.substring(0,n.baseUrl.length-1)),n.headers=Nt(e.headers,t.headers),n},Nt=(...e)=>{let t=new Headers;for(let n of e){if(!n||typeof n!=`object`)continue;let e=n instanceof Headers?n.entries():Object.entries(n);for(let[n,r]of e)if(r===null)t.delete(n);else if(Array.isArray(r))for(let e of r)t.append(n,e);else r!==void 0&&t.set(n,typeof r==`object`?JSON.stringify(r):r)}return t};var Pt=class{_fns;constructor(){this._fns=[]}clear(){this._fns=[]}getInterceptorIndex(e){return typeof e==`number`?this._fns[e]?e:-1:this._fns.indexOf(e)}exists(e){let t=this.getInterceptorIndex(e);return!!this._fns[t]}eject(e){let t=this.getInterceptorIndex(e);this._fns[t]&&(this._fns[t]=null)}update(e,t){let n=this.getInterceptorIndex(e);return this._fns[n]?(this._fns[n]=t,e):!1}use(e){return this._fns=[...this._fns,e],this._fns.length-1}};const Ft=()=>({error:new Pt,request:new Pt,response:new Pt}),It=Dt({allowReserved:!1,array:{explode:!0,style:`form`},object:{explode:!0,style:`deepObject`}}),Lt={"Content-Type":`application/json`},Rt=(e={})=>({..._t,headers:Lt,parseAs:`auto`,querySerializer:It,...e}),zt=(e={})=>{let t=Mt(Rt(),e),n=()=>({...t}),r=e=>(t=Mt(t,e),n()),i=Ft(),a=async e=>{let n={...t,...e,fetch:e.fetch??t.fetch??globalThis.fetch,headers:Nt(t.headers,e.headers),serializedBody:void 0};return n.security&&await At({...n,security:n.security}),n.requestValidator&&await n.requestValidator(n),n.body&&n.bodySerializer&&(n.serializedBody=n.bodySerializer(n.body)),(n.serializedBody===void 0||n.serializedBody===``)&&n.headers.delete(`Content-Type`),{opts:n,url:jt(n)}},o=async e=>{let{opts:t,url:n}=await a(e),r={redirect:`follow`,...t,body:t.serializedBody},o=new Request(n,r);for(let e of i.request._fns)e&&(o=await e(o,t));let s=t.fetch,c=await s(o);for(let e of i.response._fns)e&&(c=await e(c,o,t));let l={request:o,response:c};if(c.ok){if(c.status===204||c.headers.get(`Content-Length`)===`0`)return t.responseStyle===`data`?{}:{data:{},...l};let e=(t.parseAs===`auto`?Ot(c.headers.get(`Content-Type`)):t.parseAs)??`json`,n;switch(e){case`arrayBuffer`:case`blob`:case`formData`:case`json`:case`text`:n=await c[e]();break;case`stream`:return t.responseStyle===`data`?c.body:{data:c.body,...l}}return e===`json`&&(t.responseValidator&&await t.responseValidator(n),t.responseTransformer&&(n=await t.responseTransformer(n))),t.responseStyle===`data`?n:{data:n,...l}}let u=await c.text(),d;try{d=JSON.parse(u)}catch{}let f=d??u,p=f;for(let e of i.error._fns)e&&(p=await e(f,c,o,t));if(p||={},t.throwOnError)throw p;return t.responseStyle===`data`?void 0:{error:p,...l}},s=e=>{let t=t=>o({...t,method:e});return t.sse=async t=>{let{opts:n,url:r}=await a(t);return ht({...n,body:n.body,headers:n.headers,method:e,url:r})},t};return{buildUrl:jt,connect:s(`CONNECT`),delete:s(`DELETE`),get:s(`GET`),getConfig:n,head:s(`HEAD`),interceptors:i,options:s(`OPTIONS`),patch:s(`PATCH`),post:s(`POST`),put:s(`PUT`),request:o,setConfig:r,trace:s(`TRACE`)}};Object.entries({$body_:`body`,$headers_:`headers`,$path_:`path`,$query_:`query`});const Bt=zt(Rt({baseUrl:`http://localhost:4096`}));var B=class{_client=Bt;constructor(e){e?.client&&(this._client=e.client)}},Vt=class extends B{event(e){return(e?.client??this._client).get.sse({url:`/global/event`,...e})}},Ht=class extends B{list(e){return(e?.client??this._client).get({url:`/project`,...e})}current(e){return(e?.client??this._client).get({url:`/project/current`,...e})}},Ut=class extends B{list(e){return(e?.client??this._client).get({url:`/pty`,...e})}create(e){return(e?.client??this._client).post({url:`/pty`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}remove(e){return(e.client??this._client).delete({url:`/pty/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/pty/{id}`,...e})}update(e){return(e.client??this._client).put({url:`/pty/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}connect(e){return(e.client??this._client).get({url:`/pty/{id}/connect`,...e})}},Wt=class extends B{get(e){return(e?.client??this._client).get({url:`/config`,...e})}update(e){return(e?.client??this._client).patch({url:`/config`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}providers(e){return(e?.client??this._client).get({url:`/config/providers`,...e})}},Gt=class extends B{ids(e){return(e?.client??this._client).get({url:`/experimental/tool/ids`,...e})}list(e){return(e.client??this._client).get({url:`/experimental/tool`,...e})}},Kt=class extends B{dispose(e){return(e?.client??this._client).post({url:`/instance/dispose`,...e})}},qt=class extends B{get(e){return(e?.client??this._client).get({url:`/path`,...e})}},Jt=class extends B{get(e){return(e?.client??this._client).get({url:`/vcs`,...e})}},Yt=class extends B{list(e){return(e?.client??this._client).get({url:`/session`,...e})}create(e){return(e?.client??this._client).post({url:`/session`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}status(e){return(e?.client??this._client).get({url:`/session/status`,...e})}delete(e){return(e.client??this._client).delete({url:`/session/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/session/{id}`,...e})}update(e){return(e.client??this._client).patch({url:`/session/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}children(e){return(e.client??this._client).get({url:`/session/{id}/children`,...e})}todo(e){return(e.client??this._client).get({url:`/session/{id}/todo`,...e})}init(e){return(e.client??this._client).post({url:`/session/{id}/init`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}fork(e){return(e.client??this._client).post({url:`/session/{id}/fork`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}abort(e){return(e.client??this._client).post({url:`/session/{id}/abort`,...e})}unshare(e){return(e.client??this._client).delete({url:`/session/{id}/share`,...e})}share(e){return(e.client??this._client).post({url:`/session/{id}/share`,...e})}diff(e){return(e.client??this._client).get({url:`/session/{id}/diff`,...e})}summarize(e){return(e.client??this._client).post({url:`/session/{id}/summarize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}messages(e){return(e.client??this._client).get({url:`/session/{id}/message`,...e})}prompt(e){return(e.client??this._client).post({url:`/session/{id}/message`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}message(e){return(e.client??this._client).get({url:`/session/{id}/message/{messageID}`,...e})}promptAsync(e){return(e.client??this._client).post({url:`/session/{id}/prompt_async`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}command(e){return(e.client??this._client).post({url:`/session/{id}/command`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}shell(e){return(e.client??this._client).post({url:`/session/{id}/shell`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}revert(e){return(e.client??this._client).post({url:`/session/{id}/revert`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}unrevert(e){return(e.client??this._client).post({url:`/session/{id}/unrevert`,...e})}},Xt=class extends B{list(e){return(e?.client??this._client).get({url:`/command`,...e})}},Zt=class extends B{authorize(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/authorize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}callback(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Qt=class extends B{list(e){return(e?.client??this._client).get({url:`/provider`,...e})}auth(e){return(e?.client??this._client).get({url:`/provider/auth`,...e})}oauth=new Zt({client:this._client})},$t=class extends B{text(e){return(e.client??this._client).get({url:`/find`,...e})}files(e){return(e.client??this._client).get({url:`/find/file`,...e})}symbols(e){return(e.client??this._client).get({url:`/find/symbol`,...e})}},en=class extends B{list(e){return(e.client??this._client).get({url:`/file`,...e})}read(e){return(e.client??this._client).get({url:`/file/content`,...e})}status(e){return(e?.client??this._client).get({url:`/file/status`,...e})}},tn=class extends B{log(e){return(e?.client??this._client).post({url:`/log`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}agents(e){return(e?.client??this._client).get({url:`/agent`,...e})}},nn=class extends B{remove(e){return(e.client??this._client).delete({url:`/mcp/{name}/auth`,...e})}start(e){return(e.client??this._client).post({url:`/mcp/{name}/auth`,...e})}callback(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}authenticate(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/authenticate`,...e})}set(e){return(e.client??this._client).put({url:`/auth/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},rn=class extends B{status(e){return(e?.client??this._client).get({url:`/mcp`,...e})}add(e){return(e?.client??this._client).post({url:`/mcp`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}connect(e){return(e.client??this._client).post({url:`/mcp/{name}/connect`,...e})}disconnect(e){return(e.client??this._client).post({url:`/mcp/{name}/disconnect`,...e})}auth=new nn({client:this._client})},an=class extends B{status(e){return(e?.client??this._client).get({url:`/lsp`,...e})}},on=class extends B{status(e){return(e?.client??this._client).get({url:`/formatter`,...e})}},sn=class extends B{next(e){return(e?.client??this._client).get({url:`/tui/control/next`,...e})}response(e){return(e?.client??this._client).post({url:`/tui/control/response`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}},cn=class extends B{appendPrompt(e){return(e?.client??this._client).post({url:`/tui/append-prompt`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}openHelp(e){return(e?.client??this._client).post({url:`/tui/open-help`,...e})}openSessions(e){return(e?.client??this._client).post({url:`/tui/open-sessions`,...e})}openThemes(e){return(e?.client??this._client).post({url:`/tui/open-themes`,...e})}openModels(e){return(e?.client??this._client).post({url:`/tui/open-models`,...e})}submitPrompt(e){return(e?.client??this._client).post({url:`/tui/submit-prompt`,...e})}clearPrompt(e){return(e?.client??this._client).post({url:`/tui/clear-prompt`,...e})}executeCommand(e){return(e?.client??this._client).post({url:`/tui/execute-command`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}showToast(e){return(e?.client??this._client).post({url:`/tui/show-toast`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}publish(e){return(e?.client??this._client).post({url:`/tui/publish`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}control=new sn({client:this._client})},ln=class extends B{subscribe(e){return(e?.client??this._client).get.sse({url:`/event`,...e})}},un=class extends B{postSessionIdPermissionsPermissionId(e){return(e.client??this._client).post({url:`/session/{id}/permissions/{permissionID}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}global=new Vt({client:this._client});project=new Ht({client:this._client});pty=new Ut({client:this._client});config=new Wt({client:this._client});tool=new Gt({client:this._client});instance=new Kt({client:this._client});path=new qt({client:this._client});vcs=new Jt({client:this._client});session=new Yt({client:this._client});command=new Xt({client:this._client});provider=new Qt({client:this._client});find=new $t({client:this._client});file=new en({client:this._client});app=new tn({client:this._client});mcp=new rn({client:this._client});lsp=new an({client:this._client});formatter=new on({client:this._client});tui=new cn({client:this._client});auth=new nn({client:this._client});event=new ln({client:this._client})};function dn(e){if(!e?.fetch){let t=e=>(e.timeout=!1,fetch(e));e={...e,fetch:t}}return e?.directory&&(e.headers={...e.headers,"x-opencode-directory":encodeURIComponent(e.directory)}),new un({client:zt(e)})}async function fn(e){e=Object.assign({hostname:`127.0.0.1`,port:4096,timeout:5e3},e??{});let t=[`serve`,`--hostname=${e.hostname}`,`--port=${e.port}`];e.config?.logLevel&&t.push(`--log-level=${e.config.logLevel}`);let n=je(`opencode`,t,{signal:e.signal,env:{...process.env,OPENCODE_CONFIG_CONTENT:JSON.stringify(e.config??{})}});return{url:await new Promise((t,r)=>{let i=setTimeout(()=>{r(Error(`Timeout waiting for server to start after ${e.timeout}ms`))},e.timeout),a=``;n.stdout?.on(`data`,e=>{a+=e.toString();let n=a.split(` +`);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function pn(e){let t=await fn({...e});return{client:dn({baseUrl:t.url}),server:t}}async function mn(e,t,n,r){if(n!=null)try{let i=await e.session.update({path:{id:t},body:{title:n}});i.error!=null&&r.warning(`Best-effort session title re-assertion failed`,{sessionId:t,sessionTitle:n,error:String(i.error)})}catch{r.warning(`Best-effort session title re-assertion failed`,{sessionId:t,sessionTitle:n})}}async function hn(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const gn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function _n(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function vn(e){let t=_n(e),n=gn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` +`)}function yn(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const bn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function xn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return bn.some(e=>e.test(t))}function Sn(e,t){return yn(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function Cn(e,t){return yn(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}async function wn(e,t,i,a,o,s=n,c){let l=Date.now(),u=0;for(;!a.aborted;){if(await hn(500),a.aborted)return{completed:!1,error:`Aborted`};if(c?.sessionError==null)u=0;else{if(u++,u>=3)return o.error(`Session error persisted through grace period`,{sessionId:t,error:c.sessionError,graceCycles:u}),{completed:!1,error:`Session error: ${c.sessionError}`};continue}if(c?.sessionIdle===!0)return o.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let n=Date.now()-l;if(s>0&&n>=s)return o.warning(`Poll timeout reached`,{elapsedMs:n,maxPollTimeMs:s}),{completed:!1,error:`Poll timeout after ${n}ms`};try{let n=((await e.session.status({query:{directory:i}})).data??{})[t];if(n==null)o.debug(`Session status not found in poll response`,{sessionId:t});else if(n.type===`idle`)return o.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else o.debug(`Session status`,{sessionId:t,type:n.type});if(c!=null&&!c.firstMeaningfulEventReceived){let e=Date.now()-l;if(e>=9e4)return o.error(`No agent activity detected — server may have crashed during prompt processing`,{elapsedMs:e,sessionId:t}),{completed:!1,error:`No agent activity detected after ${e}ms — server may have crashed during prompt processing`}}}catch(e){o.debug(`Poll request failed`,{error:r(e)})}}return{completed:!1,error:`Aborted`}}async function Tn(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}function En(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function Dn(e){try{let t=new URL(e);return t.hostname===`github.com`&&(t.pathname.startsWith(`/user-attachments/assets/`)||t.pathname.startsWith(`/user-attachments/files/`))}catch{return!1}}function On(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(En)}function kn(e){let t=/\[[\w-]+\s+([a-f0-9]{7,40})\]/g,n=[];for(let r of e.matchAll(t))r[1]!=null&&n.push(r[1]);return[...new Set(n)]}const An={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},jn=`\x1B[0m`;function Mn(){return N.env.NO_COLOR==null}function Nn(e,t){let[n,r]=An[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);Mn()?N.stdout.write(`\n${r}|${jn} ${i} ${jn}${t}\n`):N.stdout.write(`\n| ${i} ${t}\n`)}function Pn(e){N.stdout.write(`\n${e}\n`)}function Fn(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function In(e,t,n,r,i){let a=On(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=kn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function Ln(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(Fn(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(Pn(a),a=``)}else if(e.type===`tool`){let t=e.state;t.status===`completed`&&(Nn(e.tool,t.title),e.tool.toLowerCase()===`bash`&&In(String(t.input.command??t.input.cmd??``),String(t.output),l,u,()=>{d++}))}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error,t=typeof e==`string`?e:String(e);r.error(`Session error`,{error:e}),f=xn(e)?Sn(t,s??void 0):Cn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(Pn(a),a=``))}return a.length>0&&Pn(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}const Rn=5e3;async function zn(e,t,n,r,i){let a=new AbortController,o={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},s=await e.event.subscribe(),c={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},l=Ln(s.stream,t,a.signal,i,o).then(e=>{c=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&i.debug(`Event stream error`,{error:e.message})}),u=async()=>{a.abort(),await Tn(l)};try{let s=await wn(e,t,n,a.signal,i,r,o);if(await u(),!s.completed){let e=s.error??`Session did not reach idle state`;return i.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:c.llmError,shouldRetry:c.llmError!=null,eventStreamResult:c}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:c}}finally{a.abort(),await Tn(l)}}const Bn=e=>{if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!(e!=null&&Object.values(e.omoProviders).some(e=>e!==`no`)))return{providerID:E.providerID,modelID:E.modelID}};async function Vn(e,t,n,r,i,a,o){let s={parts:[{type:`text`,text:n},...r??[]]},c=Bn(a);c!=null&&(s.model=c);let l=a?.agent??`sisyphus`;l!==`sisyphus`&&(s.agent=l);let u=await e.session.promptAsync({path:{id:t},body:s,query:{directory:i}});if(u.error!=null){let e=String(u.error),t=xn(u.error)?Sn(e):null;return{success:!1,error:e,llmError:t,shouldRetry:t!=null,eventStreamResult:{tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:t}}}return zn(e,t,i,a?.timeoutMs??18e5,o)}function Hn(){return[`## Critical Rules (NON-NEGOTIABLE)`,`- You are a NON-INTERACTIVE CI agent. Do NOT ask questions. Make decisions autonomously.`,`- Post EXACTLY ONE comment or review per invocation. Never multiple.`,`- Include the Run Summary marker block in your comment.`,"- Use `gh` CLI for all GitHub operations. Do not use the GitHub API directly.",`- Mark your comment with the bot identification marker.`].join(` +`)}function Un(e,t,n){if(e==null)return``;let r=[`## Thread Identity`];return r.push(`**Logical Thread**: \`${e.key}\` (${e.entityType} #${e.entityId})`),t?(r.push(`**Status**: Continuing previous conversation thread.`),n!=null&&n.length>0&&(r.push(``),r.push(`**Thread Summary**:`),r.push(n))):r.push(`**Status**: Fresh conversation — no prior thread found for this entity.`),r.join(` +`)}function Wn(e){return e==null||e.length===0?``:[`## Current Thread Context`,`This is work from your PREVIOUS runs on this same entity:`,``,e].join(` +`)}function Gn(){return[`## Reminder: Critical Rules`,"- ONE comment/review only. Include Run Summary marker. Use `gh` CLI only."].join(` +`)}function Kn(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` +`),appendMode:!0};case`pull_request_review_comment`:return{directive:qn(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function qn(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` +`)}function Jn(e,t){let{directive:n,appendMode:r}=Kn(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` +`)}function Yn(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a,logicalKey:o,isContinuation:s,currentThreadSessionId:c}=e,l=[],u=s===!0;l.push(Hn());let d=Un(o??null,u,null);d.length>0&&l.push(d);let f=a!=null&&u&&c!=null?Qn(a.priorWorkContext,c):null;e.triggerContext==null?n.commentBody==null?l.push(`## Task Execute the requested operation for repository ${n.repo}. Follow all instructions and requirements listed in this prompt. `):l.push(`## Task Respond to the trigger comment above. Follow all instructions and requirements listed in this prompt. -`):l.push(Kn(e.triggerContext,r)),n.commentBody!=null&&l.push(`## Trigger Comment +`):l.push(Jn(e.triggerContext,r));let p=r?.trim()??null,m=n.commentBody?.trim()??null,h=p!=null&&p.length>0&&m!=null&&m.length>0&&p===m;n.commentBody!=null&&!h&&l.push(`## Trigger Comment **Author:** ${n.commentAuthor??`unknown`} \`\`\` ${n.commentBody} \`\`\` -`);let p=Hn(f);if(p.length>0&&l.push(p),r!=null&&r.trim().length>0&&e.triggerContext==null&&l.push(` +`);let g=Wn(f);if(g.length>0&&l.push(g),r!=null&&r.trim().length>0&&e.triggerContext==null&&l.push(` ${r.trim()} -`),e.triggerContext!=null){let t=e.triggerContext.eventType;(t===`pull_request`||t===`pull_request_review_comment`)&&l.push($n(n))}if(l.push(` +`),e.triggerContext!=null){let t=e.triggerContext.eventType;(t===`pull_request`||t===`pull_request_review_comment`)&&l.push(tr(n))}if(l.push(` ## Environment - **Repository:** ${n.repo} - **Branch/Ref:** ${n.ref} @@ -159,7 +159,7 @@ ${r.trim()} - **Number:** #${n.issueNumber} - **Title:** ${n.issueTitle??`N/A`} - **Type:** ${n.issueType??`unknown`} -`)}if(n.diffContext!=null&&l.push(Qn(n.diffContext)),n.hydratedContext!=null&&l.push(it(n.hydratedContext)),a!=null){let e=Zn(a,u,c,f!=null);e!=null&&l.push(e)}l.push(`# Agent Context +`)}if(n.diffContext!=null&&l.push(er(n.diffContext)),n.hydratedContext!=null&&l.push(it(n.hydratedContext)),a!=null){let e=$n(a,u,c,f!=null);e!=null&&l.push(e)}l.push(`# Agent Context You are the Fro Bot Agent running in a non-interactive CI environment (GitHub Actions). @@ -180,23 +180,23 @@ Before completing: 1. Ensure your session contains a summary of work done 2. Include key decisions, findings, and outcomes 3. This summary will be searchable in future agent runs -`),n.issueNumber!=null&&l.push(Jn(n,i,e.sessionId));let m=n.issueNumber??``,h=n.issueNumber!=null;l.push(`## GitHub Operations (Use gh CLI) +`),n.issueNumber!=null&&l.push(Xn(n,i,e.sessionId));let _=n.issueNumber??``,v=n.issueNumber!=null;l.push(`## GitHub Operations (Use gh CLI) The \`gh\` CLI is pre-authenticated. Use it for all GitHub operations. -${h?` +${v?` ### Posting Your Response See **Response Protocol** above. Post exactly one comment or review per run. \`\`\`bash # Post response as PR comment (use --body-file for long responses) -gh pr comment ${m} --body "Your response with Run Summary" +gh pr comment ${_} --body "Your response with Run Summary" # Submit PR review with response in body -gh pr review ${m} --approve --body "Your review with Run Summary" +gh pr review ${_} --approve --body "Your review with Run Summary" # Post response as issue comment -gh issue comment ${m} --body "Your response with Run Summary" +gh issue comment ${_} --body "Your response with Run Summary" \`\`\``:``} ### Creating PRs @@ -214,10 +214,10 @@ git push origin HEAD ### API Calls \`\`\`bash gh api repos/${n.repo}/issues --jq '.[].title' -gh api repos/${n.repo}/pulls/${m}/files --jq '.[].filename' +gh api repos/${n.repo}/pulls/${_}/files --jq '.[].filename' \`\`\` -`),l.push(Un());let g=l.join(` -`);return t.debug(`Built agent prompt`,{length:g.length,hasCustom:r!=null,hasSessionContext:a!=null}),g}function Jn(e,t,n){let r=e.issueNumber??``;return`## Response Protocol (REQUIRED) +`),l.push(Gn());let y=l.join(` +`);return t.debug(`Built agent prompt`,{length:y.length,hasCustom:r!=null,hasSessionContext:a!=null}),y}function Xn(e,t,n){let r=e.issueNumber??``;return`## Response Protocol (REQUIRED) You MUST post exactly ONE comment or review per invocation. All of your output — your response content AND the Run Summary — goes into that single artifact. @@ -253,17 +253,17 @@ Every response you post — regardless of channel (issue, PR, discussion, review \`\`\` -`}function Yn(e,t,n){let r=[t];if(e.recentSessions.length>0){r.push(``),r.push(`### Recent Sessions`),r.push(`| ID | Title | Updated | Messages | Agents |`),r.push(`|----|-------|---------|----------|--------|`);for(let t of e.recentSessions.slice(0,5)){let e=new Date(t.updatedAt).toISOString().split(`T`)[0],n=t.agents.join(`, `)||`N/A`,i=t.title||`Untitled`;r.push(`| ${t.id} | ${i} | ${e} | ${t.messageCount} | ${n} |`)}r.push(``),r.push("Use `session_read` to review any of these sessions in detail.")}if(n.length>0){r.push(``),r.push(`### Relevant Prior Work`),r.push(``),r.push(`The following sessions contain content related to this issue:`),r.push(``);for(let e of n.slice(0,3)){r.push(`**Session ${e.sessionId}:**`),r.push("```markdown");for(let t of e.matches.slice(0,2))r.push(`- ${t.excerpt}`);r.push("```"),r.push(``)}r.push("Use `session_read` to review full context before starting new investigation.")}return r.push(``),r.join(` -`)}function Xn(e,t){let n=e.filter(e=>e.sessionId===t);if(n.length===0)return null;let r=[];for(let e of n.slice(0,1)){r.push(`**Session ${e.sessionId}:**`),r.push("```markdown");for(let t of e.matches.slice(0,3))r.push(`- ${t.excerpt}`);r.push("```")}return r.join(` -`)}function Zn(e,t,n,r){if(t&&n!=null){let t=e.priorWorkContext.filter(e=>e.sessionId!==n);return e.recentSessions.length===0&&t.length===0?null:Yn(e,`## Related Historical Context`,t)}return e.recentSessions.length===0&&e.priorWorkContext.length===0&&r?null:Yn(e,`## Prior Session Context`,e.priorWorkContext)}function Qn(e){let t=[`## Pull Request Diff Summary`];if(t.push(``),t.push(`- **Changed Files:** ${e.changedFiles}`),t.push(`- **Additions:** +${e.additions}`),t.push(`- **Deletions:** -${e.deletions}`),e.truncated&&t.push(`- **Note:** Diff was truncated due to size limits`),e.files.length>0){t.push(``),t.push(`### Changed Files`),t.push(`| File | Status | +/- |`),t.push(`|------|--------|-----|`);for(let n of e.files.slice(0,20))t.push(`| \`${n.filename}\` | ${n.status} | +${n.additions}/-${n.deletions} |`);e.files.length>20&&t.push(`| ... | | +${e.files.length-20} more files |`)}return t.push(``),t.join(` -`)}function $n(e){let t=[`## Output Contract`,``];return t.push(`- Review action: approve/request-changes if confident; otherwise comment-only`),t.push(`- Requested reviewer: ${e.isRequestedReviewer?`yes`:`no`}`),e.authorAssociation!=null&&t.push(`- Author association: ${e.authorAssociation}`),t.push(``),t.join(` -`)}async function er(e,t,n,i){let a=Date.now(),o=new AbortController,s=n?.timeoutMs??18e5,c=null,l=!1,u=i==null,d=null;s>0&&(c=setTimeout(()=>{l=!0,t.warning(`Execution timeout reached`,{timeoutMs:s}),o.abort()},s)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??`sisyphus`,hasModelOverride:n?.model!=null,timeoutMs:s});try{let r;if(i==null){let e=await fn({signal:o.signal});r=e.client,d=e.server}else r=i.client;let c;if(n?.continueSessionId==null){let e=n?.sessionTitle==null?void 0:{body:{title:n.sessionTitle}},i=e==null?await r.session.create():await r.session.create(e);if(i.data==null||i.error!=null)throw Error(`Failed to create session: ${i.error==null?`No data returned`:String(i.error)}`);c=i.data.id,t.info(`Created new OpenCode session`,{sessionId:c,sessionTitle:n?.sessionTitle??null})}else c=n.continueSessionId,t.info(`Continuing existing OpenCode session`,{sessionId:c});let u=qn({...e,sessionId:c},t),f=re();if(te()){let e=O(),n=Te.createHash(`sha256`).update(u).digest(`hex`),r=L.join(e,`prompt-${c}-${n.slice(0,8)}.txt`);try{await I.mkdir(e,{recursive:!0}),await I.writeFile(r,u,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let p={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},m=null,h=null;for(let i=1;i<=3;i++){if(l)return{success:!1,exitCode:130,duration:Date.now()-a,sessionId:c,error:`Execution timed out after ${s}ms`,tokenUsage:p.tokens,model:p.model,cost:p.cost,prsCreated:p.prsCreated,commitsCreated:p.commitsCreated,commentsPosted:p.commentsPosted,llmError:h};if(s>0&&s-(Date.now()-a)<=5e3&&i>1)break;let o=i===1?u:`The previous request was interrupted by a network error (fetch failed). +`}function Zn(e,t,n){let r=[t];if(e.recentSessions.length>0){r.push(``),r.push(`### Recent Sessions`),r.push(`| ID | Title | Updated | Messages | Agents |`),r.push(`|----|-------|---------|----------|--------|`);for(let t of e.recentSessions.slice(0,5)){let e=new Date(t.updatedAt).toISOString().split(`T`)[0],n=t.agents.join(`, `)||`N/A`,i=t.title||`Untitled`;r.push(`| ${t.id} | ${i} | ${e} | ${t.messageCount} | ${n} |`)}r.push(``),r.push("Use `session_read` to review any of these sessions in detail.")}if(n.length>0){r.push(``),r.push(`### Relevant Prior Work`),r.push(``),r.push(`The following sessions contain content related to this issue:`),r.push(``);for(let e of n.slice(0,3)){r.push(`**Session ${e.sessionId}:**`),r.push("```markdown");for(let t of e.matches.slice(0,2))r.push(`- ${t.excerpt}`);r.push("```"),r.push(``)}r.push("Use `session_read` to review full context before starting new investigation.")}return r.push(``),r.join(` +`)}function Qn(e,t){let n=e.filter(e=>e.sessionId===t);if(n.length===0)return null;let r=[];for(let e of n.slice(0,1)){r.push(`**Session ${e.sessionId}:**`),r.push("```markdown");for(let t of e.matches.slice(0,3))r.push(`- ${t.excerpt}`);r.push("```")}return r.join(` +`)}function $n(e,t,n,r){if(t&&n!=null){let t=e.priorWorkContext.filter(e=>e.sessionId!==n);return e.recentSessions.length===0&&t.length===0?null:Zn(e,`## Related Historical Context`,t)}return e.recentSessions.length===0&&e.priorWorkContext.length===0&&r?null:Zn(e,`## Prior Session Context`,e.priorWorkContext)}function er(e){let t=[`## Pull Request Diff Summary`];if(t.push(``),t.push(`- **Changed Files:** ${e.changedFiles}`),t.push(`- **Additions:** +${e.additions}`),t.push(`- **Deletions:** -${e.deletions}`),e.truncated&&t.push(`- **Note:** Diff was truncated due to size limits`),e.files.length>0){t.push(``),t.push(`### Changed Files`),t.push(`| File | Status | +/- |`),t.push(`|------|--------|-----|`);for(let n of e.files.slice(0,20))t.push(`| \`${n.filename}\` | ${n.status} | +${n.additions}/-${n.deletions} |`);e.files.length>20&&t.push(`| ... | | +${e.files.length-20} more files |`)}return t.push(``),t.join(` +`)}function tr(e){let t=[`## Output Contract`,``];return t.push(`- Review action: approve/request-changes if confident; otherwise comment-only`),t.push(`- Requested reviewer: ${e.isRequestedReviewer?`yes`:`no`}`),e.authorAssociation!=null&&t.push(`- Author association: ${e.authorAssociation}`),t.push(``),t.join(` +`)}async function nr(e,t,n,i){let a=Date.now(),o=new AbortController,s=n?.timeoutMs??18e5,c=null,l=!1,u=i==null,d=null;s>0&&(c=setTimeout(()=>{l=!0,t.warning(`Execution timeout reached`,{timeoutMs:s}),o.abort()},s)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??`sisyphus`,hasModelOverride:n?.model!=null,timeoutMs:s});try{let r;if(i==null){let e=await pn({signal:o.signal});r=e.client,d=e.server}else r=i.client;let c;if(n?.continueSessionId==null){let e=n?.sessionTitle==null?void 0:{body:{title:n.sessionTitle}},i=e==null?await r.session.create():await r.session.create(e);if(i.data==null||i.error!=null)throw Error(`Failed to create session: ${i.error==null?`No data returned`:String(i.error)}`);c=i.data.id,t.info(`Created new OpenCode session`,{sessionId:c,sessionTitle:n?.sessionTitle??null})}else c=n.continueSessionId,t.info(`Continuing existing OpenCode session`,{sessionId:c});let u=Yn({...e,sessionId:c},t),f=re();if(te()){let e=O(),n=Te.createHash(`sha256`).update(u).digest(`hex`),r=L.join(e,`prompt-${c}-${n.slice(0,8)}.txt`);try{await I.mkdir(e,{recursive:!0}),await I.writeFile(r,u,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let p={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},m=null,h=null;for(let i=1;i<=3;i++){if(l)return{success:!1,exitCode:130,duration:Date.now()-a,sessionId:c,error:`Execution timed out after ${s}ms`,tokenUsage:p.tokens,model:p.model,cost:p.cost,prsCreated:p.prsCreated,commitsCreated:p.commitsCreated,commentsPosted:p.commentsPosted,llmError:h};if(s>0&&s-(Date.now()-a)<=5e3&&i>1)break;let o=i===1?u:`The previous request was interrupted by a network error (fetch failed). Please continue where you left off. If you were in the middle of a task, resume it. -If you had completed the task, confirm the completion.`,d=i===1?e.fileParts:void 0,g=await zn(r,c,o,d,f,n,t);if(g.success){if(p=g.eventStreamResult,n?.sessionTitle!=null)try{await r.session.update({sessionID:c,title:n.sessionTitle})}catch{t.debug(`Best-effort session title re-assertion failed`,{sessionId:c})}return{success:!0,exitCode:0,duration:Date.now()-a,sessionId:c,error:null,tokenUsage:p.tokens,model:p.model,cost:p.cost,prsCreated:p.prsCreated,commitsCreated:p.commitsCreated,commentsPosted:p.commentsPosted,llmError:null}}if(m=g.error,h=g.llmError,!g.shouldRetry||i>=3)break;t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:i,maxAttempts:3,error:g.error,delayMs:In,sessionId:c}),await pn(In)}return{success:!1,exitCode:1,duration:Date.now()-a,sessionId:c,error:m??`Unknown error`,tokenUsage:p.tokens,model:p.model,cost:p.cost,prsCreated:p.prsCreated,commitsCreated:p.commitsCreated,commentsPosted:p.commentsPosted,llmError:h}}catch(e){let n=Date.now()-a,i=r(e);return t.error(`OpenCode execution failed`,{error:i,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:i,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:yn(e)?bn(i):null}}finally{c!=null&&clearTimeout(c),o.abort(),u&&d?.close()}}async function tr(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await Ve(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function nr(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await We(e,t.repo,`agent: working`,`fcf2e1`,`Agent is currently working on this`,n)&&await Ge(e,t.repo,t.issueNumber,[`agent: working`],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function rr(e,t,n){await Promise.all([tr(e,t,n),nr(e,t,n)])}async function ir(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await He(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Ue(e,t.repo,t.commentId,r.id,n)}async function ar(e,t,n,r){t.commentId!=null&&await Ve(e,t.repo,t.commentId,n,r)}async function or(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await ir(e,t,n),await ar(e,t,`hooray`,n),n.info(`Updated reaction to success indicator`,{commentId:t.commentId,reaction:`hooray`})}catch(e){n.warning(`Failed to update reaction (non-fatal)`,{error:r(e)})}}async function sr(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await ir(e,t,n),await ar(e,t,`confused`,n),n.info(`Updated reaction to confused`,{commentId:t.commentId})}catch(e){n.warning(`Failed to update failure reaction (non-fatal)`,{error:r(e)})}}async function cr(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Ke(e,t.repo,t.issueNumber,`agent: working`,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function lr(e,t,n,r){n?await or(e,t,r):await sr(e,t,r),await cr(e,t,r)}var ur=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(be(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(xe(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${ve}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},dr=S((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),fr=C(S((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[f.Accept]=this._getExistingOrDefaultHeader(t,f.Accept,p.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[f.Accept]=this._getExistingOrDefaultHeader(n,f.Accept,p.ApplicationJson),n[f.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,p.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[f.Accept]=this._getExistingOrDefaultHeader(n,f.Accept,p.ApplicationJson),n[f.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,p.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[f.Accept]=this._getExistingOrDefaultHeader(n,f.Accept,p.ApplicationJson),n[f.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,p.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===d.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&h.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!g.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},S(this.requestOptions.headers),S(e||{})):S(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=S(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=S(this.requestOptions.headers)[f.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[f.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new u.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===d.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let S=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),pr=ce(),mr=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function hr(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function gr(e){return new fr.HttpClient().getAgent(e)}function _r(e){return new fr.HttpClient().getAgentDispatcher(e)}function vr(e){let t=_r(e);return(e,n)=>mr(this,void 0,void 0,function*(){return(0,pr.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function yr(){return process.env.GITHUB_API_URL||`https://api.github.com`}function br(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function xr(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>xr.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function Sr(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function Cr(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const wr=Function.bind,Tr=wr.bind(wr);function Er(e,t,n){let r=Tr(Cr,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=Tr(Sr,null).apply(null,i)})}function Dr(){let e=Symbol(`Singular`),t={registry:{}},n=xr.bind(null,t,e);return Er(n,t,e),n}function Or(){let e={registry:{}},t=xr.bind(null,e);return Er(t,e),t}var kr={Singular:Dr,Collection:Or},Ar=`octokit-endpoint.js/0.0.0-development ${br()}`,jr={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":Ar},mediaType:{format:``}};function Mr(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Nr(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Pr(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Nr(t[r])&&r in e?n[r]=Pr(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Fr(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function Ir(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Mr(n.headers),Fr(n),Fr(n.headers);let r=Pr(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function Lr(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var Rr=/\{[^{}}]+\}/g;function zr(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Vr(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function Hr(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function H(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function U(e,t,n){return t=e===`+`||e===`#`?Hr(t):H(t),n?H(n)+`=`+t:t}function W(e){return e!=null}function Ur(e){return e===`;`||e===`&`||e===`?`}function Wr(e,t,n,r){var i=e[n],a=[];if(W(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`bigint`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push(U(t,i,Ur(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(W).forEach(function(e){a.push(U(t,e,Ur(t)?n:``))}):Object.keys(i).forEach(function(e){W(i[e])&&a.push(U(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(W).forEach(function(n){e.push(U(t,n))}):Object.keys(i).forEach(function(n){W(i[n])&&(e.push(H(n)),e.push(U(t,i[n].toString())))}),Ur(t)?a.push(H(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?W(i)&&a.push(H(n)):i===``&&(t===`&`||t===`?`)?a.push(H(n)+`=`):i===``&&a.push(``);return a}function Gr(e){return{expand:Kr.bind(null,e)}}function Kr(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(Wr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return Hr(i)}),e===`/`?e:e.replace(/\/$/,``)}function qr(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Vr(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Br(n);n=Gr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Vr(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=Lr(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function Jr(e,t,n){return qr(Ir(e,t,n))}function Yr(e,t){let n=Ir(e,t),r=Jr.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:Yr.bind(null,n),merge:Ir.bind(null,n),parse:qr})}var Xr=Yr(null,jr),Zr=S(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))();const Qr=/^-?\d+$/,$r=/^-?\d+n+$/,ei=JSON.stringify,ti=JSON.parse,ni=/^-?\d+n$/,ri=/([\[:])?"(-?\d+)n"($|([\\n]|\s)*(\s|[\\n])*[,\}\]])/g,ii=/([\[:])?("-?\d+n+)n("$|"([\\n]|\s)*(\s|[\\n])*[,\}\]])/g,ai=(e,t,n)=>`rawJSON`in JSON?ei(e,(e,n)=>typeof n==`bigint`?JSON.rawJSON(n.toString()):typeof t==`function`?t(e,n):(Array.isArray(t)&&t.includes(e),n),n):e?ei(e,(e,n)=>typeof n==`string`&&n.match($r)||typeof n==`bigint`?n.toString()+`n`:typeof t==`function`?t(e,n):(Array.isArray(t)&&t.includes(e),n),n).replace(ri,`$1$2$3`).replace(ii,`$1$2$3`):ei(e,t,n),oi=()=>JSON.parse(`1`,(e,t,n)=>!!n&&n.source===`1`),si=(e,t,n,r)=>typeof t==`string`&&t.match(ni)?BigInt(t.slice(0,-1)):typeof t==`string`&&t.match($r)?t.slice(0,-1):typeof r==`function`?r(e,t,n):t,ci=(e,t)=>JSON.parse(e,(e,n,r)=>{let i=typeof n==`number`&&(n>2**53-1||n<-(2**53-1)),a=r&&Qr.test(r.source);return i&&a?BigInt(r.source):typeof t==`function`?t(e,n,r):n}),li=(2**53-1).toString(),ui=li.length,di=/"(?:\\.|[^"])*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g,fi=/^"-?\d+n+"$/,pi=(e,t)=>e?oi()?ci(e,t):ti(e.replace(di,(e,t,n,r)=>{let i=e[0]===`"`;if(i&&e.match(fi))return e.substring(0,e.length-1)+`n"`;let a=n||r,o=t&&(t.lengthsi(e,n,r,t)):ti(e,t);var mi=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function yi(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=_i(e.body)||Array.isArray(e.body)?ai(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new mi(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new mi(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await bi(o),new mi(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await bi(o),new mi(Si(u.data),s,{response:u,request:e});return u.data=r?await bi(o):o.body,u}async function bi(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(vi);let n=(0,Zr.safeParse)(t);if(xi(n)){let t=``;try{return t=await e.text(),pi(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(vi);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function xi(e){return e.type===`application/json`||e.type===`application/scim+json`}function Si(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function Ci(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return yi(n.parse(r));let i=(e,t)=>yi(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:Ci.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:Ci.bind(null,n)})}var wi=Ci(Xr,gi),Ti=`0.0.0-development`;function Ei(e){return`Request failed due to following response errors: +If you had completed the task, confirm the completion.`,d=i===1?e.fileParts:void 0,g=await(async()=>{try{return await Vn(r,c,o,d,f,n,t)}finally{await mn(r,c,n?.sessionTitle,t)}})();if(g.success)return p=g.eventStreamResult,{success:!0,exitCode:0,duration:Date.now()-a,sessionId:c,error:null,tokenUsage:p.tokens,model:p.model,cost:p.cost,prsCreated:p.prsCreated,commitsCreated:p.commitsCreated,commentsPosted:p.commentsPosted,llmError:null};if(m=g.error,h=g.llmError,!g.shouldRetry||i>=3)break;t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:i,maxAttempts:3,error:g.error,delayMs:Rn,sessionId:c}),await hn(Rn)}return{success:!1,exitCode:1,duration:Date.now()-a,sessionId:c,error:m??`Unknown error`,tokenUsage:p.tokens,model:p.model,cost:p.cost,prsCreated:p.prsCreated,commitsCreated:p.commitsCreated,commentsPosted:p.commentsPosted,llmError:h}}catch(e){let n=Date.now()-a,i=r(e);return t.error(`OpenCode execution failed`,{error:i,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:i,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:xn(e)?Sn(i):null}}finally{c!=null&&clearTimeout(c),o.abort(),u&&d?.close()}}async function rr(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await Ve(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function ir(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await We(e,t.repo,`agent: working`,`fcf2e1`,`Agent is currently working on this`,n)&&await Ge(e,t.repo,t.issueNumber,[`agent: working`],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function ar(e,t,n){await Promise.all([rr(e,t,n),ir(e,t,n)])}async function or(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await He(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Ue(e,t.repo,t.commentId,r.id,n)}async function sr(e,t,n,r){t.commentId!=null&&await Ve(e,t.repo,t.commentId,n,r)}async function cr(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await or(e,t,n),await sr(e,t,`hooray`,n),n.info(`Updated reaction to success indicator`,{commentId:t.commentId,reaction:`hooray`})}catch(e){n.warning(`Failed to update reaction (non-fatal)`,{error:r(e)})}}async function lr(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await or(e,t,n),await sr(e,t,`confused`,n),n.info(`Updated reaction to confused`,{commentId:t.commentId})}catch(e){n.warning(`Failed to update failure reaction (non-fatal)`,{error:r(e)})}}async function ur(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Ke(e,t.repo,t.issueNumber,`agent: working`,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function dr(e,t,n,r){n?await cr(e,t,r):await lr(e,t,r),await ur(e,t,r)}var fr=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(be(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(xe(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${ve}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},pr=S((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),mr=C(S((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[f.Accept]=this._getExistingOrDefaultHeader(t,f.Accept,p.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[f.Accept]=this._getExistingOrDefaultHeader(n,f.Accept,p.ApplicationJson),n[f.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,p.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[f.Accept]=this._getExistingOrDefaultHeader(n,f.Accept,p.ApplicationJson),n[f.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,p.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[f.Accept]=this._getExistingOrDefaultHeader(n,f.Accept,p.ApplicationJson),n[f.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,p.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===d.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&h.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!g.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},S(this.requestOptions.headers),S(e||{})):S(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=S(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=S(this.requestOptions.headers)[f.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[f.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new u.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===d.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let S=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),hr=ce(),gr=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function _r(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function vr(e){return new mr.HttpClient().getAgent(e)}function yr(e){return new mr.HttpClient().getAgentDispatcher(e)}function br(e){let t=yr(e);return(e,n)=>gr(this,void 0,void 0,function*(){return(0,hr.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function xr(){return process.env.GITHUB_API_URL||`https://api.github.com`}function V(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function Sr(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>Sr.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function Cr(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function wr(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const Tr=Function.bind,Er=Tr.bind(Tr);function Dr(e,t,n){let r=Er(wr,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=Er(Cr,null).apply(null,i)})}function Or(){let e=Symbol(`Singular`),t={registry:{}},n=Sr.bind(null,t,e);return Dr(n,t,e),n}function kr(){let e={registry:{}},t=Sr.bind(null,e);return Dr(t,e),t}var Ar={Singular:Or,Collection:kr},jr=`octokit-endpoint.js/0.0.0-development ${V()}`,Mr={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":jr},mediaType:{format:``}};function Nr(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Pr(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Fr(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Pr(t[r])&&r in e?n[r]=Fr(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Ir(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function Lr(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Nr(n.headers),Ir(n),Ir(n.headers);let r=Fr(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function Rr(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var zr=/\{[^{}}]+\}/g;function Br(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Hr(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function Ur(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function H(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function U(e,t,n){return t=e===`+`||e===`#`?Ur(t):H(t),n?H(n)+`=`+t:t}function W(e){return e!=null}function Wr(e){return e===`;`||e===`&`||e===`?`}function Gr(e,t,n,r){var i=e[n],a=[];if(W(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`bigint`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push(U(t,i,Wr(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(W).forEach(function(e){a.push(U(t,e,Wr(t)?n:``))}):Object.keys(i).forEach(function(e){W(i[e])&&a.push(U(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(W).forEach(function(n){e.push(U(t,n))}):Object.keys(i).forEach(function(n){W(i[n])&&(e.push(H(n)),e.push(U(t,i[n].toString())))}),Wr(t)?a.push(H(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?W(i)&&a.push(H(n)):i===``&&(t===`&`||t===`?`)?a.push(H(n)+`=`):i===``&&a.push(``);return a}function Kr(e){return{expand:qr.bind(null,e)}}function qr(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(Gr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return Ur(i)}),e===`/`?e:e.replace(/\/$/,``)}function Jr(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Hr(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Vr(n);n=Kr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Hr(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=Rr(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function Yr(e,t,n){return Jr(Lr(e,t,n))}function Xr(e,t){let n=Lr(e,t),r=Yr.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:Xr.bind(null,n),merge:Lr.bind(null,n),parse:Jr})}var Zr=Xr(null,Mr),Qr=S(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))();const $r=/^-?\d+$/,ei=/^-?\d+n+$/,ti=JSON.stringify,ni=JSON.parse,ri=/^-?\d+n$/,ii=/([\[:])?"(-?\d+)n"($|([\\n]|\s)*(\s|[\\n])*[,\}\]])/g,ai=/([\[:])?("-?\d+n+)n("$|"([\\n]|\s)*(\s|[\\n])*[,\}\]])/g,oi=(e,t,n)=>`rawJSON`in JSON?ti(e,(e,n)=>typeof n==`bigint`?JSON.rawJSON(n.toString()):typeof t==`function`?t(e,n):(Array.isArray(t)&&t.includes(e),n),n):e?ti(e,(e,n)=>typeof n==`string`&&n.match(ei)||typeof n==`bigint`?n.toString()+`n`:typeof t==`function`?t(e,n):(Array.isArray(t)&&t.includes(e),n),n).replace(ii,`$1$2$3`).replace(ai,`$1$2$3`):ti(e,t,n),si=()=>JSON.parse(`1`,(e,t,n)=>!!n&&n.source===`1`),ci=(e,t,n,r)=>typeof t==`string`&&t.match(ri)?BigInt(t.slice(0,-1)):typeof t==`string`&&t.match(ei)?t.slice(0,-1):typeof r==`function`?r(e,t,n):t,li=(e,t)=>JSON.parse(e,(e,n,r)=>{let i=typeof n==`number`&&(n>2**53-1||n<-(2**53-1)),a=r&&$r.test(r.source);return i&&a?BigInt(r.source):typeof t==`function`?t(e,n,r):n}),ui=(2**53-1).toString(),di=ui.length,fi=/"(?:\\.|[^"])*"|-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?/g,pi=/^"-?\d+n+"$/,mi=(e,t)=>e?si()?li(e,t):ni(e.replace(fi,(e,t,n,r)=>{let i=e[0]===`"`;if(i&&e.match(pi))return e.substring(0,e.length-1)+`n"`;let a=n||r,o=t&&(t.lengthci(e,n,r,t)):ni(e,t);var hi=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function bi(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=vi(e.body)||Array.isArray(e.body)?oi(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new hi(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new hi(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await xi(o),new hi(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await xi(o),new hi(Ci(u.data),s,{response:u,request:e});return u.data=r?await xi(o):o.body,u}async function xi(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(yi);let n=(0,Qr.safeParse)(t);if(Si(n)){let t=``;try{return t=await e.text(),mi(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(yi);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function Si(e){return e.type===`application/json`||e.type===`application/scim+json`}function Ci(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function wi(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return bi(n.parse(r));let i=(e,t)=>bi(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:wi.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:wi.bind(null,n)})}var Ti=wi(Zr,_i),Ei=`0.0.0-development`;function Di(e){return`Request failed due to following response errors: `+e.errors.map(e=>` - ${e.message}`).join(` -`)}var Di=class extends Error{constructor(e,t,n){super(Ei(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},Oi=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],ki=[`query`,`method`,`url`],Ai=/\/api\/v3\/?$/;function ji(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(ki.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>Oi.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Ai.test(a)&&(i.url=a.replace(Ai,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Di(i,t,e.data)}return e.data.data})}function Mi(e,t){let n=e.defaults(t);return Object.assign((e,t)=>ji(n,e,t),{defaults:Mi.bind(null,n),endpoint:n.endpoint})}Mi(wi,{headers:{"user-agent":`octokit-graphql.js/${Ti} ${br()}`},method:`POST`,url:`/graphql`});function Ni(e){return Mi(e,{method:`POST`,url:`/graphql`})}var Pi=`(?:[a-zA-Z0-9_-]+)`,Fi=`\\.`,Ii=RegExp(`^${Pi}${Fi}${Pi}${Fi}${Pi}$`),Li=Ii.test.bind(Ii);async function Ri(e){let t=Li(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function zi(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Bi(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=zi(e),t(i)}var Vi=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Ri.bind(null,e),{hook:Bi.bind(null,e)})};const Hi=`7.0.6`,Ui=()=>{},Wi=console.warn.bind(console),Gi=console.error.bind(console);function Ki(e={}){return typeof e.debug!=`function`&&(e.debug=Ui),typeof e.info!=`function`&&(e.info=Ui),typeof e.warn!=`function`&&(e.warn=Wi),typeof e.error!=`function`&&(e.error=Gi),e}const qi=`octokit-core.js/${Hi} ${br()}`;var Ji=class{static VERSION=Hi;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new kr.Collection,n={baseUrl:wi.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${qi}`:qi,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=wi.defaults(n),this.graphql=Ni(this.request).defaults(n),this.log=Ki(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Vi(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=ra(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:oa(e,t,n,r)})}Object.assign(aa,{iterator:ia});function sa(e){return{paginate:Object.assign(aa.bind(null,e),{iterator:ia.bind(null,e)})}}sa.VERSION=na,new ur;const ca=yr(),la={baseUrl:ca,request:{agent:gr(ca),fetch:vr(ca)}},ua=Ji.plugin(ea,sa).defaults(la);function da(e,t){let n=Object.assign({},t||{}),r=hr(e,n);return r&&(n.auth=r),n}const fa=new ur;function pa(e,t,...n){return new(ua.plugin(...n))(da(e,t))}var K=C(ue(),1),ma=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})},ha=class{constructor(e,t,n){if(e<1)throw Error(`max attempts should be greater than or equal to 1`);if(this.maxAttempts=e,this.minSeconds=Math.floor(t),this.maxSeconds=Math.floor(n),this.minSeconds>this.maxSeconds)throw Error(`min seconds should be less than or equal to max seconds`)}execute(e,t){return ma(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},q=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})},ga=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const _a=process.platform===`win32`;process.platform;function va(e,t,n,r){return q(this,void 0,void 0,function*(){return t||=F.join(Na(),ye.randomUUID()),yield s(F.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new ha(3,Pa(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Pa(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>q(this,void 0,void 0,function*(){return yield ya(e,t||``,n,r)}),e=>!(e instanceof ga&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function ya(e,t,n,r){return q(this,void 0,void 0,function*(){if(P.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new ga(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=Ce.promisify(Fe.pipeline),s=Pa(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),c=!1;try{return yield o(s,P.createWriteStream(t)),j(`download complete`),c=!0,t}finally{if(!c){j(`download failed`);try{yield v(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function ba(e,t){return q(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Da(t),j(`Checking tar --version`);let r=``;yield M(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],m()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return _a&&i&&(a.push(`--force-local`),o=t.replace(/\\/g,`/`),s=e.replace(/\\/g,`/`)),i&&(a.push(`--warning=no-unknown-keyword`),a.push(`--overwrite`)),a.push(`-C`,o,`-f`,s),yield M(`tar`,a),t})}function xa(e,t){return q(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Da(t),_a?yield Sa(e,t):yield Ca(e,t),t})}function Sa(e,t){return q(this,void 0,void 0,function*(){let n=e.replace(/'/g,`''`).replace(/"|\n|\r/g,``),r=t.replace(/'/g,`''`).replace(/"|\n|\r/g,``),i=yield b(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield M(`"${i}"`,e)}else{let e=[`-NoLogo`,`-Sta`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`,`if ((Get-Command -Name Expand-Archive -Module Microsoft.PowerShell.Archive -ErrorAction Ignore)) { Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force }`,`else {[System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`].join(` `)],t=yield b(`powershell`,!0);j(`Using powershell at path: ${t}`),yield M(`"${t}"`,e)}})}function Ca(e,t){return q(this,void 0,void 0,function*(){let n=yield b(`unzip`,!0),r=[e];m()||r.unshift(`-q`),r.unshift(`-o`),yield M(`"${n}"`,r,{cwd:t})})}function wa(e,t,n,r){return q(this,void 0,void 0,function*(){if(n=K.clean(n)||n,r||=_e.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!P.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield Oa(t,n,r);for(let t of P.readdirSync(e))yield y(F.join(e,t),i,{recursive:!0});return ka(t,n,r),i})}function Ta(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=_e.arch(),Aa(t)||(t=ja(Ea(e,n),t));let r=``;if(t){t=K.clean(t)||``;let i=F.join(Ma(),e,t,n);j(`checking cache: ${i}`),P.existsSync(i)&&P.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Ea(e,t){let n=[];t||=_e.arch();let r=F.join(Ma(),e);if(P.existsSync(r)){let e=P.readdirSync(r);for(let i of e)if(Aa(i)){let e=F.join(r,i,t||``);P.existsSync(e)&&P.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Da(e){return q(this,void 0,void 0,function*(){return e||=F.join(Na(),ye.randomUUID()),yield s(e),e})}function Oa(e,t,n){return q(this,void 0,void 0,function*(){let r=F.join(Ma(),e,K.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield v(r),yield v(i),yield s(r),r})}function ka(e,t,n){let r=`${F.join(Ma(),e,K.clean(t)||t,n||``)}.complete`;P.writeFileSync(r,``),j(`finished caching tool`)}function Aa(e){let t=K.clean(e)||``;j(`isExplicit: ${t}`);let n=K.valid(t)!=null;return j(`explicit? ${n}`),n}function ja(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>K.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(K.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Ma(){let e=process.env.RUNNER_TOOL_CACHE||``;return Se(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function Na(){let e=process.env.RUNNER_TEMP||``;return Se(e,`Expected RUNNER_TEMP to be defined`),e}function Pa(e,t){let n=global[e];return n===void 0?t:n}function Fa(e){let t;try{t=JSON.parse(e)}catch(e){throw e instanceof SyntaxError?Error(`Invalid auth-json format: ${e.message}`):e}if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`auth-json must be a JSON object`);return t}async function Ia(e,t,n){let r=L.join(t,`auth.json`);await I.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await I.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function La(){let e=N.platform,t=N.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Ra(e,t){return`https://github.com/oven-sh/bun/releases/download/bun-${e.startsWith(`v`)?e:`v${e}`}/${`bun-${t.os}-${t.arch}${t.ext}`}`}async function za(e,t,n,i,a=pe){let o=La(),s=t.find(`bun`,a,o.arch);if(s.length>0)return e.info(`Bun found in cache`,{version:a,path:s}),i(s),await Va(s),{path:s,version:a,cached:!0};e.info(`Downloading Bun`,{version:a});let c=Ra(a,o);try{let r=await t.downloadTool(c);if(N.platform!==`win32`&&!await Ha(r,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let s=await Ba(await t.extractZip(r),t),l=ke.dirname(s);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,a,o.arch);return i(u),await Va(u),e.info(`Bun installed`,{version:a,path:u}),{path:u,version:a,cached:!1}}catch(e){let t=r(e);throw Error(`Failed to install Bun ${a}: ${t}`)}}async function Ba(e,t){for(let n of await Oe.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=ke.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ba(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ba(i,t)}throw Error(`Could not find executable: bun`)}async function Va(e){let t=e=>N.platform===`win32`?`${e}.exe`:e,n=ke.join(e,t(`bun`));try{await Oe.symlink(n,ke.join(e,t(`bunx`)))}catch(e){let t=typeof e==`object`?e.code:void 0;if(t!==`EEXIST`&&t!==`EPERM`&&t!==`EACCES`)throw e}}async function Ha(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function Ua(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Wa(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),pa(t,{log:Ua(n)})}async function Ga(e,t){try{let{data:n}=await e.rest.users.getAuthenticated();return t.debug(`Authenticated as`,{login:n.login,type:n.type}),n.login}catch{return t.debug(`Failed to get authenticated user, may be app token`),`fro-bot[bot]`}}async function Ka(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};N.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Ga(e,r)),{authenticated:!0,method:a,botLogin:o}}async function qa(e,t){let n=await t.getExecOutput(`git`,[`config`,e],{ignoreReturnCode:!0,silent:!0});return n.exitCode===0&&n.stdout.trim().length>0?n.stdout.trim():null}async function Ja(e,t,n,r){let i=await qa(`user.name`,r),a=await qa(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}const Ya=new Set([`__proto__`,`prototype`,`constructor`]);function Xa(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Za(e,t){let n=Object.create(null);for(let[t,r]of Object.entries(e))Ya.has(t)||(n[t]=r);for(let[e,r]of Object.entries(t)){if(Ya.has(e))continue;let t=n[e];Xa(r)&&Xa(t)?n[e]=Za(t,r):n[e]=r}return n}async function Qa(e,t,n){let r=JSON.parse(e);if(!Xa(r))throw Error(`omo-config must be a JSON object (non-null, non-array)`);let i=r;await I.mkdir(t,{recursive:!0});let a=L.join(t,`oh-my-opencode.json`),o={};try{let e=await I.readFile(a,`utf8`),t=JSON.parse(e);typeof t==`object`&&t&&!Array.isArray(t)&&(o=t)}catch(e){n.debug(`Using empty base oMo config`,{path:a,error:String(e)})}let s=Za(o,i);await I.writeFile(a,JSON.stringify(s,null,2)),n.info(`Wrote oMo config`,{path:a,keyCount:Object.keys(i).length})}async function $a(e,t,n={}){let{logger:i,execAdapter:a}=t,{claude:o=`no`,copilot:s=`no`,gemini:c=`no`,openai:l=`no`,opencodeZen:u=`no`,zaiCodingPlan:d=`no`,kimiForCoding:f=`no`}=n;i.info(`Installing Oh My OpenAgent plugin`,{version:e,claude:o,copilot:s,gemini:c,openai:l,opencodeZen:u,zaiCodingPlan:d,kimiForCoding:f});let p=``,m=[`oh-my-openagent@${e}`,`install`,`--no-tui`,`--skip-auth`,`--claude=${o}`,`--copilot=${s}`,`--gemini=${c}`,`--openai=${l}`,`--opencode-zen=${u}`,`--zai-coding-plan=${d}`,`--kimi-for-coding=${f}`];try{let t=await a.exec(`bunx`,m,{listeners:{stdout:e=>{p+=e.toString()},stderr:e=>{p+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-openagent install returned exit code ${t}`;return i.error(e,{output:p.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${p.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(p),r=n!=null&&n[1]!=null?n[1]:e;return i.info(`oMo plugin installed`,{version:r}),{installed:!0,version:r,error:null}}catch(e){let t=r(e),n=p.length>0?`${t}\nOutput: ${p.slice(0,500)}`:t;return i.error(`Failed to run oMo installer`,{error:t,output:p.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-openagent install failed: ${n}`}}}const eo=`opencode`,to=g;function no(){let e=Ne.platform(),t=Ne.arch(),n={darwin:`darwin`,linux:`linux`,win32:`windows`},r={x64:`x64`,arm64:`arm64`},i=e===`win32`||e===`darwin`?`.zip`:`.tar.gz`;return{os:n[e]??`linux`,arch:r[t]??`x64`,ext:i}}function ro(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function io(e,t,n,r){if(N.platform===`win32`)return!0;try{let{stdout:i}=await r.getExecOutput(`file`,[e],{silent:!0}),a=(t===`.zip`?[`Zip archive`,`ZIP`]:[`gzip`,`tar`,`compressed`]).some(e=>i.includes(e));return a||n.warning(`Download validation failed`,{output:i.trim()}),a}catch{return n.debug(`Could not validate download (file command unavailable)`),!0}}async function ao(e,t,n,i,a=to){let o=no(),s=n.find(eo,e,o.arch);if(s.length>0)return t.info(`OpenCode found in cache`,{version:e,path:s}),{path:s,version:e,cached:!0};try{return await oo(e,o,t,n,i)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:a,error:r(n)})}if(e!==a)try{let e=await oo(a,o,t,n,i);return t.info(`Installed fallback version`,{version:a}),e}catch(t){throw Error(`Failed to install OpenCode (tried ${e} and ${a}): ${r(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function oo(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=ro(e,t),o=await r.downloadTool(a);if(!await io(o,t.ext,n,i))throw Error(`Downloaded archive appears corrupted`);n.info(`Extracting OpenCode`);let s=t.ext===`.zip`?await r.extractZip(o):await r.extractTar(o);n.info(`Caching OpenCode`);let c=await r.cacheDir(s,eo,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function so(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const co={restoreCache:async(e,t,n)=>T(e,t,n),saveCache:async(e,t)=>oe(e,t)};function lo(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${me}-${t}-oc-${n}-omo-${r}`}function uo(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${me}-${t}-oc-${n}-omo-${r}-`]}async function fo(e){let{logger:t,os:n,opencodeVersion:i,omoVersion:a,toolCachePath:o,bunCachePath:s,omoConfigPath:c,cacheAdapter:l=co}=e,u=lo({os:n,opencodeVersion:i,omoVersion:a}),d=uo({os:n,opencodeVersion:i,omoVersion:a}),f=[o,s,c];t.info(`Restoring tools cache`,{primaryKey:u,restoreKeys:[...d],paths:f});try{let e=await l.restoreCache(f,u,[...d]);return e==null?(t.info(`Tools cache miss - will install tools`),{hit:!1,restoredKey:null}):(t.info(`Tools cache restored`,{restoredKey:e}),{hit:!0,restoredKey:e})}catch(e){return t.warning(`Tools cache restore failed`,{error:r(e)}),{hit:!1,restoredKey:null}}}async function po(e){let{logger:t,os:n,opencodeVersion:i,omoVersion:a,toolCachePath:o,bunCachePath:s,omoConfigPath:c,cacheAdapter:l=co}=e,u=lo({os:n,opencodeVersion:i,omoVersion:a}),d=[o,s,c];t.info(`Saving tools cache`,{saveKey:u,paths:d});try{return await l.saveCache(d,u),t.info(`Tools cache saved`,{saveKey:u}),!0}catch(e){return e instanceof Error&&e.message.includes(`already exists`)?(t.info(`Tools cache key already exists, skipping save`),!0):(t.warning(`Tools cache save failed`,{error:r(e)}),!1)}}function mo(){return{find:Ta,downloadTool:va,extractTar:ba,extractZip:xa,cacheDir:wa}}function ho(){return{exec:M,getExecOutput:t}}async function go(t,n){let a=Date.now(),o=i({component:`setup`}),s=mo(),l=ho();try{o.info(`Starting setup`,{version:t.opencodeVersion});let i;try{i=Fa(t.authJson)}catch(e){return c(`Invalid auth-json: ${r(e)}`),null}let u=t.opencodeVersion;if(u===`latest`)try{u=await so(o)}catch(e){o.warning(`Failed to get latest version, using fallback`,{error:r(e)}),u=to}let f=t.omoVersion,m=N.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,h=Ae(m,`opencode`),g=Ae(m,`bun`),_=Ae(Pe(),`.config`,`opencode`),v=se(),y=await fo({logger:o,os:v,opencodeVersion:u,omoVersion:f,toolCachePath:h,bunCachePath:g,omoConfigPath:_}),b=y.hit?`hit`:`miss`,x,S=!1,C=null;if(y.hit){let e=s.find(`opencode`,u);e.length>0?(x={path:e,version:u,cached:!0},o.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):o.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:y.restoredKey})}if(x==null)try{x=await ao(u,o,s,l)}catch(e){return c(`Failed to install OpenCode: ${r(e)}`),null}let w=!1;try{await za(o,s,l,p,pe),w=!0}catch(e){o.warning(`Bun installation failed, oMo will be unavailable`,{error:r(e)})}if(w){if(t.omoConfig!=null)try{await Qa(t.omoConfig,_,o)}catch(e){o.warning(`Failed to write omo-config, continuing without custom config`,{error:r(e)})}let e=await $a(f,{logger:o,execAdapter:l},t.omoProviders);e.installed?(o.info(`oMo installed`,{version:e.version}),S=!0):o.warning(`oMo installation failed, continuing without oMo`,{error:e.error??`unknown error`}),C=e.error}let T={autoupdate:!1};if(t.opencodeConfig!=null){let e;try{e=JSON.parse(t.opencodeConfig)}catch{return c(`opencode-config must be valid JSON`),null}if(typeof e!=`object`||!e||Array.isArray(e))return c(`opencode-config must be a JSON object`),null;Object.assign(T,e)}e(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(T)),y.hit||await po({logger:o,os:v,opencodeVersion:u,omoVersion:f,toolCachePath:h,bunCachePath:g,omoConfigPath:_}),p(x.path),d(`opencode-path`,x.path),d(`opencode-version`,x.version),o.info(`OpenCode ready`,{version:x.version,cached:x.cached});let E=pa(n),D=await Ka(E,null,n,o);e(`GH_TOKEN`,n),o.info(`GitHub CLI configured`),await Ja(E,D.botLogin,o,l);let O=Ae(ie(),`opencode`),k=await Ia(i,O,o);d(`auth-json-path`,k),o.info(`auth.json populated`,{path:k});let ee=Date.now()-a,te={opencodePath:x.path,opencodeVersion:x.version,ghAuthenticated:D.authenticated,omoInstalled:S,omoError:C,toolsCacheStatus:b,duration:ee};return o.info(`Setup complete`,{duration:ee}),te}catch(e){let t=r(e);return o.error(`Setup failed`,{error:t}),c(t),null}}function _o(e){return{success:!0,data:e}}function vo(e){return{success:!1,error:e}}const yo=[`OWNER`,`MEMBER`,`COLLABORATOR`];async function bo(e,t){try{let{client:n,server:r}=await fn({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),_o({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),vo(Error(`Server bootstrap failed: ${n}`))}}async function xo(e,t){let n=e??`opencode`;try{let e=``;await M(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function So(e){let{logger:t,opencodeVersion:n}=e,r=N.env.OPENCODE_PATH??null,i=await xo(r,t);if(i.available&&i.version!=null)return t.info(`OpenCode already available`,{version:i.version}),{path:r??`opencode`,version:i.version,didSetup:!1};t.info(`OpenCode not found, running auto-setup`,{requestedVersion:n});let a=await go({opencodeVersion:n,authJson:e.authJson,appId:null,privateKey:null,opencodeConfig:e.opencodeConfig,omoConfig:null,omoVersion:e.omoVersion,omoProviders:e.omoProviders},e.githubToken);if(a==null)throw Error(`Auto-setup failed: runSetup returned null`);return p(a.opencodePath),N.env.OPENCODE_PATH=a.opencodePath,t.info(`Auto-setup completed`,{version:a.opencodeVersion,path:a.opencodePath}),{path:a.opencodePath,version:a.opencodeVersion,didSetup:!0}}async function Co(e,t){let n={repo:e.agentContext.repo,commentId:e.agentContext.commentId,issueNumber:e.agentContext.issueNumber,issueType:e.agentContext.issueType,botLogin:e.botLogin},r=i({phase:`acknowledgment`});return await rr(e.githubClient,n,r),t.debug(`Acknowledgment phase completed`),n}function wo(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function To(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function Eo(e){let t=e.trim(),n=t.indexOf(`/`);if(n===-1)throw Error(`Invalid model format: "${e}". Expected "provider/model" (e.g., "anthropic/claude-sonnet-4-20250514")`);let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();if(r.length===0)throw Error(`Invalid model format: "${e}". Provider cannot be empty.`);if(i.length===0)throw Error(`Invalid model format: "${e}". Model ID cannot be empty.`);return{providerID:r,modelID:i}}function Do(e,t=`timeout`){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a non-negative integer, received: ${e}`);let r=Number.parseInt(n,10);if(Number.isNaN(r)||r<0)throw Error(`${t} must be a non-negative integer, received: ${e}`);return r}const Oo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function ko(e){let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),n=`no`,r=`no`,i=`no`,a=`no`,o=`no`,s=`no`,c=`no`;for(let e of t){if(!Oo.includes(e))throw Error(`Invalid omo-providers value: "${e}". Valid values: ${Oo.join(`, `)}`);switch(e){case`claude`:n=`yes`;break;case`claude-max20`:n=`max20`;break;case`copilot`:r=`yes`;break;case`gemini`:i=`yes`;break;case`openai`:a=`yes`;break;case`opencode-zen`:o=`yes`;break;case`zai-coding-plan`:s=`yes`;break;case`kimi-for-coding`:c=`yes`;break}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s,kimiForCoding:c}}function Ao(){try{let e=A(`github-token`,{required:!0}).trim();if(e.length===0)return vo(Error(`github-token is required but was not provided`));let t=A(`auth-json`,{required:!0}).trim();if(t.length===0)return vo(Error(`auth-json is required but was not provided`));wo(t,`auth-json`);let r=A(`prompt`).trim(),i=r.length>0?r:null,a=A(`session-retention`).trim(),o=a.length>0?To(a,`session-retention`):50,s=A(`s3-backup`).trim().toLowerCase()===`true`,c=A(`s3-bucket`).trim(),l=c.length>0?c:null,u=A(`aws-region`).trim(),d=u.length>0?u:null,f=A(`agent`).trim(),p=f.length>0?f:w,m=A(`model`).trim(),h=m.length>0?Eo(m):null,_=A(`timeout`).trim(),v=_.length>0?Do(_):n,y=A(`opencode-version`).trim(),b=y.length>0?y:g,x=A(`skip-cache`).trim().toLowerCase()===`true`,S=A(`omo-version`).trim(),C=S.length>0?S:he,T=A(`omo-providers`).trim(),E=ko(T.length>0?T:``),D=A(`opencode-config`).trim(),O=D.length>0?D:null,k=A(`dedup-window`).trim(),ee=k.length>0?Do(k,`dedup-window`):ge;if(O!=null){wo(O,`opencode-config`);let e=JSON.parse(O);if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Input 'opencode-config' must be a JSON object`)}return _o({githubToken:e,authJson:t,prompt:i,sessionRetention:o,s3Backup:s,s3Bucket:l,awsRegion:d,agent:p,model:h,timeoutMs:v,opencodeVersion:b,skipCache:x,omoVersion:C,omoProviders:E,opencodeConfig:O,dedupWindow:ee})}catch(e){return vo(e instanceof Error?e:Error(String(e)))}}async function jo(e){let t=Ao();if(!t.success)return c(`Invalid inputs: ${t.error.message}`),null;let n=t.data,r=i({phase:`main`});r.info(`Action inputs parsed`,{sessionRetention:n.sessionRetention,s3Backup:n.s3Backup,hasGithubToken:n.githubToken.length>0,hasPrompt:n.prompt!=null,agent:n.agent,hasModelOverride:n.model!=null,timeoutMs:n.timeoutMs});let o=await So({logger:r,opencodeVersion:n.opencodeVersion,githubToken:n.githubToken,authJson:n.authJson,omoVersion:n.omoVersion,omoProviders:n.omoProviders,opencodeConfig:n.opencodeConfig});return o.didSetup?r.info(`OpenCode auto-setup completed`,{version:o.version}):r.info(`OpenCode already available`,{version:o.version}),a(_.OPENCODE_VERSION,o.version),e.debug(`Bootstrap phase completed`,{opencodeVersion:o.version}),{inputs:n,logger:r,opencodeResult:o}}const Mo=/^[0-9a-f]{40}$/i;function No(){return{exec:M,getExecOutput:t}}async function Po(e){let{workspacePath:t,logger:n,execAdapter:i=No()}=e,a=L.join(t,`.git`),o=L.join(a,`opencode`);try{let e=(await I.readFile(o,`utf8`)).trim();if(e.length>0){if(Mo.test(e))return n.debug(`Project ID loaded from cache`,{projectId:e}),{projectId:e,source:`cached`};n.warning(`Invalid cached project ID format, regenerating`,{cachedId:e})}}catch(e){n.debug(`No cached project ID found`,{error:r(e)})}try{let e=await I.readFile(a,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};a=L.resolve(t,n[1]),o=L.join(a,`opencode`)}catch(e){if((typeof e==`object`?e.code:void 0)!==`EISDIR`)return{projectId:null,source:`error`,error:`Not a git repository`}}try{let{stdout:e,exitCode:a}=await i.getExecOutput(`git`,[`rev-list`,`--max-parents=0`,`--all`],{cwd:t,silent:!0});if(a!==0||e.trim().length===0)return{projectId:null,source:`error`,error:`No commits found in repository`};let s=e.trim().split(` -`).map(e=>e.trim()).filter(e=>e.length>0).sort();if(s.length===0)return{projectId:null,source:`error`,error:`No root commits found`};let c=s[0];try{await I.writeFile(o,c,{encoding:`utf8`,flag:`wx`}),n.info(`Project ID generated and cached`,{projectId:c,source:`generated`})}catch(e){(typeof e==`object`?e.code:void 0)===`EEXIST`?n.debug(`Project ID file already written by concurrent process, skipping`,{projectId:c}):n.warning(`Failed to cache project ID (continuing)`,{error:r(e)})}return{projectId:c,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:r(e)}}}async function Fo(e){let t=ne(),n=i({phase:`cache`}),r=re(),a=L.join(r,`.git`,`opencode`),o=await ae({components:t,logger:n,storagePath:k(),authPath:fe(),projectIdPath:a,opencodeVersion:e.opencodeResult.version}),s=o.corrupted?`corrupted`:o.hit?`hit`:`miss`;e.logger.info(`Cache restore completed`,{cacheStatus:s,key:o.key});let l=await Po({workspacePath:r,logger:n});l.source===`error`?n.warning(`Failed to generate project ID (continuing)`,{error:l.error}):n.debug(`Project ID ready`,{projectId:l.projectId,source:l.source});let u=i({phase:`server-bootstrap`}),d=await bo(new AbortController().signal,u);if(!d.success)return c(`OpenCode server bootstrap failed: ${d.error.message}`),null;let f=d.data;return u.info(`SDK server bootstrapped successfully`),{cacheResult:o,cacheStatus:s,serverHandle:f}}const Io={markdownImage:/!\[([^\]]*)\]\((https:\/\/github\.com\/user-attachments\/assets\/[^)]+)\)/gi,markdownLink:/\[([^\]]+)\]\((https:\/\/github\.com\/user-attachments\/files\/[^)]+)\)/gi,htmlImage:/]*src=["'](https:\/\/github\.com\/user-attachments\/assets\/[^"']+)["'][^>]*>/gi};function Lo(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function Ro(e){let t=[],n=new Set;return Lo(Io.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&Tn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Lo(Io.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&Tn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Lo(Io.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&Tn(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),Io.htmlImage.lastIndex=0,t}function zo(e,t,n){try{let r=new URL(e).pathname.split(`/`).at(-1);if(r!=null&&/\.[a-z0-9]+$/i.test(r))return r;if(t.trim().length>0){let e=t.replaceAll(/[^\w.-]/g,`_`).slice(0,50);return e.trim().length>0?e:`attachment_${n+1}`}return`attachment_${n+1}`}catch{return`attachment_${n+1}`}}const Bo={maxFiles:5,maxFileSizeBytes:5*1024*1024,maxTotalSizeBytes:15*1024*1024,allowedMimeTypes:[`image/png`,`image/jpeg`,`image/gif`,`image/webp`,`image/svg+xml`,`text/plain`,`text/markdown`,`text/csv`,`application/json`,`application/pdf`]},Vo=[`github.com`,`githubusercontent.com`];async function Ho(e,t,n,i,a){a.debug(`Downloading attachment`,{url:e.url});try{let r=await fetch(e.url,{headers:{Authorization:`Bearer ${n}`,Accept:`*/*`,"User-Agent":`fro-bot-agent`},redirect:`manual`}),o=r;if(r.status>=300&&r.status<400){let t=r.headers.get(`location`);if(t==null)return a.warning(`Redirect without location`,{url:e.url}),null;let n=new URL(t);if(!Vo.some(e=>n.hostname===e||n.hostname.endsWith(`.${e}`)))return a.warning(`Redirect to non-GitHub host blocked`,{url:e.url,redirectTo:n.hostname}),null;o=await fetch(t,{headers:{Accept:`*/*`,"User-Agent":`fro-bot-agent`},redirect:`follow`})}if(!o.ok)return a.warning(`Attachment download failed`,{url:e.url,status:o.status}),null;let s=o.headers.get(`content-length`);if(s!=null){let t=Number.parseInt(s,10);if(t>i.maxFileSizeBytes)return a.warning(`Attachment exceeds size limit (Content-Length)`,{url:e.url,size:t,limit:i.maxFileSizeBytes}),null}let c=we.from(await o.arrayBuffer());if(c.length>i.maxFileSizeBytes)return a.warning(`Attachment exceeds size limit`,{url:e.url,size:c.length,limit:i.maxFileSizeBytes}),null;let l=o.headers.get(`content-type`)??`application/octet-stream`,u=zo(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await I.mkdtemp(L.join(Me.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=L.join(p,m);return await I.writeFile(h,c),a.debug(`Attachment downloaded`,{filename:u,mime:f,sizeBytes:c.length,tempPath:h}),{url:e.url,filename:u,mime:f,sizeBytes:c.length,tempPath:h}}catch(t){return a.warning(`Attachment download error`,{url:e.url,error:r(t)}),null}}async function Uo(e,t,n=Bo,r){return Promise.all(e.map(async(e,i)=>Ho(e,i,t,n,r)))}async function Wo(e,t){for(let n of e)try{await I.unlink(n);let e=L.dirname(n);await I.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:r(e)})}}function Go(e){return e.map(e=>({type:`file`,mime:e.mime,url:De(e.tempPath).toString(),filename:e.filename}))}function Ko(e,t,n){let r=e,i=new Set(n.map(e=>e.filename));for(let e of t){let t=n.find(e=>i.has(e.filename));t!=null&&(r=r.replace(e.originalMarkdown,`@${t.filename}`))}return r}function qo(e,t,n,r){return{processed:n,skipped:r,modifiedBody:Ko(e,t,n),fileParts:Go(n),tempFiles:n.map(e=>e.tempPath)}}function Jo(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function Yo(e,t=Bo,n){let r=[],i=[],a=0;for(let o of e)if(o!=null){if(r.length>=t.maxFiles){i.push({url:o.url,reason:`Exceeds max file count (${t.maxFiles})`}),n.debug(`Attachment skipped: max count`,{url:o.url});continue}if(o.sizeBytes>t.maxFileSizeBytes){i.push({url:o.url,reason:`File too large (${Jo(o.sizeBytes)} > ${Jo(t.maxFileSizeBytes)})`}),n.debug(`Attachment skipped: too large`,{url:o.url,size:o.sizeBytes});continue}if(a+o.sizeBytes>t.maxTotalSizeBytes){i.push({url:o.url,reason:`Would exceed total size limit (${Jo(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!Xo(o.mime,t.allowedMimeTypes)){i.push({url:o.url,reason:`MIME type not allowed: ${o.mime}`}),n.debug(`Attachment skipped: MIME type`,{url:o.url,mime:o.mime});continue}a+=o.sizeBytes,r.push({filename:o.filename,mime:o.mime,sizeBytes:o.sizeBytes,tempPath:o.tempPath}),n.info(`Attachment validated`,{filename:o.filename,mime:o.mime,sizeBytes:o.sizeBytes})}return{validated:r,skipped:i}}function Xo(e,t){let[n]=e.split(`/`);for(let r of t)if(r===e||r.endsWith(`/*`)&&n!=null&&n===r.slice(0,-2))return!0;return!1}function J(e){let t=L.resolve(e);return t.endsWith(L.sep)&&t.length>1?t.slice(0,-1):t}const Zo=e=>typeof e==`object`&&!!e,Y=e=>typeof e==`string`?e:null,Qo=e=>typeof e==`number`?e:null;function $o(e){if(Array.isArray(e))return e.filter(Zo).map(e=>({file:Y(e.file)??``,additions:Qo(e.additions)??0,deletions:Qo(e.deletions)??0}))}function es(e){return{id:e.id,version:e.version,projectID:e.projectID,directory:e.directory,parentID:e.parentID,title:e.title,time:{created:e.time.created,updated:e.time.updated,compacting:e.time.compacting,archived:e.time.archived},summary:e.summary==null?void 0:{additions:e.summary.additions,deletions:e.summary.deletions,files:e.summary.files,diffs:$o(e.summary.diffs)},share:e.share?.url==null?void 0:{url:e.share.url},permission:e.permission==null?void 0:{rules:e.permission.rules},revert:e.revert==null?void 0:{messageID:e.revert.messageID,partID:e.revert.partID,snapshot:e.revert.snapshot,diff:e.revert.diff}}}async function ts(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Zo(e))continue;let t=Y(e.id),n=Y(e.worktree),i=Y(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i,vcs:`git`,time:{created:0,updated:0}})}return r}async function ns(e,t,n){let r=J(t),i=await ts(e,n);for(let e of i){if(J(e.worktree)===r)return e;let t=Y(e.path);if(t!=null&&J(t)===r)return e}return null}function rs(e){return e.status===`running`?{status:`running`,input:e.input,time:{start:e.time.start}}:e.status===`error`?{status:`error`,input:e.input,error:e.error,time:{start:e.time.start,end:e.time.end}}:e.status===`pending`?{status:`pending`}:{status:`completed`,input:e.input,output:e.output,title:e.title,metadata:e.metadata,time:{start:e.time.start,end:e.time.end,compacted:e.time.compacted},attachments:void 0}}function is(e){let t={id:e.id,sessionID:e.sessionID,messageID:e.messageID};if(e.type===`text`)return{...t,type:`text`,text:e.text,synthetic:e.synthetic,ignored:e.ignored,time:e.time,metadata:e.metadata};if(e.type===`reasoning`)return{...t,type:`reasoning`,reasoning:e.reasoning??e.text,time:e.time};if(e.type===`tool`)return{...t,type:`tool`,callID:e.callID,tool:e.tool,state:rs(e.state),metadata:e.metadata};if(e.type!==`step-finish`)return{...t,type:`text`,text:`text`in e?e.text:``};let n=e;return{...t,type:`step-finish`,reason:n.reason,snapshot:n.snapshot,cost:n.cost,tokens:{input:n.tokens.input,output:n.tokens.output,reasoning:n.tokens.reasoning,cache:{read:n.tokens.cache.read,write:n.tokens.cache.write}}}}function as(e){if(e.role===`user`){let t=e;return{id:t.id,sessionID:t.sessionID,role:`user`,time:{created:t.time.created},summary:t.summary==null?void 0:{title:t.summary.title,body:t.summary.body,diffs:$o(t.summary.diffs)??[]},agent:t.agent,model:{providerID:t.model.providerID,modelID:t.model.modelID},system:t.system,tools:t.tools,variant:t.variant}}let t=e;return{id:t.id,sessionID:t.sessionID,role:`assistant`,time:{created:t.time.created,completed:t.time.completed},parentID:t.parentID,modelID:t.modelID,providerID:t.providerID,mode:t.mode,agent:t.agent??``,path:{cwd:t.path.cwd,root:t.path.root},summary:t.summary,cost:t.cost,tokens:{input:t.tokens.input,output:t.tokens.output,reasoning:t.tokens.reasoning,cache:{read:t.tokens.cache.read,write:t.tokens.cache.write}},finish:t.finish,error:t.error?{name:t.error.name,message:Y(t.error.data.message)??``}:void 0}}function os(e){return[...e.map(e=>{let t=as(`info`in e?e.info:e),n=`parts`in e?e.parts.map(is):void 0;return n==null||n.length===0?t:{...t,parts:n}})].sort((e,t)=>e.time.created-t.time.created)}async function ss(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(es):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function cs(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?os(r.data):(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function ls(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(es);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function us(e,t,n){let r=await e.session.delete({path:{id:t}});if(r.error!=null){n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)});return}n.debug(`Deleted session via SDK`,{sessionID:t})}const ds={maxSessions:50,maxAgeDays:30};async function fs(e,t,n,i){let{maxSessions:a,maxAgeDays:o}=n;if(i.info(`Starting session pruning`,{workspacePath:t,maxSessions:a,maxAgeDays:o}),await ns(e,t,i)==null)return i.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let s=await ss(e,t,i),c=s.filter(e=>e.parentID==null);if(c.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let l=[...c].sort((e,t)=>t.time.updated-e.time.updated),u=new Date;u.setDate(u.getDate()-o);let d=u.getTime(),f=new Set;for(let e of l)e.time.updated>=d&&f.add(e.id);for(let e=0;e!f.has(e.id)),m=new Set;for(let e of p){m.add(e.id);for(let t of s)t.parentID===e.id&&m.add(t.id)}if(m.size===0)return i.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:c.length,freedBytes:0};let h=[];for(let t of m)try{await us(e,t,i),h.push(t),i.debug(`Pruned session`,{sessionId:t})}catch(e){i.warning(`Failed to prune session`,{sessionId:t,error:r(e)})}let g=c.length-p.length;return i.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:0}}async function ps(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await ss(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await cs(e,t.id,r),i=ms(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ms(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function hs(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await gs(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await ps(t,n,{},i);for(let e of d){if(u>=a)break;let n=await gs(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function gs(e,t,n,r,i){let a=await cs(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=_s(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function _s(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function vs(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.logicalKey!=null&&t.push(`Logical Thread: ${e.logicalKey}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` -`)}async function ys(e,t,n,i){let a=vs(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:a}]}});if(t.error!=null){i.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}i.info(`Session summary written via SDK`,{sessionId:e})}catch(t){i.warning(`SDK prompt writeback failed`,{sessionId:e,error:r(t)})}}async function bs(e){let{bootstrapLogger:t,reactionCtx:n,githubClient:r,agentSuccess:o,attachmentResult:s,serverHandle:c,detectedOpencodeVersion:l}=e;try{if(s!=null){let e=i({phase:`attachment-cleanup`});await Wo(s.tempFiles,e)}n!=null&&r!=null&&await lr(r,n,o,i({phase:`cleanup`}));let e=i({phase:`prune`}),t=re();if(c!=null){let n=J(t),r=await fs(c.client,n,ds,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let u=ne(),d=i({phase:`cache-save`}),f=L.join(t,`.git`,`opencode`);await de({components:u,runId:D(),logger:d,storagePath:k(),authPath:fe(),projectIdPath:f,opencodeVersion:l})&&a(_.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(c!=null)try{c.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}const xs=L.join(Ne.homedir(),`.cache`,`fro-bot-dedup`);function Ss(e){return e.replaceAll(`/`,`-`)}function Cs(e,t){let n=Ss(e);return L.join(xs,`${n}-${t.entityType}-${t.entityNumber}`)}function ws(e,t){return`${ee}-${Ss(e)}-${t.entityType}-${t.entityNumber}-`}function Ts(e,t,n){return`${ws(e,t)}${n}`}async function Es(e,t,n,i=le){let a=Cs(e,t),o=L.join(a,`sentinel.json`),s=ws(e,t);try{if(await I.rm(a,{recursive:!0,force:!0}),await I.mkdir(a,{recursive:!0}),await i.restoreCache([a],s,[])==null)return null;let e=await I.readFile(o,`utf8`);return JSON.parse(e)}catch(e){return n.debug(`Dedup marker restore failed; proceeding without marker`,{error:r(e),entityType:t.entityType,entityNumber:t.entityNumber}),null}}async function Ds(e,t,n,i,a=le){let o=Cs(e,t),s=L.join(o,`sentinel.json`),c=Ts(e,t,n.runId);try{return await I.mkdir(o,{recursive:!0}),await I.writeFile(s,JSON.stringify(n),`utf8`),await a.saveCache([o],c),!0}catch(e){return r(e).toLowerCase().includes(`already exists`)?!0:(i.debug(`Dedup marker save failed`,{error:r(e),entityType:t.entityType,entityNumber:t.entityNumber,saveKey:c}),!1)}}const Os=new Set([`pull_request`,`issues`]);function ks(e){return e.target==null||!Os.has(e.eventType)?null:e.eventType===`pull_request`&&e.target.kind===`pr`?{entityType:`pr`,entityNumber:e.target.number}:e.eventType===`issues`&&e.target.kind===`issue`?{entityType:`issue`,entityNumber:e.target.number}:null}async function As(e,t,n,r,a=i({phase:`dedup`}),o){let s=ks(t);if(e===0)return{shouldProceed:!0,entity:s};if(s==null)return{shouldProceed:!0,entity:null};let c=await Es(n,s,a,o);if(c==null||c.runId===t.runId)return{shouldProceed:!0,entity:s};let l=new Date(c.timestamp).getTime();if(Number.isNaN(l))return a.warning(`Dedup marker timestamp is invalid; proceeding without dedup`,{markerTimestamp:c.timestamp}),{shouldProceed:!0,entity:s};let u=Date.now()-l;return u<-6e4?(a.warning(`Dedup marker timestamp is too far in the future; proceeding without dedup`,{markerTimestamp:c.timestamp,markerAge:u}),{shouldProceed:!0,entity:s}):Math.max(0,u)>e?{shouldProceed:!0,entity:s}:(a.info(`Skipping duplicate trigger within dedup window`,{eventType:t.eventType,action:t.action,runId:t.runId,markerRunId:c.runId,markerTimestamp:c.timestamp,dedupWindow:e,entityType:s.entityType,entityNumber:s.entityNumber}),Be({sessionId:null,cacheStatus:`miss`,duration:Date.now()-r}),{shouldProceed:!1,entity:s})}async function js(e,t,n,r=i({phase:`dedup`}),a){await Ds(n,t,{timestamp:new Date().toISOString(),runId:e.runId,action:e.action??`unknown`,eventType:e.eventType,entityType:t.entityType,entityNumber:t.entityNumber},r,a)}async function Ms(e,t,n,r,o,s){let c={context:t.agentContext,customPrompt:e.inputs.prompt,cacheStatus:n.cacheStatus,sessionContext:{recentSessions:r.recentSessions,priorWorkContext:r.priorWorkContext},triggerContext:t.triggerResult.context,fileParts:r.attachmentResult?.fileParts},l=N.env.SKIP_AGENT_EXECUTION===`true`,u=Date.now(),d;if(l)e.logger.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),d={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let t=i({phase:`execution`});t.info(`Starting OpenCode execution`,{logicalKey:r.logicalKey?.key??null,continueSessionId:r.continueSessionId});let a=await er(c,t,{agent:e.inputs.agent,model:e.inputs.model,timeoutMs:e.inputs.timeoutMs,omoProviders:e.inputs.omoProviders,continueSessionId:r.continueSessionId??void 0,sessionTitle:r.sessionTitle??void 0},n.serverHandle),o=a.sessionId;if(o==null){let e=i({phase:`session`}),t=await ls(n.serverHandle.client,r.normalizedWorkspace,u,e);t!=null&&(o=t.session.id,e.debug(`Identified session from execution`,{sessionId:o}))}d={...a,sessionId:o},t.info(`Completed OpenCode execution`,{success:d.success,sessionId:d.sessionId,logicalKey:r.logicalKey?.key??null})}d.sessionId!=null&&(a(_.SESSION_ID,d.sessionId),o.addSessionCreated(d.sessionId)),d.tokenUsage!=null&&o.setTokenUsage(d.tokenUsage,d.model,d.cost);for(let e of d.prsCreated)o.addPRCreated(e);for(let e of d.commitsCreated)o.addCommitCreated(e);for(let e=0;e`)}async function Fs(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:r(e)}),null}}async function Is(e,t,n,i){let a=[],o=1;for(;o<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:o});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;a.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:Ps(t,e.body??``,n)})}if(r.length<100)break;o++}catch(e){i.warning(`Failed to fetch comments page`,{target:t,page:o,error:r(e)});break}return a}async function Ls(e,t,n,i){try{let r=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` +`)}var Oi=class extends Error{constructor(e,t,n){super(Di(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},ki=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Ai=[`query`,`method`,`url`],ji=/\/api\/v3\/?$/;function Mi(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Ai.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>ki.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return ji.test(a)&&(i.url=a.replace(ji,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Oi(i,t,e.data)}return e.data.data})}function Ni(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Mi(n,e,t),{defaults:Ni.bind(null,n),endpoint:n.endpoint})}Ni(Ti,{headers:{"user-agent":`octokit-graphql.js/${Ei} ${V()}`},method:`POST`,url:`/graphql`});function Pi(e){return Ni(e,{method:`POST`,url:`/graphql`})}var Fi=`(?:[a-zA-Z0-9_-]+)`,Ii=`\\.`,Li=RegExp(`^${Fi}${Ii}${Fi}${Ii}${Fi}$`),Ri=Li.test.bind(Li);async function zi(e){let t=Ri(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Bi(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Vi(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Bi(e),t(i)}var Hi=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(zi.bind(null,e),{hook:Vi.bind(null,e)})};const Ui=`7.0.6`,Wi=()=>{},Gi=console.warn.bind(console),Ki=console.error.bind(console);function qi(e={}){return typeof e.debug!=`function`&&(e.debug=Wi),typeof e.info!=`function`&&(e.info=Wi),typeof e.warn!=`function`&&(e.warn=Gi),typeof e.error!=`function`&&(e.error=Ki),e}const Ji=`octokit-core.js/${Ui} ${V()}`;var Yi=class{static VERSION=Ui;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Ar.Collection,n={baseUrl:Ti.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ji}`:Ji,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=Ti.defaults(n),this.graphql=Pi(this.request).defaults(n),this.log=qi(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Hi(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=ia(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:sa(e,t,n,r)})}Object.assign(oa,{iterator:aa});function ca(e){return{paginate:Object.assign(oa.bind(null,e),{iterator:aa.bind(null,e)})}}ca.VERSION=ra,new fr;const la=xr(),ua={baseUrl:la,request:{agent:vr(la),fetch:br(la)}},da=Yi.plugin(ta,ca).defaults(ua);function fa(e,t){let n=Object.assign({},t||{}),r=_r(e,n);return r&&(n.auth=r),n}const pa=new fr;function ma(e,t,...n){return new(da.plugin(...n))(fa(e,t))}var K=C(ue(),1),ha=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})},ga=class{constructor(e,t,n){if(e<1)throw Error(`max attempts should be greater than or equal to 1`);if(this.maxAttempts=e,this.minSeconds=Math.floor(t),this.maxSeconds=Math.floor(n),this.minSeconds>this.maxSeconds)throw Error(`min seconds should be less than or equal to max seconds`)}execute(e,t){return ha(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},q=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})},_a=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const va=process.platform===`win32`;process.platform;function ya(e,t,n,r){return q(this,void 0,void 0,function*(){return t||=F.join(Pa(),ye.randomUUID()),yield s(F.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new ga(3,Fa(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Fa(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>q(this,void 0,void 0,function*(){return yield ba(e,t||``,n,r)}),e=>!(e instanceof _a&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function ba(e,t,n,r){return q(this,void 0,void 0,function*(){if(P.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new _a(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=Ce.promisify(Fe.pipeline),s=Fa(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),c=!1;try{return yield o(s,P.createWriteStream(t)),j(`download complete`),c=!0,t}finally{if(!c){j(`download failed`);try{yield v(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function xa(e,t){return q(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Oa(t),j(`Checking tar --version`);let r=``;yield M(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],m()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return va&&i&&(a.push(`--force-local`),o=t.replace(/\\/g,`/`),s=e.replace(/\\/g,`/`)),i&&(a.push(`--warning=no-unknown-keyword`),a.push(`--overwrite`)),a.push(`-C`,o,`-f`,s),yield M(`tar`,a),t})}function Sa(e,t){return q(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Oa(t),va?yield Ca(e,t):yield wa(e,t),t})}function Ca(e,t){return q(this,void 0,void 0,function*(){let n=e.replace(/'/g,`''`).replace(/"|\n|\r/g,``),r=t.replace(/'/g,`''`).replace(/"|\n|\r/g,``),i=yield b(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield M(`"${i}"`,e)}else{let e=[`-NoLogo`,`-Sta`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ;`,`if ((Get-Command -Name Expand-Archive -Module Microsoft.PowerShell.Archive -ErrorAction Ignore)) { Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force }`,`else {[System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`].join(` `)],t=yield b(`powershell`,!0);j(`Using powershell at path: ${t}`),yield M(`"${t}"`,e)}})}function wa(e,t){return q(this,void 0,void 0,function*(){let n=yield b(`unzip`,!0),r=[e];m()||r.unshift(`-q`),r.unshift(`-o`),yield M(`"${n}"`,r,{cwd:t})})}function Ta(e,t,n,r){return q(this,void 0,void 0,function*(){if(n=K.clean(n)||n,r||=_e.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!P.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield ka(t,n,r);for(let t of P.readdirSync(e))yield y(F.join(e,t),i,{recursive:!0});return Aa(t,n,r),i})}function Ea(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=_e.arch(),ja(t)||(t=Ma(Da(e,n),t));let r=``;if(t){t=K.clean(t)||``;let i=F.join(Na(),e,t,n);j(`checking cache: ${i}`),P.existsSync(i)&&P.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Da(e,t){let n=[];t||=_e.arch();let r=F.join(Na(),e);if(P.existsSync(r)){let e=P.readdirSync(r);for(let i of e)if(ja(i)){let e=F.join(r,i,t||``);P.existsSync(e)&&P.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Oa(e){return q(this,void 0,void 0,function*(){return e||=F.join(Pa(),ye.randomUUID()),yield s(e),e})}function ka(e,t,n){return q(this,void 0,void 0,function*(){let r=F.join(Na(),e,K.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield v(r),yield v(i),yield s(r),r})}function Aa(e,t,n){let r=`${F.join(Na(),e,K.clean(t)||t,n||``)}.complete`;P.writeFileSync(r,``),j(`finished caching tool`)}function ja(e){let t=K.clean(e)||``;j(`isExplicit: ${t}`);let n=K.valid(t)!=null;return j(`explicit? ${n}`),n}function Ma(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>K.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(K.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Na(){let e=process.env.RUNNER_TOOL_CACHE||``;return Se(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function Pa(){let e=process.env.RUNNER_TEMP||``;return Se(e,`Expected RUNNER_TEMP to be defined`),e}function Fa(e,t){let n=global[e];return n===void 0?t:n}function Ia(e){let t;try{t=JSON.parse(e)}catch(e){throw e instanceof SyntaxError?Error(`Invalid auth-json format: ${e.message}`):e}if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`auth-json must be a JSON object`);return t}async function La(e,t,n){let r=L.join(t,`auth.json`);await I.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await I.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ra(){let e=N.platform,t=N.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function za(e,t){return`https://github.com/oven-sh/bun/releases/download/bun-${e.startsWith(`v`)?e:`v${e}`}/${`bun-${t.os}-${t.arch}${t.ext}`}`}async function Ba(e,t,n,i,a=pe){let o=Ra(),s=t.find(`bun`,a,o.arch);if(s.length>0)return e.info(`Bun found in cache`,{version:a,path:s}),i(s),await Ha(s),{path:s,version:a,cached:!0};e.info(`Downloading Bun`,{version:a});let c=za(a,o);try{let r=await t.downloadTool(c);if(N.platform!==`win32`&&!await Ua(r,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let s=await Va(await t.extractZip(r),t),l=ke.dirname(s);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,a,o.arch);return i(u),await Ha(u),e.info(`Bun installed`,{version:a,path:u}),{path:u,version:a,cached:!1}}catch(e){let t=r(e);throw Error(`Failed to install Bun ${a}: ${t}`)}}async function Va(e,t){for(let n of await Oe.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=ke.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Va(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Va(i,t)}throw Error(`Could not find executable: bun`)}async function Ha(e){let t=e=>N.platform===`win32`?`${e}.exe`:e,n=ke.join(e,t(`bun`));try{await Oe.symlink(n,ke.join(e,t(`bunx`)))}catch(e){let t=typeof e==`object`?e.code:void 0;if(t!==`EEXIST`&&t!==`EPERM`&&t!==`EACCES`)throw e}}async function Ua(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function Wa(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Ga(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),ma(t,{log:Wa(n)})}async function Ka(e,t){try{let{data:n}=await e.rest.users.getAuthenticated();return t.debug(`Authenticated as`,{login:n.login,type:n.type}),n.login}catch{return t.debug(`Failed to get authenticated user, may be app token`),`fro-bot[bot]`}}async function qa(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};N.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Ka(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ja(e,t){let n=await t.getExecOutput(`git`,[`config`,e],{ignoreReturnCode:!0,silent:!0});return n.exitCode===0&&n.stdout.trim().length>0?n.stdout.trim():null}async function Ya(e,t,n,r){let i=await Ja(`user.name`,r),a=await Ja(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}const Xa=new Set([`__proto__`,`prototype`,`constructor`]);function Za(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Qa(e,t){let n=Object.create(null);for(let[t,r]of Object.entries(e))Xa.has(t)||(n[t]=r);for(let[e,r]of Object.entries(t)){if(Xa.has(e))continue;let t=n[e];Za(r)&&Za(t)?n[e]=Qa(t,r):n[e]=r}return n}async function $a(e,t,n){let r=JSON.parse(e);if(!Za(r))throw Error(`omo-config must be a JSON object (non-null, non-array)`);let i=r;await I.mkdir(t,{recursive:!0});let a=L.join(t,`oh-my-opencode.json`),o={};try{let e=await I.readFile(a,`utf8`),t=JSON.parse(e);typeof t==`object`&&t&&!Array.isArray(t)&&(o=t)}catch(e){n.debug(`Using empty base oMo config`,{path:a,error:String(e)})}let s=Qa(o,i);await I.writeFile(a,JSON.stringify(s,null,2)),n.info(`Wrote oMo config`,{path:a,keyCount:Object.keys(i).length})}async function eo(e,t,n={}){let{logger:i,execAdapter:a}=t,{claude:o=`no`,copilot:s=`no`,gemini:c=`no`,openai:l=`no`,opencodeZen:u=`no`,zaiCodingPlan:d=`no`,kimiForCoding:f=`no`}=n;i.info(`Installing Oh My OpenAgent plugin`,{version:e,claude:o,copilot:s,gemini:c,openai:l,opencodeZen:u,zaiCodingPlan:d,kimiForCoding:f});let p=``,m=[`oh-my-openagent@${e}`,`install`,`--no-tui`,`--skip-auth`,`--claude=${o}`,`--copilot=${s}`,`--gemini=${c}`,`--openai=${l}`,`--opencode-zen=${u}`,`--zai-coding-plan=${d}`,`--kimi-for-coding=${f}`];try{let t=await a.exec(`bunx`,m,{listeners:{stdout:e=>{p+=e.toString()},stderr:e=>{p+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-openagent install returned exit code ${t}`;return i.error(e,{output:p.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${p.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(p),r=n!=null&&n[1]!=null?n[1]:e;return i.info(`oMo plugin installed`,{version:r}),{installed:!0,version:r,error:null}}catch(e){let t=r(e),n=p.length>0?`${t}\nOutput: ${p.slice(0,500)}`:t;return i.error(`Failed to run oMo installer`,{error:t,output:p.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-openagent install failed: ${n}`}}}const to=`opencode`,no=g;function ro(){let e=Ne.platform(),t=Ne.arch(),n={darwin:`darwin`,linux:`linux`,win32:`windows`},r={x64:`x64`,arm64:`arm64`},i=e===`win32`||e===`darwin`?`.zip`:`.tar.gz`;return{os:n[e]??`linux`,arch:r[t]??`x64`,ext:i}}function io(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function ao(e,t,n,r){if(N.platform===`win32`)return!0;try{let{stdout:i}=await r.getExecOutput(`file`,[e],{silent:!0}),a=(t===`.zip`?[`Zip archive`,`ZIP`]:[`gzip`,`tar`,`compressed`]).some(e=>i.includes(e));return a||n.warning(`Download validation failed`,{output:i.trim()}),a}catch{return n.debug(`Could not validate download (file command unavailable)`),!0}}async function oo(e,t,n,i,a=no){let o=ro(),s=n.find(to,e,o.arch);if(s.length>0)return t.info(`OpenCode found in cache`,{version:e,path:s}),{path:s,version:e,cached:!0};try{return await so(e,o,t,n,i)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:a,error:r(n)})}if(e!==a)try{let e=await so(a,o,t,n,i);return t.info(`Installed fallback version`,{version:a}),e}catch(t){throw Error(`Failed to install OpenCode (tried ${e} and ${a}): ${r(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function so(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=io(e,t),o=await r.downloadTool(a);if(!await ao(o,t.ext,n,i))throw Error(`Downloaded archive appears corrupted`);n.info(`Extracting OpenCode`);let s=t.ext===`.zip`?await r.extractZip(o):await r.extractTar(o);n.info(`Caching OpenCode`);let c=await r.cacheDir(s,to,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function co(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const lo={restoreCache:async(e,t,n)=>T(e,t,n),saveCache:async(e,t)=>oe(e,t)};function uo(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${me}-${t}-oc-${n}-omo-${r}`}function fo(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${me}-${t}-oc-${n}-omo-${r}-`]}async function po(e){let{logger:t,os:n,opencodeVersion:i,omoVersion:a,toolCachePath:o,bunCachePath:s,omoConfigPath:c,cacheAdapter:l=lo}=e,u=uo({os:n,opencodeVersion:i,omoVersion:a}),d=fo({os:n,opencodeVersion:i,omoVersion:a}),f=[o,s,c];t.info(`Restoring tools cache`,{primaryKey:u,restoreKeys:[...d],paths:f});try{let e=await l.restoreCache(f,u,[...d]);return e==null?(t.info(`Tools cache miss - will install tools`),{hit:!1,restoredKey:null}):(t.info(`Tools cache restored`,{restoredKey:e}),{hit:!0,restoredKey:e})}catch(e){return t.warning(`Tools cache restore failed`,{error:r(e)}),{hit:!1,restoredKey:null}}}async function mo(e){let{logger:t,os:n,opencodeVersion:i,omoVersion:a,toolCachePath:o,bunCachePath:s,omoConfigPath:c,cacheAdapter:l=lo}=e,u=uo({os:n,opencodeVersion:i,omoVersion:a}),d=[o,s,c];t.info(`Saving tools cache`,{saveKey:u,paths:d});try{return await l.saveCache(d,u),t.info(`Tools cache saved`,{saveKey:u}),!0}catch(e){return e instanceof Error&&e.message.includes(`already exists`)?(t.info(`Tools cache key already exists, skipping save`),!0):(t.warning(`Tools cache save failed`,{error:r(e)}),!1)}}function ho(){return{find:Ea,downloadTool:ya,extractTar:xa,extractZip:Sa,cacheDir:Ta}}function go(){return{exec:M,getExecOutput:t}}async function _o(t,n){let a=Date.now(),o=i({component:`setup`}),s=ho(),l=go();try{o.info(`Starting setup`,{version:t.opencodeVersion});let i;try{i=Ia(t.authJson)}catch(e){return c(`Invalid auth-json: ${r(e)}`),null}let u=t.opencodeVersion;if(u===`latest`)try{u=await co(o)}catch(e){o.warning(`Failed to get latest version, using fallback`,{error:r(e)}),u=no}let f=t.omoVersion,m=N.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,h=Ae(m,`opencode`),g=Ae(m,`bun`),_=Ae(Pe(),`.config`,`opencode`),v=se(),y=await po({logger:o,os:v,opencodeVersion:u,omoVersion:f,toolCachePath:h,bunCachePath:g,omoConfigPath:_}),b=y.hit?`hit`:`miss`,x,S=!1,C=null;if(y.hit){let e=s.find(`opencode`,u);e.length>0?(x={path:e,version:u,cached:!0},o.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):o.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:y.restoredKey})}if(x==null)try{x=await oo(u,o,s,l)}catch(e){return c(`Failed to install OpenCode: ${r(e)}`),null}let w=!1;try{await Ba(o,s,l,p,pe),w=!0}catch(e){o.warning(`Bun installation failed, oMo will be unavailable`,{error:r(e)})}if(w){if(t.omoConfig!=null)try{await $a(t.omoConfig,_,o)}catch(e){o.warning(`Failed to write omo-config, continuing without custom config`,{error:r(e)})}let e=await eo(f,{logger:o,execAdapter:l},t.omoProviders);e.installed?(o.info(`oMo installed`,{version:e.version}),S=!0):o.warning(`oMo installation failed, continuing without oMo`,{error:e.error??`unknown error`}),C=e.error}let T={autoupdate:!1};if(t.opencodeConfig!=null){let e;try{e=JSON.parse(t.opencodeConfig)}catch{return c(`opencode-config must be valid JSON`),null}if(typeof e!=`object`||!e||Array.isArray(e))return c(`opencode-config must be a JSON object`),null;Object.assign(T,e)}e(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(T)),y.hit||await mo({logger:o,os:v,opencodeVersion:u,omoVersion:f,toolCachePath:h,bunCachePath:g,omoConfigPath:_}),p(x.path),d(`opencode-path`,x.path),d(`opencode-version`,x.version),o.info(`OpenCode ready`,{version:x.version,cached:x.cached});let E=ma(n),D=await qa(E,null,n,o);e(`GH_TOKEN`,n),o.info(`GitHub CLI configured`),await Ya(E,D.botLogin,o,l);let O=Ae(ie(),`opencode`),k=await La(i,O,o);d(`auth-json-path`,k),o.info(`auth.json populated`,{path:k});let ee=Date.now()-a,te={opencodePath:x.path,opencodeVersion:x.version,ghAuthenticated:D.authenticated,omoInstalled:S,omoError:C,toolsCacheStatus:b,duration:ee};return o.info(`Setup complete`,{duration:ee}),te}catch(e){let t=r(e);return o.error(`Setup failed`,{error:t}),c(t),null}}function vo(e){return{success:!0,data:e}}function yo(e){return{success:!1,error:e}}const bo=[`OWNER`,`MEMBER`,`COLLABORATOR`];async function xo(e,t){try{let{client:n,server:r}=await pn({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),vo({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),yo(Error(`Server bootstrap failed: ${n}`))}}async function So(e,t){let n=e??`opencode`;try{let e=``;await M(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function Co(e){let{logger:t,opencodeVersion:n}=e,r=N.env.OPENCODE_PATH??null,i=await So(r,t);if(i.available&&i.version!=null)return t.info(`OpenCode already available`,{version:i.version}),{path:r??`opencode`,version:i.version,didSetup:!1};t.info(`OpenCode not found, running auto-setup`,{requestedVersion:n});let a=await _o({opencodeVersion:n,authJson:e.authJson,appId:null,privateKey:null,opencodeConfig:e.opencodeConfig,omoConfig:null,omoVersion:e.omoVersion,omoProviders:e.omoProviders},e.githubToken);if(a==null)throw Error(`Auto-setup failed: runSetup returned null`);return p(a.opencodePath),N.env.OPENCODE_PATH=a.opencodePath,t.info(`Auto-setup completed`,{version:a.opencodeVersion,path:a.opencodePath}),{path:a.opencodePath,version:a.opencodeVersion,didSetup:!0}}async function wo(e,t){let n={repo:e.agentContext.repo,commentId:e.agentContext.commentId,issueNumber:e.agentContext.issueNumber,issueType:e.agentContext.issueType,botLogin:e.botLogin},r=i({phase:`acknowledgment`});return await ar(e.githubClient,n,r),t.debug(`Acknowledgment phase completed`),n}function To(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function Eo(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function Do(e){let t=e.trim(),n=t.indexOf(`/`);if(n===-1)throw Error(`Invalid model format: "${e}". Expected "provider/model" (e.g., "anthropic/claude-sonnet-4-20250514")`);let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();if(r.length===0)throw Error(`Invalid model format: "${e}". Provider cannot be empty.`);if(i.length===0)throw Error(`Invalid model format: "${e}". Model ID cannot be empty.`);return{providerID:r,modelID:i}}function Oo(e,t=`timeout`){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a non-negative integer, received: ${e}`);let r=Number.parseInt(n,10);if(Number.isNaN(r)||r<0)throw Error(`${t} must be a non-negative integer, received: ${e}`);return r}const ko=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function Ao(e){let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),n=`no`,r=`no`,i=`no`,a=`no`,o=`no`,s=`no`,c=`no`;for(let e of t){if(!ko.includes(e))throw Error(`Invalid omo-providers value: "${e}". Valid values: ${ko.join(`, `)}`);switch(e){case`claude`:n=`yes`;break;case`claude-max20`:n=`max20`;break;case`copilot`:r=`yes`;break;case`gemini`:i=`yes`;break;case`openai`:a=`yes`;break;case`opencode-zen`:o=`yes`;break;case`zai-coding-plan`:s=`yes`;break;case`kimi-for-coding`:c=`yes`;break}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s,kimiForCoding:c}}function jo(){try{let e=A(`github-token`,{required:!0}).trim();if(e.length===0)return yo(Error(`github-token is required but was not provided`));let t=A(`auth-json`,{required:!0}).trim();if(t.length===0)return yo(Error(`auth-json is required but was not provided`));To(t,`auth-json`);let r=A(`prompt`).trim(),i=r.length>0?r:null,a=A(`session-retention`).trim(),o=a.length>0?Eo(a,`session-retention`):50,s=A(`s3-backup`).trim().toLowerCase()===`true`,c=A(`s3-bucket`).trim(),l=c.length>0?c:null,u=A(`aws-region`).trim(),d=u.length>0?u:null,f=A(`agent`).trim(),p=f.length>0?f:w,m=A(`model`).trim(),h=m.length>0?Do(m):null,_=A(`timeout`).trim(),v=_.length>0?Oo(_):n,y=A(`opencode-version`).trim(),b=y.length>0?y:g,x=A(`skip-cache`).trim().toLowerCase()===`true`,S=A(`omo-version`).trim(),C=S.length>0?S:he,T=A(`omo-providers`).trim(),E=Ao(T.length>0?T:``),D=A(`opencode-config`).trim(),O=D.length>0?D:null,k=A(`dedup-window`).trim(),ee=k.length>0?Oo(k,`dedup-window`):ge;if(O!=null){To(O,`opencode-config`);let e=JSON.parse(O);if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Input 'opencode-config' must be a JSON object`)}return vo({githubToken:e,authJson:t,prompt:i,sessionRetention:o,s3Backup:s,s3Bucket:l,awsRegion:d,agent:p,model:h,timeoutMs:v,opencodeVersion:b,skipCache:x,omoVersion:C,omoProviders:E,opencodeConfig:O,dedupWindow:ee})}catch(e){return yo(e instanceof Error?e:Error(String(e)))}}async function Mo(e){let t=jo();if(!t.success)return c(`Invalid inputs: ${t.error.message}`),null;let n=t.data,r=i({phase:`main`});r.info(`Action inputs parsed`,{sessionRetention:n.sessionRetention,s3Backup:n.s3Backup,hasGithubToken:n.githubToken.length>0,hasPrompt:n.prompt!=null,agent:n.agent,hasModelOverride:n.model!=null,timeoutMs:n.timeoutMs});let o=await Co({logger:r,opencodeVersion:n.opencodeVersion,githubToken:n.githubToken,authJson:n.authJson,omoVersion:n.omoVersion,omoProviders:n.omoProviders,opencodeConfig:n.opencodeConfig});return o.didSetup?r.info(`OpenCode auto-setup completed`,{version:o.version}):r.info(`OpenCode already available`,{version:o.version}),a(_.OPENCODE_VERSION,o.version),e.debug(`Bootstrap phase completed`,{opencodeVersion:o.version}),{inputs:n,logger:r,opencodeResult:o}}const No=/^[0-9a-f]{40}$/i;function Po(){return{exec:M,getExecOutput:t}}async function Fo(e){let{workspacePath:t,logger:n,execAdapter:i=Po()}=e,a=L.join(t,`.git`),o=L.join(a,`opencode`);try{let e=(await I.readFile(o,`utf8`)).trim();if(e.length>0){if(No.test(e))return n.debug(`Project ID loaded from cache`,{projectId:e}),{projectId:e,source:`cached`};n.warning(`Invalid cached project ID format, regenerating`,{cachedId:e})}}catch(e){n.debug(`No cached project ID found`,{error:r(e)})}try{let e=await I.readFile(a,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};a=L.resolve(t,n[1]),o=L.join(a,`opencode`)}catch(e){if((typeof e==`object`?e.code:void 0)!==`EISDIR`)return{projectId:null,source:`error`,error:`Not a git repository`}}try{let{stdout:e,exitCode:a}=await i.getExecOutput(`git`,[`rev-list`,`--max-parents=0`,`--all`],{cwd:t,silent:!0});if(a!==0||e.trim().length===0)return{projectId:null,source:`error`,error:`No commits found in repository`};let s=e.trim().split(` +`).map(e=>e.trim()).filter(e=>e.length>0).sort();if(s.length===0)return{projectId:null,source:`error`,error:`No root commits found`};let c=s[0];try{await I.writeFile(o,c,{encoding:`utf8`,flag:`wx`}),n.info(`Project ID generated and cached`,{projectId:c,source:`generated`})}catch(e){(typeof e==`object`?e.code:void 0)===`EEXIST`?n.debug(`Project ID file already written by concurrent process, skipping`,{projectId:c}):n.warning(`Failed to cache project ID (continuing)`,{error:r(e)})}return{projectId:c,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:r(e)}}}async function Io(e){let t=ne(),n=i({phase:`cache`}),r=re(),a=L.join(r,`.git`,`opencode`),o=await ae({components:t,logger:n,storagePath:k(),authPath:fe(),projectIdPath:a,opencodeVersion:e.opencodeResult.version}),s=o.corrupted?`corrupted`:o.hit?`hit`:`miss`;e.logger.info(`Cache restore completed`,{cacheStatus:s,key:o.key});let l=await Fo({workspacePath:r,logger:n});l.source===`error`?n.warning(`Failed to generate project ID (continuing)`,{error:l.error}):n.debug(`Project ID ready`,{projectId:l.projectId,source:l.source});let u=i({phase:`server-bootstrap`}),d=await xo(new AbortController().signal,u);if(!d.success)return c(`OpenCode server bootstrap failed: ${d.error.message}`),null;let f=d.data;return u.info(`SDK server bootstrapped successfully`),{cacheResult:o,cacheStatus:s,serverHandle:f}}const Lo={markdownImage:/!\[([^\]]*)\]\((https:\/\/github\.com\/user-attachments\/assets\/[^)]+)\)/gi,markdownLink:/\[([^\]]+)\]\((https:\/\/github\.com\/user-attachments\/files\/[^)]+)\)/gi,htmlImage:/]*src=["'](https:\/\/github\.com\/user-attachments\/assets\/[^"']+)["'][^>]*>/gi};function Ro(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function zo(e){let t=[],n=new Set;return Ro(Lo.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&Dn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Ro(Lo.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&Dn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Ro(Lo.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&Dn(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),Lo.htmlImage.lastIndex=0,t}function Bo(e,t,n){try{let r=new URL(e).pathname.split(`/`).at(-1);if(r!=null&&/\.[a-z0-9]+$/i.test(r))return r;if(t.trim().length>0){let e=t.replaceAll(/[^\w.-]/g,`_`).slice(0,50);return e.trim().length>0?e:`attachment_${n+1}`}return`attachment_${n+1}`}catch{return`attachment_${n+1}`}}const Vo={maxFiles:5,maxFileSizeBytes:5*1024*1024,maxTotalSizeBytes:15*1024*1024,allowedMimeTypes:[`image/png`,`image/jpeg`,`image/gif`,`image/webp`,`image/svg+xml`,`text/plain`,`text/markdown`,`text/csv`,`application/json`,`application/pdf`]},Ho=[`github.com`,`githubusercontent.com`];async function Uo(e,t,n,i,a){a.debug(`Downloading attachment`,{url:e.url});try{let r=await fetch(e.url,{headers:{Authorization:`Bearer ${n}`,Accept:`*/*`,"User-Agent":`fro-bot-agent`},redirect:`manual`}),o=r;if(r.status>=300&&r.status<400){let t=r.headers.get(`location`);if(t==null)return a.warning(`Redirect without location`,{url:e.url}),null;let n=new URL(t);if(!Ho.some(e=>n.hostname===e||n.hostname.endsWith(`.${e}`)))return a.warning(`Redirect to non-GitHub host blocked`,{url:e.url,redirectTo:n.hostname}),null;o=await fetch(t,{headers:{Accept:`*/*`,"User-Agent":`fro-bot-agent`},redirect:`follow`})}if(!o.ok)return a.warning(`Attachment download failed`,{url:e.url,status:o.status}),null;let s=o.headers.get(`content-length`);if(s!=null){let t=Number.parseInt(s,10);if(t>i.maxFileSizeBytes)return a.warning(`Attachment exceeds size limit (Content-Length)`,{url:e.url,size:t,limit:i.maxFileSizeBytes}),null}let c=we.from(await o.arrayBuffer());if(c.length>i.maxFileSizeBytes)return a.warning(`Attachment exceeds size limit`,{url:e.url,size:c.length,limit:i.maxFileSizeBytes}),null;let l=o.headers.get(`content-type`)??`application/octet-stream`,u=Bo(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await I.mkdtemp(L.join(Me.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=L.join(p,m);return await I.writeFile(h,c),a.debug(`Attachment downloaded`,{filename:u,mime:f,sizeBytes:c.length,tempPath:h}),{url:e.url,filename:u,mime:f,sizeBytes:c.length,tempPath:h}}catch(t){return a.warning(`Attachment download error`,{url:e.url,error:r(t)}),null}}async function Wo(e,t,n=Vo,r){return Promise.all(e.map(async(e,i)=>Uo(e,i,t,n,r)))}async function Go(e,t){for(let n of e)try{await I.unlink(n);let e=L.dirname(n);await I.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:r(e)})}}function Ko(e){return e.map(e=>({type:`file`,mime:e.mime,url:De(e.tempPath).toString(),filename:e.filename}))}function qo(e,t,n){let r=e,i=new Set(n.map(e=>e.filename));for(let e of t){let t=n.find(e=>i.has(e.filename));t!=null&&(r=r.replace(e.originalMarkdown,`@${t.filename}`))}return r}function Jo(e,t,n,r){return{processed:n,skipped:r,modifiedBody:qo(e,t,n),fileParts:Ko(n),tempFiles:n.map(e=>e.tempPath)}}function Yo(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function Xo(e,t=Vo,n){let r=[],i=[],a=0;for(let o of e)if(o!=null){if(r.length>=t.maxFiles){i.push({url:o.url,reason:`Exceeds max file count (${t.maxFiles})`}),n.debug(`Attachment skipped: max count`,{url:o.url});continue}if(o.sizeBytes>t.maxFileSizeBytes){i.push({url:o.url,reason:`File too large (${Yo(o.sizeBytes)} > ${Yo(t.maxFileSizeBytes)})`}),n.debug(`Attachment skipped: too large`,{url:o.url,size:o.sizeBytes});continue}if(a+o.sizeBytes>t.maxTotalSizeBytes){i.push({url:o.url,reason:`Would exceed total size limit (${Yo(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!Zo(o.mime,t.allowedMimeTypes)){i.push({url:o.url,reason:`MIME type not allowed: ${o.mime}`}),n.debug(`Attachment skipped: MIME type`,{url:o.url,mime:o.mime});continue}a+=o.sizeBytes,r.push({filename:o.filename,mime:o.mime,sizeBytes:o.sizeBytes,tempPath:o.tempPath}),n.info(`Attachment validated`,{filename:o.filename,mime:o.mime,sizeBytes:o.sizeBytes})}return{validated:r,skipped:i}}function Zo(e,t){let[n]=e.split(`/`);for(let r of t)if(r===e||r.endsWith(`/*`)&&n!=null&&n===r.slice(0,-2))return!0;return!1}function J(e){let t=L.resolve(e);return t.endsWith(L.sep)&&t.length>1?t.slice(0,-1):t}const Qo=e=>typeof e==`object`&&!!e,Y=e=>typeof e==`string`?e:null,$o=e=>typeof e==`number`?e:null;function es(e){if(Array.isArray(e))return e.filter(Qo).map(e=>({file:Y(e.file)??``,additions:$o(e.additions)??0,deletions:$o(e.deletions)??0}))}function ts(e){return{id:e.id,version:e.version,projectID:e.projectID,directory:e.directory,parentID:e.parentID,title:e.title,time:{created:e.time.created,updated:e.time.updated,compacting:e.time.compacting,archived:e.time.archived},summary:e.summary==null?void 0:{additions:e.summary.additions,deletions:e.summary.deletions,files:e.summary.files,diffs:es(e.summary.diffs)},share:e.share?.url==null?void 0:{url:e.share.url},permission:e.permission==null?void 0:{rules:e.permission.rules},revert:e.revert==null?void 0:{messageID:e.revert.messageID,partID:e.revert.partID,snapshot:e.revert.snapshot,diff:e.revert.diff}}}async function ns(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Qo(e))continue;let t=Y(e.id),n=Y(e.worktree),i=Y(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i,vcs:`git`,time:{created:0,updated:0}})}return r}async function rs(e,t,n){let r=J(t),i=await ns(e,n);for(let e of i){if(J(e.worktree)===r)return e;let t=Y(e.path);if(t!=null&&J(t)===r)return e}return null}function is(e){return e.status===`running`?{status:`running`,input:e.input,time:{start:e.time.start}}:e.status===`error`?{status:`error`,input:e.input,error:e.error,time:{start:e.time.start,end:e.time.end}}:e.status===`pending`?{status:`pending`}:{status:`completed`,input:e.input,output:e.output,title:e.title,metadata:e.metadata,time:{start:e.time.start,end:e.time.end,compacted:e.time.compacted},attachments:void 0}}function as(e){let t={id:e.id,sessionID:e.sessionID,messageID:e.messageID};if(e.type===`text`)return{...t,type:`text`,text:e.text,synthetic:e.synthetic,ignored:e.ignored,time:e.time,metadata:e.metadata};if(e.type===`reasoning`)return{...t,type:`reasoning`,reasoning:e.reasoning??e.text,time:e.time};if(e.type===`tool`)return{...t,type:`tool`,callID:e.callID,tool:e.tool,state:is(e.state),metadata:e.metadata};if(e.type!==`step-finish`)return{...t,type:`text`,text:`text`in e?e.text:``};let n=e;return{...t,type:`step-finish`,reason:n.reason,snapshot:n.snapshot,cost:n.cost,tokens:{input:n.tokens.input,output:n.tokens.output,reasoning:n.tokens.reasoning,cache:{read:n.tokens.cache.read,write:n.tokens.cache.write}}}}function os(e){if(e.role===`user`){let t=e;return{id:t.id,sessionID:t.sessionID,role:`user`,time:{created:t.time.created},summary:t.summary==null?void 0:{title:t.summary.title,body:t.summary.body,diffs:es(t.summary.diffs)??[]},agent:t.agent,model:{providerID:t.model.providerID,modelID:t.model.modelID},system:t.system,tools:t.tools,variant:t.variant}}let t=e;return{id:t.id,sessionID:t.sessionID,role:`assistant`,time:{created:t.time.created,completed:t.time.completed},parentID:t.parentID,modelID:t.modelID,providerID:t.providerID,mode:t.mode,agent:t.agent??``,path:{cwd:t.path.cwd,root:t.path.root},summary:t.summary,cost:t.cost,tokens:{input:t.tokens.input,output:t.tokens.output,reasoning:t.tokens.reasoning,cache:{read:t.tokens.cache.read,write:t.tokens.cache.write}},finish:t.finish,error:t.error?{name:t.error.name,message:Y(t.error.data.message)??``}:void 0}}function ss(e){return[...e.map(e=>{let t=os(`info`in e?e.info:e),n=`parts`in e?e.parts.map(as):void 0;return n==null||n.length===0?t:{...t,parts:n}})].sort((e,t)=>e.time.created-t.time.created)}async function cs(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(ts):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function ls(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?ss(r.data):(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function us(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(ts);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function ds(e,t,n){let r=await e.session.delete({path:{id:t}});if(r.error!=null){n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)});return}n.debug(`Deleted session via SDK`,{sessionID:t})}const fs={maxSessions:50,maxAgeDays:30};async function ps(e,t,n,i){let{maxSessions:a,maxAgeDays:o}=n;if(i.info(`Starting session pruning`,{workspacePath:t,maxSessions:a,maxAgeDays:o}),await rs(e,t,i)==null)return i.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let s=await cs(e,t,i),c=s.filter(e=>e.parentID==null);if(c.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let l=[...c].sort((e,t)=>t.time.updated-e.time.updated),u=new Date;u.setDate(u.getDate()-o);let d=u.getTime(),f=new Set;for(let e of l)e.time.updated>=d&&f.add(e.id);for(let e=0;e!f.has(e.id)),m=new Set;for(let e of p){m.add(e.id);for(let t of s)t.parentID===e.id&&m.add(t.id)}if(m.size===0)return i.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:c.length,freedBytes:0};let h=[];for(let t of m)try{await ds(e,t,i),h.push(t),i.debug(`Pruned session`,{sessionId:t})}catch(e){i.warning(`Failed to prune session`,{sessionId:t,error:r(e)})}let g=c.length-p.length;return i.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:0}}async function ms(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await cs(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await ls(e,t.id,r),i=hs(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function hs(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function gs(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await _s(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await ms(t,n,{},i);for(let e of d){if(u>=a)break;let n=await _s(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function _s(e,t,n,r,i){let a=await ls(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=vs(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function vs(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ys(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.logicalKey!=null&&t.push(`Logical Thread: ${e.logicalKey}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` +`)}async function bs(e,t,n,i){let a=ys(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:a}]}});if(t.error!=null){i.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}i.info(`Session summary written via SDK`,{sessionId:e})}catch(t){i.warning(`SDK prompt writeback failed`,{sessionId:e,error:r(t)})}}async function xs(e){let{bootstrapLogger:t,reactionCtx:n,githubClient:r,agentSuccess:o,attachmentResult:s,serverHandle:c,detectedOpencodeVersion:l}=e;try{if(s!=null){let e=i({phase:`attachment-cleanup`});await Go(s.tempFiles,e)}n!=null&&r!=null&&await dr(r,n,o,i({phase:`cleanup`}));let e=i({phase:`prune`}),t=re();if(c!=null){let n=J(t),r=await ps(c.client,n,fs,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let u=ne(),d=i({phase:`cache-save`}),f=L.join(t,`.git`,`opencode`);await de({components:u,runId:D(),logger:d,storagePath:k(),authPath:fe(),projectIdPath:f,opencodeVersion:l})&&a(_.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(c!=null)try{c.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}const Ss=L.join(Ne.homedir(),`.cache`,`fro-bot-dedup`);function Cs(e){return e.replaceAll(`/`,`-`)}function ws(e,t){let n=Cs(e);return L.join(Ss,`${n}-${t.entityType}-${t.entityNumber}`)}function Ts(e,t){return`${ee}-${Cs(e)}-${t.entityType}-${t.entityNumber}-`}function Es(e,t,n){return`${Ts(e,t)}${n}`}async function Ds(e,t,n,i=le){let a=ws(e,t),o=L.join(a,`sentinel.json`),s=Ts(e,t);try{if(await I.rm(a,{recursive:!0,force:!0}),await I.mkdir(a,{recursive:!0}),await i.restoreCache([a],s,[])==null)return null;let e=await I.readFile(o,`utf8`);return JSON.parse(e)}catch(e){return n.debug(`Dedup marker restore failed; proceeding without marker`,{error:r(e),entityType:t.entityType,entityNumber:t.entityNumber}),null}}async function Os(e,t,n,i,a=le){let o=ws(e,t),s=L.join(o,`sentinel.json`),c=Es(e,t,n.runId);try{return await I.mkdir(o,{recursive:!0}),await I.writeFile(s,JSON.stringify(n),`utf8`),await a.saveCache([o],c),!0}catch(e){return r(e).toLowerCase().includes(`already exists`)?!0:(i.debug(`Dedup marker save failed`,{error:r(e),entityType:t.entityType,entityNumber:t.entityNumber,saveKey:c}),!1)}}const ks=new Set([`pull_request`,`issues`]);function As(e){return e.target==null||!ks.has(e.eventType)?null:e.eventType===`pull_request`&&e.target.kind===`pr`?{entityType:`pr`,entityNumber:e.target.number}:e.eventType===`issues`&&e.target.kind===`issue`?{entityType:`issue`,entityNumber:e.target.number}:null}async function js(e,t,n,r,a=i({phase:`dedup`}),o){let s=As(t);if(e===0)return{shouldProceed:!0,entity:s};if(s==null)return{shouldProceed:!0,entity:null};let c=await Ds(n,s,a,o);if(c==null||c.runId===t.runId)return{shouldProceed:!0,entity:s};let l=new Date(c.timestamp).getTime();if(Number.isNaN(l))return a.warning(`Dedup marker timestamp is invalid; proceeding without dedup`,{markerTimestamp:c.timestamp}),{shouldProceed:!0,entity:s};let u=Date.now()-l;return u<-6e4?(a.warning(`Dedup marker timestamp is too far in the future; proceeding without dedup`,{markerTimestamp:c.timestamp,markerAge:u}),{shouldProceed:!0,entity:s}):Math.max(0,u)>e?{shouldProceed:!0,entity:s}:(a.info(`Skipping duplicate trigger within dedup window`,{eventType:t.eventType,action:t.action,runId:t.runId,markerRunId:c.runId,markerTimestamp:c.timestamp,dedupWindow:e,entityType:s.entityType,entityNumber:s.entityNumber}),Be({sessionId:null,cacheStatus:`miss`,duration:Date.now()-r}),{shouldProceed:!1,entity:s})}async function Ms(e,t,n,r=i({phase:`dedup`}),a){await Os(n,t,{timestamp:new Date().toISOString(),runId:e.runId,action:e.action??`unknown`,eventType:e.eventType,entityType:t.entityType,entityNumber:t.entityNumber},r,a)}async function Ns(e,t,n,r,o,s){let c={context:t.agentContext,customPrompt:e.inputs.prompt,cacheStatus:n.cacheStatus,sessionContext:{recentSessions:r.recentSessions,priorWorkContext:r.priorWorkContext},logicalKey:r.logicalKey??null,isContinuation:r.isContinuation,currentThreadSessionId:r.continueSessionId??null,triggerContext:t.triggerResult.context,fileParts:r.attachmentResult?.fileParts},l=N.env.SKIP_AGENT_EXECUTION===`true`,u=Date.now(),d;if(l)e.logger.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),d={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let t=i({phase:`execution`});t.info(`Starting OpenCode execution`,{logicalKey:r.logicalKey?.key??null,continueSessionId:r.continueSessionId});let a=await nr(c,t,{agent:e.inputs.agent,model:e.inputs.model,timeoutMs:e.inputs.timeoutMs,omoProviders:e.inputs.omoProviders,continueSessionId:r.continueSessionId??void 0,sessionTitle:r.sessionTitle??void 0},n.serverHandle),o=a.sessionId;if(o==null){let e=i({phase:`session`}),t=await us(n.serverHandle.client,r.normalizedWorkspace,u,e);t!=null&&(o=t.session.id,e.debug(`Identified session from execution`,{sessionId:o}))}d={...a,sessionId:o},t.info(`Completed OpenCode execution`,{success:d.success,sessionId:d.sessionId,logicalKey:r.logicalKey?.key??null})}d.sessionId!=null&&(a(_.SESSION_ID,d.sessionId),o.addSessionCreated(d.sessionId)),d.tokenUsage!=null&&o.setTokenUsage(d.tokenUsage,d.model,d.cost);for(let e of d.prsCreated)o.addPRCreated(e);for(let e of d.commitsCreated)o.addCommitCreated(e);for(let e=0;e`)}async function Is(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:r(e)}),null}}async function Ls(e,t,n,i){let a=[],o=1;for(;o<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:o});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;a.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:Fs(t,e.body??``,n)})}if(r.length<100)break;o++}catch(e){i.warning(`Failed to fetch comments page`,{target:t,page:o,error:r(e)});break}return a}async function Rs(e,t,n,i){try{let r=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` query GetDiscussion($owner: String!, $repo: String!, $number: Int!, $after: String) { repository(owner: $owner, name: $repo) { discussion(number: $number) { @@ -287,7 +287,7 @@ If you had completed the task, confirm the completion.`,d=i===1?e.fileParts:void } } } -`,{owner:t.owner,repo:t.repo,number:t.number,after:a})).repository.discussion;if(d==null)return i.debug(`Discussion not found`,{target:t}),null;u===0&&(o=d.id,s=d.title,c=d.body,l=d.author?.login??`unknown`);for(let e of d.comments.nodes){let t=e.author?.login??`unknown`;r.push({id:e.id,body:e.body,author:t,authorAssociation:`NONE`,createdAt:e.createdAt,updatedAt:e.updatedAt,isBot:Ps(t,e.body,n)})}if(!d.comments.pageInfo.hasNextPage)break;a=d.comments.pageInfo.endCursor,u++}return{type:`discussion`,number:t.number,title:s,body:c,author:l,comments:r,discussionId:o??void 0}}catch(e){return i.warning(`Failed to fetch discussion`,{target:t,error:r(e)}),null}}async function Rs(e,t,n,r){if(t.type===`discussion`)return Ls(e,t,n,r);let i=await Fs(e,t,r);if(i==null)return null;let a=await Is(e,t,n,r);return{type:t.type,number:t.number,title:i.title,body:i.body,author:i.author,comments:a}}function zs(e,t){let n=e.comments.filter(e=>Ns(e.author,t)&&e.body.includes(``));return n.length===0?null:n.at(-1)??null}async function Bs(e,t,n,i){try{let{data:r}=await e.rest.issues.createComment({owner:t.owner,repo:t.repo,issue_number:t.number,body:n});return i.debug(`Created issue comment`,{commentId:r.id,target:t}),{commentId:r.id,created:!0,updated:!1,url:r.html_url}}catch(e){return i.warning(`Failed to create issue comment`,{target:t,error:r(e)}),null}}async function Vs(e,t,n,i,a){try{let{data:r}=await e.rest.issues.updateComment({owner:t.owner,repo:t.repo,comment_id:n,body:i});return a.debug(`Updated issue comment`,{commentId:r.id,target:t}),{commentId:r.id,created:!1,updated:!0,url:r.html_url}}catch(e){return a.warning(`Failed to update issue comment`,{target:t,commentId:n,error:r(e)}),null}}async function Hs(e,t,n,i){try{let r=(await e.graphql(` +`,{owner:t.owner,repo:t.repo,number:t.number,after:a})).repository.discussion;if(d==null)return i.debug(`Discussion not found`,{target:t}),null;u===0&&(o=d.id,s=d.title,c=d.body,l=d.author?.login??`unknown`);for(let e of d.comments.nodes){let t=e.author?.login??`unknown`;r.push({id:e.id,body:e.body,author:t,authorAssociation:`NONE`,createdAt:e.createdAt,updatedAt:e.updatedAt,isBot:Fs(t,e.body,n)})}if(!d.comments.pageInfo.hasNextPage)break;a=d.comments.pageInfo.endCursor,u++}return{type:`discussion`,number:t.number,title:s,body:c,author:l,comments:r,discussionId:o??void 0}}catch(e){return i.warning(`Failed to fetch discussion`,{target:t,error:r(e)}),null}}async function zs(e,t,n,r){if(t.type===`discussion`)return Rs(e,t,n,r);let i=await Is(e,t,r);if(i==null)return null;let a=await Ls(e,t,n,r);return{type:t.type,number:t.number,title:i.title,body:i.body,author:i.author,comments:a}}function Bs(e,t){let n=e.comments.filter(e=>Ps(e.author,t)&&e.body.includes(``));return n.length===0?null:n.at(-1)??null}async function Vs(e,t,n,i){try{let{data:r}=await e.rest.issues.createComment({owner:t.owner,repo:t.repo,issue_number:t.number,body:n});return i.debug(`Created issue comment`,{commentId:r.id,target:t}),{commentId:r.id,created:!0,updated:!1,url:r.html_url}}catch(e){return i.warning(`Failed to create issue comment`,{target:t,error:r(e)}),null}}async function Hs(e,t,n,i,a){try{let{data:r}=await e.rest.issues.updateComment({owner:t.owner,repo:t.repo,comment_id:n,body:i});return a.debug(`Updated issue comment`,{commentId:r.id,target:t}),{commentId:r.id,created:!1,updated:!0,url:r.html_url}}catch(e){return a.warning(`Failed to update issue comment`,{target:t,commentId:n,error:r(e)}),null}}async function Us(e,t,n,i){try{let r=(await e.graphql(` query GetDiscussionId($owner: String!, $repo: String!, $number: Int!) { repository(owner: $owner, name: $repo) { discussion(number: $number) { @@ -308,7 +308,7 @@ If you had completed the task, confirm the completion.`,d=i===1?e.fileParts:void } } } -`,{owner:t.owner,repo:t.repo,number:t.number})).repository.discussion;if(r==null)return i.warning(`Discussion not found`,{target:t}),null;if(n.updateExisting===!0&&n.botLogin!=null){let r=await Rs(e,t,n.botLogin,i);if(r!=null){let t=zs(r,n.botLogin);if(t!=null&&typeof t.id==`string`){let r=await e.graphql(` +`,{owner:t.owner,repo:t.repo,number:t.number})).repository.discussion;if(r==null)return i.warning(`Discussion not found`,{target:t}),null;if(n.updateExisting===!0&&n.botLogin!=null){let r=await zs(e,t,n.botLogin,i);if(r!=null){let t=Bs(r,n.botLogin);if(t!=null&&typeof t.id==`string`){let r=await e.graphql(` mutation UpdateDiscussionComment($commentId: ID!, $body: String!) { updateDiscussionComment(input: {commentId: $commentId, body: $body}) { comment { id url } @@ -320,4 +320,4 @@ If you had completed the task, confirm the completion.`,d=i===1?e.fileParts:void comment { id url } } } -`,{discussionId:r.id,body:n.body});return i.debug(`Created discussion comment`,{discussionId:r.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return i.warning(`Failed to post discussion comment`,{target:t,error:r(e)}),null}}async function Us(e,t,n,r){if(t.type===`discussion`)return Hs(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await Rs(e,t,n.botLogin,r);if(i!=null){let a=zs(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return Vs(e,t,a.id,n.body,r)}}return Bs(e,t,n.body,r)}async function Ws(e,t,n,r,a,o,s){let l=Date.now()-o;if(Be({sessionId:r.sessionId,cacheStatus:n.cacheStatus,duration:l}),await Re({eventType:t.agentContext.eventName,repo:t.agentContext.repo,ref:t.agentContext.ref,runId:Number(t.agentContext.runId),runUrl:`https://github.com/${t.agentContext.repo}/actions/runs/${t.agentContext.runId}`,metrics:a.getMetrics(),agent:e.inputs.agent},s),r.success)return s.info(`Agent run completed successfully`,{durationMs:l}),0;if(r.llmError==null)return c(`Agent execution failed with exit code ${r.exitCode}`),r.exitCode;s.info(`Agent failed with recoverable LLM error`,{error:r.llmError.message,type:r.llmError.type,durationMs:l});let[u,d]=t.agentContext.repo.split(`/`),f={type:t.triggerResult.context.eventType===`discussion_comment`?`discussion`:t.agentContext.issueType===`pr`?`pr`:`issue`,number:t.agentContext.issueNumber??0,owner:u??``,repo:d??``};if(f.number>0&&f.owner.length>0&&f.repo.length>0){let e=gn(r.llmError),n=i({phase:`error-comment`}),o=await Us(t.githubClient,f,{body:e},n);o==null?n.warning(`Failed to post LLM error comment`):(n.info(`Posted LLM error comment`,{commentUrl:o.url}),a.incrementComments())}else s.warning(`Cannot post error comment: missing target context`);return 0}function Gs(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function Ks(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t,n=e.pull_request.requested_reviewers??[],r=`requested_reviewer`in e&&e.requested_reviewer!=null?{login:e.requested_reviewer.login,type:e.requested_reviewer.type}:null,i=`requested_team`in e&&e.requested_team!=null?{name:e.requested_team.name,slug:e.requested_team.slug}:null,a=n.flatMap(e=>`login`in e&&`type`in e?[{login:e.login,type:e.type}]:[]);return{type:`pull_request`,action:e.action,requestedReviewer:r,requestedTeam:i,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`,requestedReviewers:a},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function qs(e){let t=fa,n=Gs(t.eventName),r=Ks(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function Js(e,t){return t.includes(e)}function X(e){return e.endsWith(`[bot]`)}function Ys(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${Xs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function Xs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function Zs(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${Xs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function Z(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=Ys(e,t);return{hasMention:n,command:n?Zs(e,t):null}}function Qs(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:X(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},{hasMention:i,command:a}=Z(e.comment.body,t);return{action:e.action,author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,isBotReviewRequested:!1}}function $s(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:X(e.comment.author)},r=e.comment.body??null,i={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:r??e.discussion.body??null,locked:e.discussion.locked},{hasMention:a,command:o}=Z(r,t);return{action:e.action,author:n,target:i,commentBody:r,commentId:e.comment.id,hasMention:a,command:o,isBotReviewRequested:!1}}function ec(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:X(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=Z(e.comment.body,t);return{action:e.action,author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,isBotReviewRequested:!1}}function tc(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{action:null,author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,isBotReviewRequested:!1}}function nc(e,t,n){let r=n?.trim()??``;return{action:null,author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,isBotReviewRequested:!1}}function rc(e){return e.toLowerCase().replace(/\[bot\]$/i,``)}function ic(e,t){if(e.type!==`pull_request`||t==null||t===``)return!1;let n=rc(t);if(n===``)return!1;if(e.action===`review_requested`){let t=e.requestedReviewer?.login;return t!=null&&rc(t)===n}return e.action===`ready_for_review`?e.pullRequest.requestedReviewers.some(e=>rc(e.login)===n):!1}function ac(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:X(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=Z(e.issue.body??``,t);return{action:e.action,author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,isBotReviewRequested:!1}}function oc(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:X(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft,requestedReviewerLogin:e.requestedReviewer?.login,requestedTeamSlug:e.requestedTeam?.slug,requestedReviewerLogins:e.pullRequest.requestedReviewers.map(e=>e.login)},{hasMention:i,command:a}=Z(e.pullRequest.body??``,t);return{action:e.action,author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,isBotReviewRequested:ic(e,t)}}function Q(e,t){return{...e,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command,isBotReviewRequested:t.isBotReviewRequested}}function sc(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:return Q(r,Qs(e.event,t));case`discussion_comment`:return Q(r,$s(e.event,t));case`workflow_dispatch`:return Q(r,tc(e.event,e.actor,n));case`issues`:return Q(r,ac(e.event,t));case`pull_request`:return Q(r,oc(e.event,t));case`pull_request_review_comment`:return Q(r,ec(e.event,t));case`schedule`:return Q(r,nc(e.event,e.actor,n));case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null,isBotReviewRequested:!1}}}function cc(e,t,n){let{targetLabel:r,actionLabel:i}=n;return e.action===`created`?e.target?.locked===!0?{shouldSkip:!0,reason:`issue_locked`,message:`${r} is locked`}:e.author!=null&&e.author.isBot?{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}:e.author!=null&&!Js(e.author.association,t.allowedAssociations)?{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}:t.requireMention&&!e.hasMention?{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}:{shouldSkip:!1}:{shouldSkip:!0,reason:`action_not_created`,message:`${i} action is '${e.action}', not 'created'`}}function lc(e,t){return cc(e,t,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function uc(e,t){return cc(e,t,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}const dc=[`opened`,`edited`];function fc(e){return dc.includes(e)}function pc(e,t){let n=e.action;return n==null||!fc(n)?{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${n}' is not supported (only 'opened' and 'edited')`}:e.author!=null&&e.author.isBot?{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}:e.author!=null&&!Js(e.author.association,t.allowedAssociations)?{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}:n===`edited`&&!e.hasMention?{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}:e.target?.locked===!0?{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}:{shouldSkip:!1}}function mc(e){return(e.promptInput?.trim()??``)===``?{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}:{shouldSkip:!1}}function hc(e){return(e.commentBody?.trim()??``)===``?{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}:{shouldSkip:!1}}const gc=[`opened`,`synchronize`,`reopened`,`ready_for_review`,`review_requested`];function _c(e){return gc.includes(e)}function vc(e,t){let n=e.action;return n==null||!_c(n)?{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${n}' is not supported`}:e.action!==`review_requested`&&e.action!==`ready_for_review`&&e.author!=null&&e.author.isBot?{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}:e.author!=null&&!Js(e.author.association,t.allowedAssociations)?{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}:t.skipDraftPRs&&e.target?.isDraft===!0?{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}:e.target?.locked===!0?{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}:t.botLogin!=null&&t.botLogin!==``&&(e.action===`ready_for_review`||e.action===`review_requested`)&&e.isBotReviewRequested!==!0?{shouldSkip:!0,reason:`bot_not_requested`,message:`Pull request action '${e.action}' did not request review from the bot`}:{shouldSkip:!1}}function yc(e,t){let n=e.action;return n===`created`?e.target?.locked===!0?{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}:e.author!=null&&e.author.isBot?{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}:e.author!=null&&!Js(e.author.association,t.allowedAssociations)?{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}:t.requireMention&&!e.hasMention?{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}:{shouldSkip:!1}:{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${n}' is not supported (only 'created')`}}function bc(e){return{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e}`}}function xc(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),bc(e.eventName);switch(e.eventType){case`issue_comment`:return lc(e,t);case`discussion_comment`:return uc(e,t);case`issues`:return pc(e,t);case`pull_request`:return vc(e,t);case`pull_request_review_comment`:return yc(e,t);case`schedule`:return mc(t);case`workflow_dispatch`:return hc(e);default:return{shouldSkip:!1}}}const Sc={botLogin:null,requireMention:!0,allowedAssociations:yo,skipDraftPRs:!0,promptInput:null,senderAssociation:null};function Cc(e,t,n={}){let r={...Sc,...n},i=sc(e,r.botLogin,r.promptInput);r.senderAssociation!=null&&(i.action===`review_requested`||i.action===`ready_for_review`)&&i.author!=null&&(i={...i,author:{...i.author,association:r.senderAssociation}}),t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=xc(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function wc(e,t){let n=i({phase:`context`}),r=qs(n),o=Wa({token:e.inputs.githubToken,logger:n}),s=await Ga(o,n),c=null;if(r.event.type===`pull_request`&&(r.event.action===`review_requested`||r.event.action===`ready_for_review`)){let{owner:e,repo:t}=r.repo;c=await Ye(o,e,t,r.event.sender.login,n)}let l=i({phase:`trigger`}),u=Cc(r,l,{botLogin:s,requireMention:!0,promptInput:e.inputs.prompt,senderAssociation:c});return u.shouldProcess?(l.info(`Event routed for processing`,{eventType:u.context.eventType,hasMention:u.context.hasMention,command:u.context.command?.action??null}),a(_.SHOULD_SAVE_CACHE,`true`),{githubClient:o,triggerResult:u,agentContext:await pt({logger:n,octokit:o,triggerContext:u.context,botLogin:s}),botLogin:s}):(l.info(`Skipping event`,{reason:u.skipReason,message:u.skipMessage}),Be({sessionId:null,cacheStatus:`miss`,duration:Date.now()-t}),null)}function $(e,t){return{key:`${e}-${t}`,entityType:e,entityId:t}}function Tc(e){return Ee(`sha256`).update(e).digest(`hex`).slice(0,8)}function Ec(e){if(e.eventType===`unsupported`)return null;if(e.eventType===`schedule`){let t=e.raw.event.type===`schedule`?e.raw.event.schedule:void 0;return $(`schedule`,Tc((t!=null&&t.trim().length>0?t:e.action)??`default`))}return e.eventType===`workflow_dispatch`?$(`dispatch`,String(e.runId)):e.target==null?null:e.eventType===`issue_comment`?e.target.kind===`issue`?$(`issue`,String(e.target.number)):e.target.kind===`pr`?$(`pr`,String(e.target.number)):null:e.eventType===`discussion_comment`?e.target.kind===`discussion`?$(`discussion`,String(e.target.number)):null:e.eventType===`issues`?e.target.kind===`issue`?$(`issue`,String(e.target.number)):null:(e.eventType===`pull_request`||e.eventType===`pull_request_review_comment`)&&e.target.kind===`pr`?$(`pr`,String(e.target.number)):null}function Dc(e){return`fro-bot: ${e.key}`}function Oc(e,t){let n=e.filter(e=>e.title===t);return n.length===0?null:n.reduce((e,t)=>t.time.updated>e.time.updated?t:e)}async function kc(e,t,n,r){try{let i=Oc(await ss(e,t,r),Dc(n));return i==null||i.time.archived!=null||i.time.compacting!=null?{status:`not-found`}:{status:`found`,session:i}}catch(e){return{status:`error`,error:e instanceof Error?e.message:String(e)}}}async function Ac(e,t,n,r){let a=i({phase:`session`}),o=J(re()),s=await ps(n.serverHandle.client,o,{limit:10},a);a.debug(`Listed recent sessions`,{count:s.length});let c=Ec(t.triggerResult.context),l=c==null?null:Dc(c),u=null,d=!1;if(c!=null){let e=await kc(n.serverHandle.client,o,c,a);e.status===`found`?(u=e.session.id,d=!0,a.info(`Session continuity: found existing session`,{logicalKey:c.key,sessionId:u})):e.status===`error`?a.warning(`Session continuity: lookup error, will create new`,{logicalKey:c.key,error:e.error}):a.info(`Session continuity: no existing session found`,{logicalKey:c.key})}let f=c?.key??t.agentContext.issueTitle??t.agentContext.repo,p=await hs(f,n.serverHandle.client,o,{limit:5},a);a.debug(`Searched prior sessions`,{query:f,resultCount:p.length});for(let e of p)r.addSessionUsed(e.sessionId);let m=i({phase:`attachments`}),h=t.agentContext.commentBody??``,g=Ro(h),_=null;if(g.length>0){m.info(`Processing attachments`,{count:g.length});let{validated:t,skipped:n}=Yo(await Uo(g,e.inputs.githubToken,void 0,m),void 0,m);(t.length>0||n.length>0)&&(_=qo(h,g,t,n),m.info(`Attachments processed`,{processed:t.length,skipped:n.length}))}return{recentSessions:s,priorWorkContext:p,attachmentResult:_,normalizedWorkspace:o,logicalKey:c,continueSessionId:u,isContinuation:d,sessionTitle:l}}async function jc(){let e=Date.now(),t=i({phase:`bootstrap`}),n=ze();n.start();let r=null,o=!1,s=0,l=null,u=null,d=null,f=null;a(_.SHOULD_SAVE_CACHE,`false`),a(_.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let i=await jo(t);if(i==null)return 1;d=i.opencodeResult.version;let a=await wc(i,e);if(a==null)return 0;l=a.githubClient;let c=`${a.triggerResult.context.repo.owner}/${a.triggerResult.context.repo.repo}`,p=await As(i.inputs.dedupWindow,a.triggerResult.context,c,e);if(!p.shouldProceed)return 0;r=await Co(a,i.logger);let m=await Fo(i);if(m==null)return 1;f=m.serverHandle,n.setCacheStatus(m.cacheStatus);let h=await Ac(i,a,m,n);u=h.attachmentResult;let g=await Ms(i,a,m,h,n,e);o=g.success,o&&p.entity!=null&&await js(a.triggerResult.context,p.entity,c),n.end(),s=await Ws(i,a,m,g,n,e,i.logger)}catch(r){s=1;let i=Date.now()-e,a=r instanceof Error?r.name:`UnknownError`,o=r instanceof Error?r.message:String(r);n.recordError(a,o,!1),n.end(),Be({sessionId:null,cacheStatus:`miss`,duration:i}),r instanceof Error?(t.error(`Agent failed`,{error:r.message}),c(r.message)):(t.error(`Agent failed with unknown error`),c(`An unknown error occurred`))}finally{await bs({bootstrapLogger:t,reactionCtx:r,githubClient:l,agentSuccess:o,attachmentResult:u,serverHandle:f,detectedOpencodeVersion:d})}return s}await jc().then(e=>{N.exit(e)});export{}; \ No newline at end of file +`,{discussionId:r.id,body:n.body});return i.debug(`Created discussion comment`,{discussionId:r.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return i.warning(`Failed to post discussion comment`,{target:t,error:r(e)}),null}}async function Ws(e,t,n,r){if(t.type===`discussion`)return Us(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await zs(e,t,n.botLogin,r);if(i!=null){let a=Bs(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return Hs(e,t,a.id,n.body,r)}}return Vs(e,t,n.body,r)}async function Gs(e,t,n,r,a,o,s){let l=Date.now()-o;if(Be({sessionId:r.sessionId,cacheStatus:n.cacheStatus,duration:l}),await Re({eventType:t.agentContext.eventName,repo:t.agentContext.repo,ref:t.agentContext.ref,runId:Number(t.agentContext.runId),runUrl:`https://github.com/${t.agentContext.repo}/actions/runs/${t.agentContext.runId}`,metrics:a.getMetrics(),agent:e.inputs.agent},s),r.success)return s.info(`Agent run completed successfully`,{durationMs:l}),0;if(r.llmError==null)return c(`Agent execution failed with exit code ${r.exitCode}`),r.exitCode;s.info(`Agent failed with recoverable LLM error`,{error:r.llmError.message,type:r.llmError.type,durationMs:l});let[u,d]=t.agentContext.repo.split(`/`),f={type:t.triggerResult.context.eventType===`discussion_comment`?`discussion`:t.agentContext.issueType===`pr`?`pr`:`issue`,number:t.agentContext.issueNumber??0,owner:u??``,repo:d??``};if(f.number>0&&f.owner.length>0&&f.repo.length>0){let e=vn(r.llmError),n=i({phase:`error-comment`}),o=await Ws(t.githubClient,f,{body:e},n);o==null?n.warning(`Failed to post LLM error comment`):(n.info(`Posted LLM error comment`,{commentUrl:o.url}),a.incrementComments())}else s.warning(`Cannot post error comment: missing target context`);return 0}function Ks(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function qs(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t,n=e.pull_request.requested_reviewers??[],r=`requested_reviewer`in e&&e.requested_reviewer!=null?{login:e.requested_reviewer.login,type:e.requested_reviewer.type}:null,i=`requested_team`in e&&e.requested_team!=null?{name:e.requested_team.name,slug:e.requested_team.slug}:null,a=n.flatMap(e=>`login`in e&&`type`in e?[{login:e.login,type:e.type}]:[]);return{type:`pull_request`,action:e.action,requestedReviewer:r,requestedTeam:i,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`,requestedReviewers:a},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function Js(e){let t=pa,n=Ks(t.eventName),r=qs(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function Ys(e,t){return t.includes(e)}function X(e){return e.endsWith(`[bot]`)}function Xs(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${Zs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function Zs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function Qs(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${Zs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function Z(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=Xs(e,t);return{hasMention:n,command:n?Qs(e,t):null}}function $s(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:X(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},{hasMention:i,command:a}=Z(e.comment.body,t);return{action:e.action,author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,isBotReviewRequested:!1}}function ec(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:X(e.comment.author)},r=e.comment.body??null,i={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:r??e.discussion.body??null,locked:e.discussion.locked},{hasMention:a,command:o}=Z(r,t);return{action:e.action,author:n,target:i,commentBody:r,commentId:e.comment.id,hasMention:a,command:o,isBotReviewRequested:!1}}function tc(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:X(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=Z(e.comment.body,t);return{action:e.action,author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,isBotReviewRequested:!1}}function nc(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{action:null,author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,isBotReviewRequested:!1}}function rc(e,t,n){let r=n?.trim()??``;return{action:null,author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,isBotReviewRequested:!1}}function ic(e){return e.toLowerCase().replace(/\[bot\]$/i,``)}function ac(e,t){if(e.type!==`pull_request`||t==null||t===``)return!1;let n=ic(t);if(n===``)return!1;if(e.action===`review_requested`){let t=e.requestedReviewer?.login;return t!=null&&ic(t)===n}return e.action===`ready_for_review`?e.pullRequest.requestedReviewers.some(e=>ic(e.login)===n):!1}function oc(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:X(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=Z(e.issue.body??``,t);return{action:e.action,author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,isBotReviewRequested:!1}}function sc(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:X(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft,requestedReviewerLogin:e.requestedReviewer?.login,requestedTeamSlug:e.requestedTeam?.slug,requestedReviewerLogins:e.pullRequest.requestedReviewers.map(e=>e.login)},{hasMention:i,command:a}=Z(e.pullRequest.body??``,t);return{action:e.action,author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,isBotReviewRequested:ac(e,t)}}function Q(e,t){return{...e,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command,isBotReviewRequested:t.isBotReviewRequested}}function cc(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:return Q(r,$s(e.event,t));case`discussion_comment`:return Q(r,ec(e.event,t));case`workflow_dispatch`:return Q(r,nc(e.event,e.actor,n));case`issues`:return Q(r,oc(e.event,t));case`pull_request`:return Q(r,sc(e.event,t));case`pull_request_review_comment`:return Q(r,tc(e.event,t));case`schedule`:return Q(r,rc(e.event,e.actor,n));case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null,isBotReviewRequested:!1}}}function lc(e,t,n){let{targetLabel:r,actionLabel:i}=n;return e.action===`created`?e.target?.locked===!0?{shouldSkip:!0,reason:`issue_locked`,message:`${r} is locked`}:e.author!=null&&e.author.isBot?{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}:e.author!=null&&!Ys(e.author.association,t.allowedAssociations)?{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}:t.requireMention&&!e.hasMention?{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}:{shouldSkip:!1}:{shouldSkip:!0,reason:`action_not_created`,message:`${i} action is '${e.action}', not 'created'`}}function uc(e,t){return lc(e,t,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function dc(e,t){return lc(e,t,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}const fc=[`opened`,`edited`];function pc(e){return fc.includes(e)}function mc(e,t){let n=e.action;return n==null||!pc(n)?{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${n}' is not supported (only 'opened' and 'edited')`}:e.author!=null&&e.author.isBot?{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}:e.author!=null&&!Ys(e.author.association,t.allowedAssociations)?{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}:n===`edited`&&!e.hasMention?{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}:e.target?.locked===!0?{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}:{shouldSkip:!1}}function hc(e){return(e.promptInput?.trim()??``)===``?{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}:{shouldSkip:!1}}function gc(e){return(e.commentBody?.trim()??``)===``?{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}:{shouldSkip:!1}}const _c=[`opened`,`synchronize`,`reopened`,`ready_for_review`,`review_requested`];function vc(e){return _c.includes(e)}function yc(e,t){let n=e.action;return n==null||!vc(n)?{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${n}' is not supported`}:e.action!==`review_requested`&&e.action!==`ready_for_review`&&e.author!=null&&e.author.isBot?{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}:e.author!=null&&!Ys(e.author.association,t.allowedAssociations)?{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}:t.skipDraftPRs&&e.target?.isDraft===!0?{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}:e.target?.locked===!0?{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}:t.botLogin!=null&&t.botLogin!==``&&(e.action===`ready_for_review`||e.action===`review_requested`)&&e.isBotReviewRequested!==!0?{shouldSkip:!0,reason:`bot_not_requested`,message:`Pull request action '${e.action}' did not request review from the bot`}:{shouldSkip:!1}}function bc(e,t){let n=e.action;return n===`created`?e.target?.locked===!0?{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}:e.author!=null&&e.author.isBot?{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}:e.author!=null&&!Ys(e.author.association,t.allowedAssociations)?{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}:t.requireMention&&!e.hasMention?{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}:{shouldSkip:!1}:{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${n}' is not supported (only 'created')`}}function xc(e){return{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e}`}}function Sc(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),xc(e.eventName);switch(e.eventType){case`issue_comment`:return uc(e,t);case`discussion_comment`:return dc(e,t);case`issues`:return mc(e,t);case`pull_request`:return yc(e,t);case`pull_request_review_comment`:return bc(e,t);case`schedule`:return hc(t);case`workflow_dispatch`:return gc(e);default:return{shouldSkip:!1}}}const Cc={botLogin:null,requireMention:!0,allowedAssociations:bo,skipDraftPRs:!0,promptInput:null,senderAssociation:null};function wc(e,t,n={}){let r={...Cc,...n},i=cc(e,r.botLogin,r.promptInput);r.senderAssociation!=null&&(i.action===`review_requested`||i.action===`ready_for_review`)&&i.author!=null&&(i={...i,author:{...i.author,association:r.senderAssociation}}),t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Sc(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function Tc(e,t){let n=i({phase:`context`}),r=Js(n),o=Ga({token:e.inputs.githubToken,logger:n}),s=await Ka(o,n),c=null;if(r.event.type===`pull_request`&&(r.event.action===`review_requested`||r.event.action===`ready_for_review`)){let{owner:e,repo:t}=r.repo;c=await Ye(o,e,t,r.event.sender.login,n)}let l=i({phase:`trigger`}),u=wc(r,l,{botLogin:s,requireMention:!0,promptInput:e.inputs.prompt,senderAssociation:c});return u.shouldProcess?(l.info(`Event routed for processing`,{eventType:u.context.eventType,hasMention:u.context.hasMention,command:u.context.command?.action??null}),a(_.SHOULD_SAVE_CACHE,`true`),{githubClient:o,triggerResult:u,agentContext:await pt({logger:n,octokit:o,triggerContext:u.context,botLogin:s}),botLogin:s}):(l.info(`Skipping event`,{reason:u.skipReason,message:u.skipMessage}),Be({sessionId:null,cacheStatus:`miss`,duration:Date.now()-t}),null)}function $(e,t){return{key:`${e}-${t}`,entityType:e,entityId:t}}function Ec(e){return Ee(`sha256`).update(e).digest(`hex`).slice(0,8)}function Dc(e){if(e.eventType===`unsupported`)return null;if(e.eventType===`schedule`){let t=e.raw.event.type===`schedule`?e.raw.event.schedule:void 0;return $(`schedule`,Ec((t!=null&&t.trim().length>0?t:e.action)??`default`))}return e.eventType===`workflow_dispatch`?$(`dispatch`,String(e.runId)):e.target==null?null:e.eventType===`issue_comment`?e.target.kind===`issue`?$(`issue`,String(e.target.number)):e.target.kind===`pr`?$(`pr`,String(e.target.number)):null:e.eventType===`discussion_comment`?e.target.kind===`discussion`?$(`discussion`,String(e.target.number)):null:e.eventType===`issues`?e.target.kind===`issue`?$(`issue`,String(e.target.number)):null:(e.eventType===`pull_request`||e.eventType===`pull_request_review_comment`)&&e.target.kind===`pr`?$(`pr`,String(e.target.number)):null}function Oc(e){return`fro-bot: ${e.key}`}function kc(e,t){let n=e.filter(e=>e.title===t);return n.length===0?null:n.reduce((e,t)=>t.time.updated>e.time.updated?t:e)}async function Ac(e,t,n,r){try{let i=kc(await cs(e,t,r),Oc(n));return i==null||i.time.archived!=null||i.time.compacting!=null?{status:`not-found`}:{status:`found`,session:i}}catch(e){return{status:`error`,error:e instanceof Error?e.message:String(e)}}}async function jc(e,t,n,r){let a=i({phase:`session`}),o=J(re()),s=await ms(n.serverHandle.client,o,{limit:10},a);a.debug(`Listed recent sessions`,{count:s.length});let c=Dc(t.triggerResult.context),l=c==null?null:Oc(c),u=null,d=!1;if(c!=null){let e=await Ac(n.serverHandle.client,o,c,a);e.status===`found`?(u=e.session.id,d=!0,a.info(`Session continuity: found existing session`,{logicalKey:c.key,sessionId:u})):e.status===`error`?a.warning(`Session continuity: lookup error, will create new`,{logicalKey:c.key,error:e.error}):a.info(`Session continuity: no existing session found`,{logicalKey:c.key})}let f=c?.key??t.agentContext.issueTitle??t.agentContext.repo,p=await gs(f,n.serverHandle.client,o,{limit:5},a);a.debug(`Searched prior sessions`,{query:f,resultCount:p.length});for(let e of p)r.addSessionUsed(e.sessionId);let m=i({phase:`attachments`}),h=t.agentContext.commentBody??``,g=zo(h),_=null;if(g.length>0){m.info(`Processing attachments`,{count:g.length});let{validated:t,skipped:n}=Xo(await Wo(g,e.inputs.githubToken,void 0,m),void 0,m);(t.length>0||n.length>0)&&(_=Jo(h,g,t,n),m.info(`Attachments processed`,{processed:t.length,skipped:n.length}))}return{recentSessions:s,priorWorkContext:p,attachmentResult:_,normalizedWorkspace:o,logicalKey:c,continueSessionId:u,isContinuation:d,sessionTitle:l}}async function Mc(){let e=Date.now(),t=i({phase:`bootstrap`}),n=ze();n.start();let r=null,o=!1,s=0,l=null,u=null,d=null,f=null;a(_.SHOULD_SAVE_CACHE,`false`),a(_.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let i=await Mo(t);if(i==null)return 1;d=i.opencodeResult.version;let a=await Tc(i,e);if(a==null)return 0;l=a.githubClient;let c=`${a.triggerResult.context.repo.owner}/${a.triggerResult.context.repo.repo}`,p=await js(i.inputs.dedupWindow,a.triggerResult.context,c,e);if(!p.shouldProceed)return 0;r=await wo(a,i.logger);let m=await Io(i);if(m==null)return 1;f=m.serverHandle,n.setCacheStatus(m.cacheStatus);let h=await jc(i,a,m,n);u=h.attachmentResult;let g=await Ns(i,a,m,h,n,e);o=g.success,o&&p.entity!=null&&await Ms(a.triggerResult.context,p.entity,c),n.end(),s=await Gs(i,a,m,g,n,e,i.logger)}catch(r){s=1;let i=Date.now()-e,a=r instanceof Error?r.name:`UnknownError`,o=r instanceof Error?r.message:String(r);n.recordError(a,o,!1),n.end(),Be({sessionId:null,cacheStatus:`miss`,duration:i}),r instanceof Error?(t.error(`Agent failed`,{error:r.message}),c(r.message)):(t.error(`Agent failed with unknown error`),c(`An unknown error occurred`))}finally{await xs({bootstrapLogger:t,reactionCtx:r,githubClient:l,agentSuccess:o,attachmentResult:u,serverHandle:f,detectedOpencodeVersion:d})}return s}await Mc().then(e=>{N.exit(e)});export{}; \ No newline at end of file diff --git a/docs/audits/2026-03-28-session-continuity-post-ship-audit.md b/docs/audits/2026-03-28-session-continuity-post-ship-audit.md new file mode 100644 index 00000000..3f0c9587 --- /dev/null +++ b/docs/audits/2026-03-28-session-continuity-post-ship-audit.md @@ -0,0 +1,188 @@ +--- +title: "Session Continuity Post-Ship Audit" +date: 2026-03-28 +scope: v0.32.0+ (PR #376) +runs_sampled: 4 Fro Bot schedule runs (Mar 24-27, 2026) +--- + +## Session Continuity Post-Ship Audit + +## Executive Summary + +The session continuity feature (PR #376, v0.32.0) is **partially functioning**. Prompt restructuring (Non-Negotiable Rules, Constraint Reminder) works correctly. Session titles are set correctly at creation. But **session continuation never succeeds** — every run creates a fresh session because OpenCode auto-renames the title after the first prompt, and the title re-set after prompt was never implemented. + +**Impact**: Zero session continuity across runs. The agent cannot recall its prior work on the same entity. The "Thread Identity" section is never populated in prompts. + +## Runs Sampled + +| Run ID | Date | Event | Session ID | Title at Creation | +| ----------- | ---------- | -------- | ------------------- | ---------------------------- | +| 23500894440 | 2026-03-24 | schedule | ses_2df4c0cafffe... | `fro-bot: schedule-c757a308` | +| 23552690701 | 2026-03-25 | schedule | ses_2da20617dffe... | `fro-bot: schedule-c757a308` | +| 23606276260 | 2026-03-26 | schedule | ses_2d4fc0340ffe... | `fro-bot: schedule-c757a308` | +| 23655941186 | 2026-03-27 | schedule | ses_2cfed642fffe... | `fro-bot: schedule-c757a308` | + +All 4 runs: different session IDs despite identical logical key `schedule-c757a308`. + +## Findings + +### 1. CRITICAL: Session Title Auto-Overwrite (Root Cause) + +**Severity**: Critical — blocks all session continuity + +OpenCode auto-renames session titles based on the first message content. The title `fro-bot: schedule-c757a308` set at creation is overwritten (likely to something like "Daily maintenance report") before the cache is saved. The next run's resolver calls `findSessionByTitle()` looking for `fro-bot: schedule-c757a308` and finds no match. + +**Evidence**: + +- All 4 runs log: `Session continuity: no existing session found` +- All 4 runs log: `continueSessionId: null` +- All 4 runs: `Created new OpenCode session` with the correct title +- Cache IS restored from previous run (confirmed: `Cache hit for restore-key: opencode-storage-github-fro-bot-agent-main-Linux-23606276260`) +- 10 sessions exist at resolver time, none match the title + +**Root cause**: The plan specified "After successful prompt, **re-set title** via `session.update()` to guard against OpenCode's auto-title behavior" — but this was **never implemented** in `execution.ts`. There is no `session.update()` call anywhere in the codebase. + +**Fix**: Add `session.update()` call after each prompt to restore the logical key title. The OpenCode PATCH endpoint (`/session/{id}`) accepts `{ title }` — confirmed in `routes/session.ts:265`. + +### 2. WORKING: Prompt Restructuring (Instruction Sandwich) + +**Severity**: N/A — functioning correctly + +The prompt shows: + +- **Position 1**: `## Critical Rules (NON-NEGOTIABLE)` — 5-line hard constraints ✅ +- **Last position**: `## Reminder: Critical Rules` — 1-line recency reminder ✅ +- Task and Trigger Comment positioned near the top ✅ +- Agent Context demoted below task content ✅ + +### 3. WORKING: Logical Key Computation + +**Severity**: N/A — functioning correctly + +The logical key `schedule-c757a308` is: + +- Deterministic (same hash across all 4 runs) ✅ +- Correctly derived from the schedule event ✅ +- Used for session title and search fallback ✅ + +### 4. WORKING: Observability (Artifact Upload) + +**Severity**: N/A — functioning correctly + +All 4 Fro Bot schedule runs produced downloadable `opencode-logs` artifacts containing: + +- OpenCode server log (4,000-8,700 lines each) +- Prompt artifact file (197 lines each) +- Unique artifact names (`opencode-logs-{runId}-1`) ✅ + +### 5. ISSUE: Thread Identity Section Missing from Prompts + +**Severity**: High — dependent on session continuity + +The prompt shows NO "Thread Identity" section. This is expected given continuity never succeeds — the section is only populated when `logicalKey` and `isContinuation` are provided to the prompt builder. When `continueSessionId` is null, no thread identity is injected. + +**Fix**: Will resolve automatically once session continuity works. However, consider showing thread identity even on fresh sessions (e.g., "Fresh conversation — no prior thread found for schedule-c757a308") to aid debugging. + +### 6. ISSUE: Task Content Duplicated in Prompt + +**Severity**: Low — token waste + +The schedule task description appears verbatim in both: + +- `## Task` section (lines 8-37) +- `## Trigger Comment` section (lines 38-70) + +This is ~30 lines / ~400 tokens of pure duplication. For schedule events, the Task and Trigger Comment are identical because the `prompt` input IS the task. + +**Fix**: In `buildAgentPrompt()`, skip the Trigger Comment section when its content is identical to the Task section. + +### 7. NOISE: `tool.registry ... invalid` Entries + +**Severity**: Low — cosmetic noise + +Every run logs 14-24 instances of: + +``` +INFO service=tool.registry status=started invalid +INFO service=tool.registry status=completed duration=N invalid +``` + +The `invalid` here is NOT an error — it's the tool name. OpenCode's tool registry initializes a tool called `invalid` (likely a placeholder/sentinel). This is benign startup chatter from OpenCode internals. + +**Recommendation**: No action needed. Document as expected noise. + +### 8. NOISE: `Blocked 3 postinstalls` + +**Severity**: Low — cosmetic noise + +Every run logs exactly once: + +``` +Blocked 3 postinstalls. Run `bun pm untrusted` for details. +``` + +This is Bun's security policy for oMo's dependencies. Expected behavior. + +**Recommendation**: No action needed. Document as expected noise. + +### 9. OBSERVATION: Prior Session Context Shows Stale Sessions + +**Severity**: Medium — reduced context quality + +The "Prior Session Context" table shows sessions from March 3-22 (pre-v0.32.0), none of which are schedule-related maintenance sessions. The recent schedule sessions (Mar 24-26) don't appear because they likely got renamed by OpenCode and are no longer matching any useful search query. + +**Fix**: Will improve automatically once session continuity works. The "Current Thread Context" section will show the actual prior work from the same schedule thread. + +## Prioritized Action Items + +### P0: Fix session title persistence (blocks all continuity) + +Add `session.update()` call in `execution.ts` after successful prompt to re-set the logical key title. Without this, no session continuity can ever work. + +```typescript +// After successful prompt, re-set title to guard against auto-rename +if (sessionTitle != null) { + try { + await client.session.update({ + path: {id: sessionId}, + body: {title: sessionTitle} as Record, + }) + } catch { + logger.warning("Failed to re-set session title", {sessionId, sessionTitle}) + } +} +``` + +### P1: Show Thread Identity on fresh sessions too + +Currently Thread Identity only shows when `isContinuation` is true. Show it on fresh starts too so the logical key is visible in the prompt artifact for debugging: + +``` +## Thread Identity +**Logical Thread**: `schedule-c757a308` (schedule) +**Status**: Fresh conversation — no prior thread found for this entity. +``` + +### P2: Deduplicate Task / Trigger Comment for schedule events + +Skip the Trigger Comment section when it's identical to the Task section. Saves ~400 tokens per schedule run. + +### P3: Add debug logging for session title state + +Log the titles of sessions returned by `listSessionsForProject()` during resolution so we can see what titles the sessions actually have (vs. what we're searching for). + +## Metrics + +| Metric | Value | +| --------------------------------------- | ------------------------------------------------------------ | +| Runs sampled | 4 | +| Session continuity success rate | **0%** (0/4 runs) | +| Prompt restructuring working | **Yes** (Non-Negotiable Rules + Constraint Reminder present) | +| Artifact upload working | **Yes** (all 4 runs have artifacts) | +| Logical key computation working | **Yes** (deterministic `schedule-c757a308` across all runs) | +| OpenCode errors in logs | **0** | +| OpenCode warnings in logs | **0** | +| tool.registry "invalid" entries per run | 14-24 (benign noise) | +| Avg run duration | ~4-10 minutes | +| Avg OpenCode log size | 4,000-8,700 lines | +| Prompt size | 197 lines (~2,500 words) | diff --git a/src/features/agent/execution.ts b/src/features/agent/execution.ts index e2151d81..2906fee3 100644 --- a/src/features/agent/execution.ts +++ b/src/features/agent/execution.ts @@ -7,6 +7,7 @@ import * as crypto from 'node:crypto' import * as fs from 'node:fs/promises' import * as path from 'node:path' import {createOpencode} from '@opencode-ai/sdk' +import {reassertSessionTitle} from '../../services/session/title-reassert.js' import {sleep} from '../../shared/async.js' import {DEFAULT_AGENT, DEFAULT_TIMEOUT_MS} from '../../shared/constants.js' import {getGitHubWorkspace, getOpenCodeLogPath, isOpenCodePromptArtifactEnabled} from '../../shared/env.js' @@ -116,23 +117,17 @@ export async function executeOpenCode( const prompt = attempt === 1 ? initialPrompt : CONTINUATION_PROMPT const files = attempt === 1 ? promptOptions.fileParts : undefined - const result = await sendPromptToSession(client, sessionId, prompt, files, directory, config, logger) + const result = await (async () => { + try { + return await sendPromptToSession(client, sessionId, prompt, files, directory, config, logger) + } finally { + await reassertSessionTitle(client, sessionId, config?.sessionTitle, logger) + } + })() + if (result.success) { final = result.eventStreamResult - // Best-effort title re-assertion: OpenCode may auto-overwrite session titles - // based on first message content. Re-set to preserve deterministic lookup. - if (config?.sessionTitle != null) { - try { - await (client.session as unknown as {update: (args: Record) => Promise}).update({ - sessionID: sessionId, - title: config.sessionTitle, - }) - } catch { - logger.debug('Best-effort session title re-assertion failed', {sessionId}) - } - } - return { success: true, exitCode: 0, diff --git a/src/features/agent/opencode.test.ts b/src/features/agent/opencode.test.ts index 667b208a..655b0e8e 100644 --- a/src/features/agent/opencode.test.ts +++ b/src/features/agent/opencode.test.ts @@ -110,6 +110,7 @@ function createMockClient(options: { create: options.throwOnCreate ? vi.fn().mockRejectedValue(new Error('Session creation failed')) : vi.fn().mockResolvedValue({data: {id: 'ses_123', title: 'Test', version: '1'}}), + update: vi.fn().mockResolvedValue({data: {id: 'ses_123', title: 'Test', version: '1'}}), promptAsync: options.throwOnPrompt ? vi.fn().mockRejectedValue(new Error('Prompt failed')) : vi.fn().mockResolvedValue({data: options.promptResponse}), @@ -444,6 +445,70 @@ describe('executeOpenCode', () => { expect(result.duration).toBeGreaterThanOrEqual(0) }) + it('re-asserts session title with SDK update payload after prompt attempts', async () => { + // #given + const mockClient = createMockClient({ + promptResponse: {parts: [{type: 'text', text: 'Agent response'}]}, + }) + const mockOpencode = createMockOpencode({client: mockClient}) + vi.mocked(createOpencode).mockResolvedValue(mockOpencode as unknown as Awaited>) + const config: ExecutionConfig = { + agent: 'sisyphus', + model: null, + timeoutMs: 1800000, + omoProviders: { + claude: 'no', + copilot: 'no', + gemini: 'no', + openai: 'no', + opencodeZen: 'no', + zaiCodingPlan: 'no', + kimiForCoding: 'no', + }, + sessionTitle: 'fro-bot: schedule-c757a308', + } + + // #when + await executeOpenCode(createMockPromptOptions(), mockLogger, config) + + // #then + expect(mockClient.session.update).toHaveBeenCalledWith({ + path: {id: 'ses_123'}, + body: {title: 'fro-bot: schedule-c757a308'}, + }) + }) + + it('re-asserts session title even when prompt attempt fails', async () => { + // #given + const mockClient = createMockClient({throwOnPrompt: true}) + const mockOpencode = createMockOpencode({client: mockClient}) + vi.mocked(createOpencode).mockResolvedValue(mockOpencode as unknown as Awaited>) + const config: ExecutionConfig = { + agent: 'sisyphus', + model: null, + timeoutMs: 1800000, + omoProviders: { + claude: 'no', + copilot: 'no', + gemini: 'no', + openai: 'no', + opencodeZen: 'no', + zaiCodingPlan: 'no', + kimiForCoding: 'no', + }, + sessionTitle: 'fro-bot: schedule-c757a308', + } + + // #when + await executeOpenCode(createMockPromptOptions(), mockLogger, config) + + // #then + expect(mockClient.session.update).toHaveBeenCalledWith({ + path: {id: 'ses_123'}, + body: {title: 'fro-bot: schedule-c757a308'}, + }) + }) + it('returns failure result when prompt fails', async () => { // #given const mockClient = createMockClient({throwOnPrompt: true}) diff --git a/src/features/agent/prompt.test.ts b/src/features/agent/prompt.test.ts index ab24def3..874c4ca5 100644 --- a/src/features/agent/prompt.test.ts +++ b/src/features/agent/prompt.test.ts @@ -136,6 +136,25 @@ describe('buildAgentPrompt', () => { expect(prompt).toContain('**Status**: Continuing previous conversation thread.') }) + it('shows fresh thread identity status when logical key exists without continuation', () => { + // #given + const options: PromptOptions = { + context: createMockContext(), + customPrompt: null, + cacheStatus: 'hit', + logicalKey: createMockLogicalKey(), + isContinuation: false, + } + + // #when + const prompt = buildAgentPrompt(options, mockLogger) + + // #then + expect(prompt).toContain('## Thread Identity') + expect(prompt).toContain('**Logical Thread**: `pr-42` (pr #42)') + expect(prompt).toContain('**Status**: Fresh conversation — no prior thread found for this entity.') + }) + it('places current thread context above environment and historical context for continuation runs', () => { // #given const sessionContext: SessionContext = { @@ -570,6 +589,37 @@ describe('buildAgentPrompt', () => { expect(prompt).toContain('## GitHub Operations (Use gh CLI)') }) + it('skips Trigger Comment section when schedule prompt text matches trigger comment', () => { + // #given + const duplicatedTask = 'Run daily maintenance tasks and update the report issue.' + const context = createMockContext({ + eventName: 'schedule', + issueNumber: null, + issueTitle: null, + issueType: null, + commentBody: duplicatedTask, + }) + const triggerContext = createMockTriggerContext({ + eventType: 'schedule', + commentBody: duplicatedTask, + target: undefined, + }) + const options: PromptOptions = { + context, + customPrompt: ` ${duplicatedTask} `, + cacheStatus: 'hit', + triggerContext, + } + + // #when + const prompt = buildAgentPrompt(options, mockLogger) + + // #then + expect(prompt).toContain('## Task') + expect(prompt).toContain(duplicatedTask) + expect(prompt).not.toContain('## Trigger Comment') + }) + describe('session context', () => { it('includes session context section when sessionContext is provided', () => { // #given diff --git a/src/features/agent/prompt.ts b/src/features/agent/prompt.ts index 4e70cc00..10293e94 100644 --- a/src/features/agent/prompt.ts +++ b/src/features/agent/prompt.ts @@ -156,7 +156,16 @@ Respond to the trigger comment above. Follow all instructions and requirements l `) } - if (context.commentBody != null) { + const trimmedCustomPrompt = customPrompt?.trim() ?? null + const trimmedCommentBody = context.commentBody?.trim() ?? null + const triggerCommentDuplicatesTask = + trimmedCustomPrompt != null && + trimmedCustomPrompt.length > 0 && + trimmedCommentBody != null && + trimmedCommentBody.length > 0 && + trimmedCustomPrompt === trimmedCommentBody + + if (context.commentBody != null && !triggerCommentDuplicatesTask) { parts.push(`## Trigger Comment **Author:** ${context.commentAuthor ?? 'unknown'} diff --git a/src/harness/phases/execute.ts b/src/harness/phases/execute.ts index 5fce46d0..2e27e310 100644 --- a/src/harness/phases/execute.ts +++ b/src/harness/phases/execute.ts @@ -43,6 +43,9 @@ export async function runExecute( recentSessions: sessionPrep.recentSessions, priorWorkContext: sessionPrep.priorWorkContext, }, + logicalKey: sessionPrep.logicalKey ?? null, + isContinuation: sessionPrep.isContinuation, + currentThreadSessionId: sessionPrep.continueSessionId ?? null, triggerContext: routing.triggerResult.context, fileParts: sessionPrep.attachmentResult?.fileParts, } diff --git a/src/services/session/title-reassert.ts b/src/services/session/title-reassert.ts new file mode 100644 index 00000000..981337f4 --- /dev/null +++ b/src/services/session/title-reassert.ts @@ -0,0 +1,34 @@ +import type {Logger} from '../../shared/logger.js' +import type {SessionClient} from './backend.js' + +export async function reassertSessionTitle( + client: SessionClient, + sessionId: string, + title: string | undefined, + logger: Logger, +): Promise { + if (title == null) { + return + } + + try { + const response = await client.session.update({ + path: {id: sessionId}, + body: {title} as Record, + }) + + if (response.error != null) { + logger.warning('Best-effort session title re-assertion failed', { + sessionId, + sessionTitle: title, + error: String(response.error), + }) + } + } catch (error) { + logger.warning('Best-effort session title re-assertion failed', { + sessionId, + sessionTitle: title, + error: error instanceof Error ? error.message : String(error), + }) + } +} From 7c7f08d3afe7959688ad037817460f9059e18ed9 Mon Sep 17 00:00:00 2001 From: "Marcus R. Brown" Date: Sat, 28 Mar 2026 06:22:47 -0700 Subject: [PATCH 2/2] chore: update action build artifact --- dist/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/main.js b/dist/main.js index 1ac65dc2..5e8af93a 100644 --- a/dist/main.js +++ b/dist/main.js @@ -124,7 +124,7 @@ import{A as e,B as t,C as n,D as r,E as i,F as a,G as o,H as s,I as c,J as l,K a `);o=c.pop()??``;for(let e of c){let i=e.split(` `),a=[],o;for(let e of i)if(e.startsWith(`data:`))a.push(e.replace(/^data:\s*/,``));else if(e.startsWith(`event:`))o=e.replace(/^event:\s*/,``);else if(e.startsWith(`id:`))u=e.replace(/^id:\s*/,``);else if(e.startsWith(`retry:`)){let t=Number.parseInt(e.replace(/^retry:\s*/,``),10);Number.isNaN(t)||(s=t)}let c,l=!1;if(a.length){let e=a.join(` `);try{c=JSON.parse(e),l=!0}catch{c=e}}l&&(r&&await r(c),n&&(c=await n(c))),t?.({data:c,event:o,id:u,retry:s}),a.length&&(yield c)}}}finally{p.removeEventListener(`abort`,d),a.releaseLock()}break}catch(t){if(e?.(t),a!==void 0&&f>=a)break;await d(Math.min(s*2**(f-1),o??3e4))}}}()}},gt=async(e,t)=>{let n=typeof t==`function`?await t(e):t;if(n)return e.scheme===`bearer`?`Bearer ${n}`:e.scheme===`basic`?`Basic ${btoa(n)}`:n},_t={bodySerializer:e=>JSON.stringify(e,(e,t)=>typeof t==`bigint`?t.toString():t)},vt=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},yt=e=>{switch(e){case`form`:return`,`;case`pipeDelimited`:return`|`;case`spaceDelimited`:return`%20`;default:return`,`}},bt=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},xt=({allowReserved:e,explode:t,name:n,style:r,value:i})=>{if(!t){let t=(e?i:i.map(e=>encodeURIComponent(e))).join(yt(r));switch(r){case`label`:return`.${t}`;case`matrix`:return`;${n}=${t}`;case`simple`:return t;default:return`${n}=${t}`}}let a=vt(r),o=i.map(t=>r===`label`||r===`simple`?e?t:encodeURIComponent(t):St({allowReserved:e,name:n,value:t})).join(a);return r===`label`||r===`matrix`?a+o:o},St=({allowReserved:e,name:t,value:n})=>{if(n==null)return``;if(typeof n==`object`)throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${t}=${e?n:encodeURIComponent(n)}`},Ct=({allowReserved:e,explode:t,name:n,style:r,value:i,valueOnly:a})=>{if(i instanceof Date)return a?i.toISOString():`${n}=${i.toISOString()}`;if(r!==`deepObject`&&!t){let t=[];Object.entries(i).forEach(([n,r])=>{t=[...t,n,e?r:encodeURIComponent(r)]});let a=t.join(`,`);switch(r){case`form`:return`${n}=${a}`;case`label`:return`.${a}`;case`matrix`:return`;${n}=${a}`;default:return a}}let o=bt(r),s=Object.entries(i).map(([t,i])=>St({allowReserved:e,name:r===`deepObject`?`${n}[${t}]`:t,value:i})).join(o);return r===`label`||r===`matrix`?o+s:s},wt=/\{[^{}]+\}/g,Tt=({path:e,url:t})=>{let n=t,r=t.match(wt);if(r)for(let t of r){let r=!1,i=t.substring(1,t.length-1),a=`simple`;i.endsWith(`*`)&&(r=!0,i=i.substring(0,i.length-1)),i.startsWith(`.`)?(i=i.substring(1),a=`label`):i.startsWith(`;`)&&(i=i.substring(1),a=`matrix`);let o=e[i];if(o==null)continue;if(Array.isArray(o)){n=n.replace(t,xt({explode:r,name:i,style:a,value:o}));continue}if(typeof o==`object`){n=n.replace(t,Ct({explode:r,name:i,style:a,value:o,valueOnly:!0}));continue}if(a===`matrix`){n=n.replace(t,`;${St({name:i,value:o})}`);continue}let s=encodeURIComponent(a===`label`?`.${o}`:o);n=n.replace(t,s)}return n},Et=({baseUrl:e,path:t,query:n,querySerializer:r,url:i})=>{let a=i.startsWith(`/`)?i:`/${i}`,o=(e??``)+a;t&&(o=Tt({path:t,url:o}));let s=n?r(n):``;return s.startsWith(`?`)&&(s=s.substring(1)),s&&(o+=`?${s}`),o},Dt=({allowReserved:e,array:t,object:n}={})=>r=>{let i=[];if(r&&typeof r==`object`)for(let a in r){let o=r[a];if(o!=null)if(Array.isArray(o)){let n=xt({allowReserved:e,explode:!0,name:a,style:`form`,value:o,...t});n&&i.push(n)}else if(typeof o==`object`){let t=Ct({allowReserved:e,explode:!0,name:a,style:`deepObject`,value:o,...n});t&&i.push(t)}else{let t=St({allowReserved:e,name:a,value:o});t&&i.push(t)}}return i.join(`&`)},Ot=e=>{if(!e)return`stream`;let t=e.split(`;`)[0]?.trim();if(t){if(t.startsWith(`application/json`)||t.endsWith(`+json`))return`json`;if(t===`multipart/form-data`)return`formData`;if([`application/`,`audio/`,`image/`,`video/`].some(e=>t.startsWith(e)))return`blob`;if(t.startsWith(`text/`))return`text`}},kt=(e,t)=>t?!!(e.headers.has(t)||e.query?.[t]||e.headers.get(`Cookie`)?.includes(`${t}=`)):!1,At=async({security:e,...t})=>{for(let n of e){if(kt(t,n.name))continue;let e=await gt(n,t.auth);if(!e)continue;let r=n.name??`Authorization`;switch(n.in){case`query`:t.query||={},t.query[r]=e;break;case`cookie`:t.headers.append(`Cookie`,`${r}=${e}`);break;default:t.headers.set(r,e);break}}},jt=e=>Et({baseUrl:e.baseUrl,path:e.path,query:e.query,querySerializer:typeof e.querySerializer==`function`?e.querySerializer:Dt(e.querySerializer),url:e.url}),Mt=(e,t)=>{let n={...e,...t};return n.baseUrl?.endsWith(`/`)&&(n.baseUrl=n.baseUrl.substring(0,n.baseUrl.length-1)),n.headers=Nt(e.headers,t.headers),n},Nt=(...e)=>{let t=new Headers;for(let n of e){if(!n||typeof n!=`object`)continue;let e=n instanceof Headers?n.entries():Object.entries(n);for(let[n,r]of e)if(r===null)t.delete(n);else if(Array.isArray(r))for(let e of r)t.append(n,e);else r!==void 0&&t.set(n,typeof r==`object`?JSON.stringify(r):r)}return t};var Pt=class{_fns;constructor(){this._fns=[]}clear(){this._fns=[]}getInterceptorIndex(e){return typeof e==`number`?this._fns[e]?e:-1:this._fns.indexOf(e)}exists(e){let t=this.getInterceptorIndex(e);return!!this._fns[t]}eject(e){let t=this.getInterceptorIndex(e);this._fns[t]&&(this._fns[t]=null)}update(e,t){let n=this.getInterceptorIndex(e);return this._fns[n]?(this._fns[n]=t,e):!1}use(e){return this._fns=[...this._fns,e],this._fns.length-1}};const Ft=()=>({error:new Pt,request:new Pt,response:new Pt}),It=Dt({allowReserved:!1,array:{explode:!0,style:`form`},object:{explode:!0,style:`deepObject`}}),Lt={"Content-Type":`application/json`},Rt=(e={})=>({..._t,headers:Lt,parseAs:`auto`,querySerializer:It,...e}),zt=(e={})=>{let t=Mt(Rt(),e),n=()=>({...t}),r=e=>(t=Mt(t,e),n()),i=Ft(),a=async e=>{let n={...t,...e,fetch:e.fetch??t.fetch??globalThis.fetch,headers:Nt(t.headers,e.headers),serializedBody:void 0};return n.security&&await At({...n,security:n.security}),n.requestValidator&&await n.requestValidator(n),n.body&&n.bodySerializer&&(n.serializedBody=n.bodySerializer(n.body)),(n.serializedBody===void 0||n.serializedBody===``)&&n.headers.delete(`Content-Type`),{opts:n,url:jt(n)}},o=async e=>{let{opts:t,url:n}=await a(e),r={redirect:`follow`,...t,body:t.serializedBody},o=new Request(n,r);for(let e of i.request._fns)e&&(o=await e(o,t));let s=t.fetch,c=await s(o);for(let e of i.response._fns)e&&(c=await e(c,o,t));let l={request:o,response:c};if(c.ok){if(c.status===204||c.headers.get(`Content-Length`)===`0`)return t.responseStyle===`data`?{}:{data:{},...l};let e=(t.parseAs===`auto`?Ot(c.headers.get(`Content-Type`)):t.parseAs)??`json`,n;switch(e){case`arrayBuffer`:case`blob`:case`formData`:case`json`:case`text`:n=await c[e]();break;case`stream`:return t.responseStyle===`data`?c.body:{data:c.body,...l}}return e===`json`&&(t.responseValidator&&await t.responseValidator(n),t.responseTransformer&&(n=await t.responseTransformer(n))),t.responseStyle===`data`?n:{data:n,...l}}let u=await c.text(),d;try{d=JSON.parse(u)}catch{}let f=d??u,p=f;for(let e of i.error._fns)e&&(p=await e(f,c,o,t));if(p||={},t.throwOnError)throw p;return t.responseStyle===`data`?void 0:{error:p,...l}},s=e=>{let t=t=>o({...t,method:e});return t.sse=async t=>{let{opts:n,url:r}=await a(t);return ht({...n,body:n.body,headers:n.headers,method:e,url:r})},t};return{buildUrl:jt,connect:s(`CONNECT`),delete:s(`DELETE`),get:s(`GET`),getConfig:n,head:s(`HEAD`),interceptors:i,options:s(`OPTIONS`),patch:s(`PATCH`),post:s(`POST`),put:s(`PUT`),request:o,setConfig:r,trace:s(`TRACE`)}};Object.entries({$body_:`body`,$headers_:`headers`,$path_:`path`,$query_:`query`});const Bt=zt(Rt({baseUrl:`http://localhost:4096`}));var B=class{_client=Bt;constructor(e){e?.client&&(this._client=e.client)}},Vt=class extends B{event(e){return(e?.client??this._client).get.sse({url:`/global/event`,...e})}},Ht=class extends B{list(e){return(e?.client??this._client).get({url:`/project`,...e})}current(e){return(e?.client??this._client).get({url:`/project/current`,...e})}},Ut=class extends B{list(e){return(e?.client??this._client).get({url:`/pty`,...e})}create(e){return(e?.client??this._client).post({url:`/pty`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}remove(e){return(e.client??this._client).delete({url:`/pty/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/pty/{id}`,...e})}update(e){return(e.client??this._client).put({url:`/pty/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}connect(e){return(e.client??this._client).get({url:`/pty/{id}/connect`,...e})}},Wt=class extends B{get(e){return(e?.client??this._client).get({url:`/config`,...e})}update(e){return(e?.client??this._client).patch({url:`/config`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}providers(e){return(e?.client??this._client).get({url:`/config/providers`,...e})}},Gt=class extends B{ids(e){return(e?.client??this._client).get({url:`/experimental/tool/ids`,...e})}list(e){return(e.client??this._client).get({url:`/experimental/tool`,...e})}},Kt=class extends B{dispose(e){return(e?.client??this._client).post({url:`/instance/dispose`,...e})}},qt=class extends B{get(e){return(e?.client??this._client).get({url:`/path`,...e})}},Jt=class extends B{get(e){return(e?.client??this._client).get({url:`/vcs`,...e})}},Yt=class extends B{list(e){return(e?.client??this._client).get({url:`/session`,...e})}create(e){return(e?.client??this._client).post({url:`/session`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}status(e){return(e?.client??this._client).get({url:`/session/status`,...e})}delete(e){return(e.client??this._client).delete({url:`/session/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/session/{id}`,...e})}update(e){return(e.client??this._client).patch({url:`/session/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}children(e){return(e.client??this._client).get({url:`/session/{id}/children`,...e})}todo(e){return(e.client??this._client).get({url:`/session/{id}/todo`,...e})}init(e){return(e.client??this._client).post({url:`/session/{id}/init`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}fork(e){return(e.client??this._client).post({url:`/session/{id}/fork`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}abort(e){return(e.client??this._client).post({url:`/session/{id}/abort`,...e})}unshare(e){return(e.client??this._client).delete({url:`/session/{id}/share`,...e})}share(e){return(e.client??this._client).post({url:`/session/{id}/share`,...e})}diff(e){return(e.client??this._client).get({url:`/session/{id}/diff`,...e})}summarize(e){return(e.client??this._client).post({url:`/session/{id}/summarize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}messages(e){return(e.client??this._client).get({url:`/session/{id}/message`,...e})}prompt(e){return(e.client??this._client).post({url:`/session/{id}/message`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}message(e){return(e.client??this._client).get({url:`/session/{id}/message/{messageID}`,...e})}promptAsync(e){return(e.client??this._client).post({url:`/session/{id}/prompt_async`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}command(e){return(e.client??this._client).post({url:`/session/{id}/command`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}shell(e){return(e.client??this._client).post({url:`/session/{id}/shell`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}revert(e){return(e.client??this._client).post({url:`/session/{id}/revert`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}unrevert(e){return(e.client??this._client).post({url:`/session/{id}/unrevert`,...e})}},Xt=class extends B{list(e){return(e?.client??this._client).get({url:`/command`,...e})}},Zt=class extends B{authorize(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/authorize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}callback(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Qt=class extends B{list(e){return(e?.client??this._client).get({url:`/provider`,...e})}auth(e){return(e?.client??this._client).get({url:`/provider/auth`,...e})}oauth=new Zt({client:this._client})},$t=class extends B{text(e){return(e.client??this._client).get({url:`/find`,...e})}files(e){return(e.client??this._client).get({url:`/find/file`,...e})}symbols(e){return(e.client??this._client).get({url:`/find/symbol`,...e})}},en=class extends B{list(e){return(e.client??this._client).get({url:`/file`,...e})}read(e){return(e.client??this._client).get({url:`/file/content`,...e})}status(e){return(e?.client??this._client).get({url:`/file/status`,...e})}},tn=class extends B{log(e){return(e?.client??this._client).post({url:`/log`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}agents(e){return(e?.client??this._client).get({url:`/agent`,...e})}},nn=class extends B{remove(e){return(e.client??this._client).delete({url:`/mcp/{name}/auth`,...e})}start(e){return(e.client??this._client).post({url:`/mcp/{name}/auth`,...e})}callback(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}authenticate(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/authenticate`,...e})}set(e){return(e.client??this._client).put({url:`/auth/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},rn=class extends B{status(e){return(e?.client??this._client).get({url:`/mcp`,...e})}add(e){return(e?.client??this._client).post({url:`/mcp`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}connect(e){return(e.client??this._client).post({url:`/mcp/{name}/connect`,...e})}disconnect(e){return(e.client??this._client).post({url:`/mcp/{name}/disconnect`,...e})}auth=new nn({client:this._client})},an=class extends B{status(e){return(e?.client??this._client).get({url:`/lsp`,...e})}},on=class extends B{status(e){return(e?.client??this._client).get({url:`/formatter`,...e})}},sn=class extends B{next(e){return(e?.client??this._client).get({url:`/tui/control/next`,...e})}response(e){return(e?.client??this._client).post({url:`/tui/control/response`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}},cn=class extends B{appendPrompt(e){return(e?.client??this._client).post({url:`/tui/append-prompt`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}openHelp(e){return(e?.client??this._client).post({url:`/tui/open-help`,...e})}openSessions(e){return(e?.client??this._client).post({url:`/tui/open-sessions`,...e})}openThemes(e){return(e?.client??this._client).post({url:`/tui/open-themes`,...e})}openModels(e){return(e?.client??this._client).post({url:`/tui/open-models`,...e})}submitPrompt(e){return(e?.client??this._client).post({url:`/tui/submit-prompt`,...e})}clearPrompt(e){return(e?.client??this._client).post({url:`/tui/clear-prompt`,...e})}executeCommand(e){return(e?.client??this._client).post({url:`/tui/execute-command`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}showToast(e){return(e?.client??this._client).post({url:`/tui/show-toast`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}publish(e){return(e?.client??this._client).post({url:`/tui/publish`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}control=new sn({client:this._client})},ln=class extends B{subscribe(e){return(e?.client??this._client).get.sse({url:`/event`,...e})}},un=class extends B{postSessionIdPermissionsPermissionId(e){return(e.client??this._client).post({url:`/session/{id}/permissions/{permissionID}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}global=new Vt({client:this._client});project=new Ht({client:this._client});pty=new Ut({client:this._client});config=new Wt({client:this._client});tool=new Gt({client:this._client});instance=new Kt({client:this._client});path=new qt({client:this._client});vcs=new Jt({client:this._client});session=new Yt({client:this._client});command=new Xt({client:this._client});provider=new Qt({client:this._client});find=new $t({client:this._client});file=new en({client:this._client});app=new tn({client:this._client});mcp=new rn({client:this._client});lsp=new an({client:this._client});formatter=new on({client:this._client});tui=new cn({client:this._client});auth=new nn({client:this._client});event=new ln({client:this._client})};function dn(e){if(!e?.fetch){let t=e=>(e.timeout=!1,fetch(e));e={...e,fetch:t}}return e?.directory&&(e.headers={...e.headers,"x-opencode-directory":encodeURIComponent(e.directory)}),new un({client:zt(e)})}async function fn(e){e=Object.assign({hostname:`127.0.0.1`,port:4096,timeout:5e3},e??{});let t=[`serve`,`--hostname=${e.hostname}`,`--port=${e.port}`];e.config?.logLevel&&t.push(`--log-level=${e.config.logLevel}`);let n=je(`opencode`,t,{signal:e.signal,env:{...process.env,OPENCODE_CONFIG_CONTENT:JSON.stringify(e.config??{})}});return{url:await new Promise((t,r)=>{let i=setTimeout(()=>{r(Error(`Timeout waiting for server to start after ${e.timeout}ms`))},e.timeout),a=``;n.stdout?.on(`data`,e=>{a+=e.toString();let n=a.split(` -`);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function pn(e){let t=await fn({...e});return{client:dn({baseUrl:t.url}),server:t}}async function mn(e,t,n,r){if(n!=null)try{let i=await e.session.update({path:{id:t},body:{title:n}});i.error!=null&&r.warning(`Best-effort session title re-assertion failed`,{sessionId:t,sessionTitle:n,error:String(i.error)})}catch{r.warning(`Best-effort session title re-assertion failed`,{sessionId:t,sessionTitle:n})}}async function hn(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const gn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function _n(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function vn(e){let t=_n(e),n=gn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` +`);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function pn(e){let t=await fn({...e});return{client:dn({baseUrl:t.url}),server:t}}async function mn(e,t,n,r){if(n!=null)try{let i=await e.session.update({path:{id:t},body:{title:n}});i.error!=null&&r.warning(`Best-effort session title re-assertion failed`,{sessionId:t,sessionTitle:n,error:String(i.error)})}catch(e){r.warning(`Best-effort session title re-assertion failed`,{sessionId:t,sessionTitle:n,error:e instanceof Error?e.message:String(e)})}}async function hn(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const gn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function _n(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function vn(e){let t=_n(e),n=gn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` `)}function yn(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const bn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function xn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return bn.some(e=>e.test(t))}function Sn(e,t){return yn(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function Cn(e,t){return yn(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}async function wn(e,t,i,a,o,s=n,c){let l=Date.now(),u=0;for(;!a.aborted;){if(await hn(500),a.aborted)return{completed:!1,error:`Aborted`};if(c?.sessionError==null)u=0;else{if(u++,u>=3)return o.error(`Session error persisted through grace period`,{sessionId:t,error:c.sessionError,graceCycles:u}),{completed:!1,error:`Session error: ${c.sessionError}`};continue}if(c?.sessionIdle===!0)return o.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let n=Date.now()-l;if(s>0&&n>=s)return o.warning(`Poll timeout reached`,{elapsedMs:n,maxPollTimeMs:s}),{completed:!1,error:`Poll timeout after ${n}ms`};try{let n=((await e.session.status({query:{directory:i}})).data??{})[t];if(n==null)o.debug(`Session status not found in poll response`,{sessionId:t});else if(n.type===`idle`)return o.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else o.debug(`Session status`,{sessionId:t,type:n.type});if(c!=null&&!c.firstMeaningfulEventReceived){let e=Date.now()-l;if(e>=9e4)return o.error(`No agent activity detected — server may have crashed during prompt processing`,{elapsedMs:e,sessionId:t}),{completed:!1,error:`No agent activity detected after ${e}ms — server may have crashed during prompt processing`}}}catch(e){o.debug(`Poll request failed`,{error:r(e)})}}return{completed:!1,error:`Aborted`}}async function Tn(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}function En(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function Dn(e){try{let t=new URL(e);return t.hostname===`github.com`&&(t.pathname.startsWith(`/user-attachments/assets/`)||t.pathname.startsWith(`/user-attachments/files/`))}catch{return!1}}function On(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(En)}function kn(e){let t=/\[[\w-]+\s+([a-f0-9]{7,40})\]/g,n=[];for(let r of e.matchAll(t))r[1]!=null&&n.push(r[1]);return[...new Set(n)]}const An={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},jn=`\x1B[0m`;function Mn(){return N.env.NO_COLOR==null}function Nn(e,t){let[n,r]=An[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);Mn()?N.stdout.write(`\n${r}|${jn} ${i} ${jn}${t}\n`):N.stdout.write(`\n| ${i} ${t}\n`)}function Pn(e){N.stdout.write(`\n${e}\n`)}function Fn(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function In(e,t,n,r,i){let a=On(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=kn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function Ln(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(Fn(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(Pn(a),a=``)}else if(e.type===`tool`){let t=e.state;t.status===`completed`&&(Nn(e.tool,t.title),e.tool.toLowerCase()===`bash`&&In(String(t.input.command??t.input.cmd??``),String(t.output),l,u,()=>{d++}))}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error,t=typeof e==`string`?e:String(e);r.error(`Session error`,{error:e}),f=xn(e)?Sn(t,s??void 0):Cn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(Pn(a),a=``))}return a.length>0&&Pn(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}const Rn=5e3;async function zn(e,t,n,r,i){let a=new AbortController,o={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},s=await e.event.subscribe(),c={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},l=Ln(s.stream,t,a.signal,i,o).then(e=>{c=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&i.debug(`Event stream error`,{error:e.message})}),u=async()=>{a.abort(),await Tn(l)};try{let s=await wn(e,t,n,a.signal,i,r,o);if(await u(),!s.completed){let e=s.error??`Session did not reach idle state`;return i.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:c.llmError,shouldRetry:c.llmError!=null,eventStreamResult:c}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:c}}finally{a.abort(),await Tn(l)}}const Bn=e=>{if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!(e!=null&&Object.values(e.omoProviders).some(e=>e!==`no`)))return{providerID:E.providerID,modelID:E.modelID}};async function Vn(e,t,n,r,i,a,o){let s={parts:[{type:`text`,text:n},...r??[]]},c=Bn(a);c!=null&&(s.model=c);let l=a?.agent??`sisyphus`;l!==`sisyphus`&&(s.agent=l);let u=await e.session.promptAsync({path:{id:t},body:s,query:{directory:i}});if(u.error!=null){let e=String(u.error),t=xn(u.error)?Sn(e):null;return{success:!1,error:e,llmError:t,shouldRetry:t!=null,eventStreamResult:{tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:t}}}return zn(e,t,i,a?.timeoutMs??18e5,o)}function Hn(){return[`## Critical Rules (NON-NEGOTIABLE)`,`- You are a NON-INTERACTIVE CI agent. Do NOT ask questions. Make decisions autonomously.`,`- Post EXACTLY ONE comment or review per invocation. Never multiple.`,`- Include the Run Summary marker block in your comment.`,"- Use `gh` CLI for all GitHub operations. Do not use the GitHub API directly.",`- Mark your comment with the bot identification marker.`].join(` `)}function Un(e,t,n){if(e==null)return``;let r=[`## Thread Identity`];return r.push(`**Logical Thread**: \`${e.key}\` (${e.entityType} #${e.entityId})`),t?(r.push(`**Status**: Continuing previous conversation thread.`),n!=null&&n.length>0&&(r.push(``),r.push(`**Thread Summary**:`),r.push(n))):r.push(`**Status**: Fresh conversation — no prior thread found for this entity.`),r.join(` `)}function Wn(e){return e==null||e.length===0?``:[`## Current Thread Context`,`This is work from your PREVIOUS runs on this same entity:`,``,e].join(`