diff --git a/dist/main.js b/dist/main.js index db7c4eb9c9..8cb16b68aa 100644 --- a/dist/main.js +++ b/dist/main.js @@ -120,7 +120,7 @@ import{o as e}from"./rolldown-runtime-DaDcL9Zw.js";import{$ as t,A as n,B as r,C } `,{owner:t,repo:n,number:r,maxComments:i,maxCommits:a,maxFiles:o,maxReviews:s})}catch(e){return c.warning(`GraphQL pull request query failed`,{owner:t,repo:n,number:r,error:E(e)}),null}}async function Jn(e,t,n,r,i,a){let o=await Kn(e,t,n,r,i.maxComments,a);if(o==null)return null;let s=o.repository.issue;if(s==null)return a.debug(`Issue not found`,{owner:t,repo:n,number:r}),null;let c=Hn(s.body??``,i.maxBodyBytes),l=s.comments.nodes,u=l.slice(Math.max(0,l.length-i.maxComments)),d=s.comments.totalCount>u.length,f=u.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),p=s.labels.nodes.map(e=>({name:e.name,color:e.color})),m=s.assignees.nodes.map(e=>({login:e.login}));return{type:`issue`,number:s.number,title:s.title,body:c.text,bodyTruncated:c.truncated,state:s.state,author:s.author?.login??null,createdAt:s.createdAt,labels:p,assignees:m,comments:f,commentsTruncated:d,totalComments:s.comments.totalCount}}async function Yn(e,t,n,r,i,a){let o=await qn(e,t,n,r,i.maxComments,i.maxCommits,i.maxFiles,i.maxReviews,a);if(o==null)return null;let s=o.repository.pullRequest;if(s==null)return a.debug(`Pull request not found`,{owner:t,repo:n,number:r}),null;let c=Hn(s.body??``,i.maxBodyBytes),l=s.baseRepository?.owner.login,u=s.headRepository?.owner.login,d=u==null||l!==u,f=s.comments.nodes,p=f.slice(Math.max(0,f.length-i.maxComments)),m=s.comments.totalCount>p.length,h=p.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),g=s.commits.nodes,_=g.slice(Math.max(0,g.length-i.maxCommits)),v=s.commits.totalCount>_.length,y=_.map(e=>({oid:e.commit.oid,message:e.commit.message,author:e.commit.author?.name??null})),b=s.files.nodes.slice(0,i.maxFiles),x=s.files.totalCount>b.length,S=b.map(e=>({path:e.path,additions:e.additions,deletions:e.deletions})),C=s.reviews.nodes,w=C.slice(Math.max(0,C.length-i.maxReviews)),ee=s.reviews.totalCount>w.length,T=w.map(e=>({author:e.author?.login??null,state:e.state,body:e.body,createdAt:e.createdAt,comments:e.comments.nodes.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,path:e.path,line:e.line,createdAt:e.createdAt}))})),E=s.labels.nodes.map(e=>({name:e.name,color:e.color})),te=s.assignees.nodes.map(e=>({login:e.login})),ne=s.reviewRequests.nodes.map(e=>`login`in e.requestedReviewer?e.requestedReviewer.login:null).filter(e=>e!=null),re=s.reviewRequests.nodes.map(e=>`name`in e.requestedReviewer?e.requestedReviewer.name:null).filter(e=>e!=null);return{type:`pull_request`,number:s.number,title:s.title,body:c.text,bodyTruncated:c.truncated,state:s.state,author:s.author?.login??null,createdAt:s.createdAt,baseBranch:s.baseRefName,headBranch:s.headRefName,isFork:d,labels:E,assignees:te,comments:h,commentsTruncated:m,totalComments:s.comments.totalCount,commits:y,commitsTruncated:v,totalCommits:s.commits.totalCount,files:S,filesTruncated:x,totalFiles:s.files.totalCount,reviews:T,reviewsTruncated:ee,totalReviews:s.reviews.totalCount,authorAssociation:s.authorAssociation,requestedReviewers:ne,requestedReviewerTeams:re}}const Xn={PER_PAGE:100,MAX_PAGES:50};async function Zn(e,t,n,r,i){i.debug(`Fetching PR diff`,{prNumber:r});let a=[],o=1,s=!1;for(;o<=Xn.MAX_PAGES;){let{data:c}=await e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:Xn.PER_PAGE,page:o}),l=c.map(e=>({filename:e.filename,status:e.status,additions:e.additions,deletions:e.deletions,patch:e.patch??null,previousFilename:e.previous_filename??null}));if(a.push(...l),c.lengthXn.MAX_PAGES&&(s=!0,i.warning(`PR diff pagination limit reached`,{filesLoaded:a.length,maxPages:Xn.MAX_PAGES}))}let c=a.reduce((e,t)=>({additions:e.additions+t.additions,deletions:e.deletions+t.deletions}),{additions:0,deletions:0});return i.debug(`Fetched diff`,{files:a.length,additions:c.additions,deletions:c.deletions,truncated:s}),{files:a,additions:c.additions,deletions:c.deletions,changedFiles:a.length,truncated:s}}function Qn(e,t,n){let r=[],i=[];for(let a of e){let e=t.files.find(e=>e.filename===a.path);if(e==null){n.warning(`File not in diff, skipping comment`,{path:a.path}),i.push({comment:a,reason:`file_not_in_diff`});continue}if(e.patch==null){n.warning(`File has no patch, skipping comment`,{path:a.path}),i.push({comment:a,reason:`patch_missing`});continue}let o={path:a.path,body:a.body,line:a.line,side:a.side};a.startLine!=null&&a.startLine!==a.line&&(o.start_line=a.startLine,o.start_side=a.startSide??a.side),r.push(o)}return{ready:r,skipped:i}}async function $n(e,t,n){let{prNumber:r,owner:i,repo:a,event:o,body:s,comments:c,commitSha:l}=t;n.info(`Submitting review`,{prNumber:r,event:o,commentCount:c.length});let u=[],d=0;if(c.length>0){let t=Qn(c,await Zn(e,i,a,r,n),n);u=t.ready,d=t.skipped.length}let{data:f}=await e.rest.pulls.createReview({owner:i,repo:a,pull_number:r,event:o,body:s,...l===void 0?{}:{commit_id:l},comments:u.map(e=>({path:e.path,body:e.body,line:e.line,side:e.side,start_line:e.start_line,start_side:e.start_side}))});return n.info(`Review submitted`,{reviewId:f.id,state:f.state,commentsPosted:u.length,commentsSkipped:d}),{reviewId:f.id,state:f.state??``,commentsPosted:u.length,commentsSkipped:d,url:f.html_url??``}}async function er(e,t,n,r){if(e.eventType!==`pull_request`)return null;let i=e.target?.number;if(i==null)return r.debug(`No PR number in trigger context, skipping diff collection`),null;let[a,o]=n.split(`/`);if(a==null||o==null)return r.warning(`Invalid repo format, skipping diff collection`,{repo:n}),null;try{let e=await Zn(t,a,o,i,r),n={changedFiles:e.changedFiles,additions:e.additions,deletions:e.deletions,truncated:e.truncated,files:e.files.slice(0,50).map(e=>({filename:e.filename,status:e.status,additions:e.additions,deletions:e.deletions}))};return r.debug(`Collected diff context`,{files:n.changedFiles,additions:n.additions,deletions:n.deletions,truncated:n.truncated}),n}catch(e){return r.warning(`Failed to fetch PR diff`,{error:E(e)}),null}}async function tr(e){let{logger:t,octokit:n,triggerContext:r,botLogin:i}=e,{repo:a,ref:o,actor:s,runId:c,target:l,author:u,commentBody:d,commentId:f}=r,p=`${a.owner}/${a.repo}`,m=l?.kind===`issue`||l?.kind===`pr`?l.kind:null,h=l!=null&&l.kind!==`manual`?l.number:null,g=l?.title??null,_=u?.login??null,v=await er(r,n,p,t),y=await nr(n,a.owner,a.repo,h,m,t),b=y?.type===`pull_request`?y:null,x=b?.authorAssociation??null,S=i!=null&&b!=null&&b.requestedReviewers.includes(i);return t.info(`Collected agent context`,{eventName:r.eventName,repo:p,issueNumber:h,issueType:m,hasComment:d!=null,hasDiffContext:v!=null,hasHydratedContext:y!=null}),{eventName:r.eventName,repo:p,ref:o,actor:s,runId:String(c),issueNumber:h,issueTitle:g,issueType:m,commentBody:d,commentAuthor:_,commentId:f,defaultBranch:await In(n,p,t),diffContext:v,hydratedContext:y,authorAssociation:x,isRequestedReviewer:S}}async function nr(e,t,n,r,i,a){if(r==null||i==null)return null;let o=Bn;return i===`issue`?await Jn(e,t,n,r,o,a)??Wn(e,t,n,r,o,a):await Yn(e,t,n,r,o,a)??Gn(e,t,n,r,o,a)}function rr(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function ir(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 ar(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(rr)}function or(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)]}function sr(e){if(q(e,`type`)!==`retry`)return null;let t=q(Y(e,`action`),`reason`);if(t==null)return null;let n=J(e,`next`),r=n!=null&&Number.isFinite(n)?new Date(n):void 0,i=r!=null&&!Number.isNaN(r.getTime())?r:void 0;return Ct({kind:`retry-status`,reason:t})??Ot({kind:`retry-status`,reason:t,resetAt:i})}function cr(e){return e.type===`context_overflow`||e.type===`quota_exceeded`||e.type===`provider_auth_error`}function lr(e,t,n,r){let i=n?.terminalProviderError;if(i!=null)return i;let a=cr(t),o=e!=null&&cr(e),s=e??t;return o?s=e:a&&(s=t),n!=null&&cr(s)?(n.terminalProviderError=s,n.sessionError=s.message,n.currentTurnTerminalSignalReceived=!0,s):(n!=null&&n.sessionError==null&&r!=null&&(n.sessionError=r),s)}function ur(e,t){let n=q(e,`type`);if(n===`sync`){let n=q(e,`name`)?.replace(/\.\d+$/,``)??`sync`,r=K(Y(e,`data`));t.debug(`Server event`,{eventKind:n,sessionID:r})}else{let r=Y(e,`properties`),i=K(r)??K(Y(r,`part`));t.debug(`Server event`,i==null?{eventType:n}:{eventType:n,sessionId:i})}}function dr(e,t,n,r,i,a){let o=ar(t);if(e.includes(`gh pr create`)){let e=o.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=or(t);for(let t of e)r.includes(t)||r.push(t)}if(e.includes(`gh issue comment`)||e.includes(`gh pr comment`)){let e=o.filter(e=>e.includes(`#issuecomment`));for(let t of e)(a==null||!a.includes(t))&&(a?.push(t),i())}}function K(e){if(typeof e!=`object`||!e)return null;let t=Object.getOwnPropertyDescriptor(e,`sessionID`);return typeof t?.value==`string`?t.value:null}function q(e,t){if(typeof e!=`object`||!e)return null;let n=Object.getOwnPropertyDescriptor(e,t);return typeof n?.value==`string`?n.value:null}function J(e,t){if(typeof e!=`object`||!e)return null;let n=Object.getOwnPropertyDescriptor(e,t);return typeof n?.value==`number`?n.value:null}function fr(e,t){if(typeof e!=`object`||!e)return null;let n=Object.getOwnPropertyDescriptor(e,t);return typeof n?.value==`boolean`?n.value:null}function Y(e,t){return typeof e!=`object`||!e?null:Object.getOwnPropertyDescriptor(e,t)?.value??null}const pr=`Unknown session error`;function mr(e,t){let n=q(e,t);if(n==null||n.length===0)return null;let r=n.replaceAll(/[\r\n]+/g,`; `).trim();return r.length===0?null:r.length<=256?r:`${r.slice(0,253)}...`}function hr(e,t,n){return mr(e,n)??mr(t,n)}function gr(e){if(typeof e==`string`)return e;if(typeof e!=`object`||!e)return pr;let t=Y(e,`data`),n=hr(e,t,`provider`),r=hr(e,t,`name`),i=hr(e,t,`code`),a=J(e,`status`)??J(e,`statusCode`)??J(t,`status`)??J(t,`statusCode`),o=[];return n!=null&&o.push(`provider=${n}`),r!=null&&o.push(`name=${r}`),a!=null&&Number.isFinite(a)&&o.push(`status=${a}`),i!=null&&o.push(`code=${i}`),o.length>0?o.join(`; `):pr}function _r(e){return K(Y(e,`properties`))??K(Y(e,`data`))}function vr(e){let t=q(e,`type`);return t===`sync`?q(e,`name`)?.replace(/\.\d+$/,``)??t:t}function yr(e){return Y(e,`properties`)??Y(e,`data`)}function br(e){return e===`message.part.delta`||e?.startsWith(`session.next.`)===!0}async function xr(e,t,n,r,i,a){let o=``,s=null,c=null,l=null,u=[],d=[],f=[],p=0,m=null,h,g=new Map;for await(let _ of e){if(n.aborted)break;if(ur(_,r),i?.currentTurnArmed===!1)continue;let e=vr(_),v=yr(_);if(i!=null&&br(e)&&_r(_)===t&&(i.firstMeaningfulEventReceived=!0),e===`message.part.delta`){if(_r(_)===t){let e=Y(v,`delta`),t=q(e,`type`),n=q(e,`text`);t===`text`&&n!=null?o+=n:typeof e==`string`&&q(v,`field`)===`text`&&(o+=e)}}else if(e===`session.next.text.delta`){if(_r(_)===t){let e=Y(v,`delta`),t=typeof e==`string`?e:q(e,`text`)??null;t!=null&&(o+=t)}}else if(e===`session.next.tool.called`){if(_r(_)===t){let e=q(v,`callID`),t=q(v,`tool`),n=Y(v,`input`);e!=null&&t!=null&&(g.set(e,{tool:t,input:n}),r.debug(`Tool called`,{callID:e,tool:t}))}}else if(e===`session.next.tool.success`){if(_r(_)===t){let e=q(v,`callID`);if(e===null)continue;let t=g.get(e);if(t!==void 0){g.delete(e);let{tool:n,input:r}=t;if(Sn(n,q(Y(v,`structured`),`title`)??q(r,`title`)??(n.toLowerCase()===`bash`?String(Y(r,`command`)??Y(r,`cmd`)??n):n)),n.toLowerCase()===`bash`){let e=String(Y(r,`command`)??Y(r,`cmd`)??``),t=Y(v,`content`);dr(e,Array.isArray(t)?t.map(e=>q(e,`type`)===`text`?q(e,`text`)??``:``).join(` `):``,u,d,()=>{p++},f)}}}}else if(e===`message.part.updated`){let e=Y(v,`part`);if((K(v)??K(e))!==t)continue;i!=null&&(i.firstMeaningfulEventReceived=!0);let n=q(e,`type`);if(n===`text`){let t=q(e,`text`);t!=null&&(o=t),J(Y(e,`time`),`end`)!=null&&(Cn(o),o=``)}else if(n===`tool`){let t=Y(e,`state`);if(q(t,`status`)===`completed`){let n=q(e,`tool`)??``;if(Sn(n,String(Y(t,`title`)??``)),n.toLowerCase()===`bash`){let e=Y(t,`input`);dr(String(Y(e,`command`)??Y(e,`cmd`)??``),String(Y(t,`output`)??``),u,d,()=>{p++},f)}}}}else if(e===`message.updated`){let e=Y(v,`info`),n=K(v)??K(e),a=Y(e,`tokens`);n===t&&q(e,`role`)===`assistant`&&a!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),s={input:J(a,`input`)??0,output:J(a,`output`)??0,reasoning:J(a,`reasoning`)??0,cache:{read:J(Y(a,`cache`),`read`)??0,write:J(Y(a,`cache`),`write`)??0}},c=q(e,`modelID`),l=J(e,`cost`),r.debug(`Token usage received`,{tokens:s,model:c,cost:l}))}else if(e===`session.status`){if(K(v)===t){let e=sr(Y(v,`status`));if(e!=null){if(a?.isExpired()===!0&&i?.terminalProviderError==null)continue;r.error(`Session status retry classified as terminal provider error`,{sessionId:t,type:e.type}),h=`structured`,m=lr(m,e,i)}}}else if(e===`session.error`){if(K(v)===t){let e=Y(v,`error`);r.error(`Session error received`,{sessionType:typeof e});let n=Y(e,`data`),o=J(e,`status`)??J(e,`statusCode`)??J(n,`status`)??J(n,`statusCode`),s=q(e,`code`)??q(n,`code`),l=q(e,`name`)??q(n,`name`),u=q(e,`message`)??q(n,`message`)??(typeof e==`string`?e:void 0),d=Ct({kind:`session-error`,name:l})??Tt({kind:`session-error`,name:l})??Ot({kind:`session-error`,status:o??void 0,code:s??void 0,message:u??void 0});if(d!=null){if(a?.isExpired()===!0&&i?.terminalProviderError==null)continue;r.error(`Session error classified as terminal provider error`,{sessionId:t,type:d.type}),h=`structured`,m=lr(m,d,i)}else if(m==null||cr(m)===!1){let t=gr(e),r,a;if(_t(t))r=vt(t,c??void 0),a=`fallback`;else if(o===429)r=G(`rate_limit`,t,!0),a=`name`;else{let i=fr(e,`isRetryable`)??fr(n,`isRetryable`);i===!0?(r=yt(t,c??void 0),a=`structured`):i===!1?(r=bt(t),a=`structured`):(r=bt(t),a=l!=null||o!=null||s!=null?`name`:`unclassified`)}h??=a,m=lr(m,r,i,t)}}}else e===`session.idle`&&K(v)===t&&(i!=null&&(i.sessionIdle=!0,i.currentTurnTerminalSignalReceived=!0),o.length>0&&(Cn(o),o=``))}return o.length>0&&Cn(o),{tokens:s,model:c,cost:l,prsCreated:u,commitsCreated:d,commentsPostedUrls:f,commentsPosted:p,llmError:m,classificationPath:h}}function Sr(e,t){let n=[],r=[],i=[],a=0;for(let o of e)if(q(o,`type`)===`tool`){let e=Y(o,`state`);if(q(e,`status`)===`completed`&&(q(o,`tool`)??``).toLowerCase()===`bash`){let o=Y(e,`input`),s=String(Y(o,`command`)??Y(o,`cmd`)??``),c=String(Y(e,`output`)??``);t.debug(`Artifact scan: bash tool part`,{command:s.slice(0,80)}),dr(s,c,n,r,()=>{a++},i)}}return{prsCreated:n,commitsCreated:r,commentsPostedUrls:i,commentsPosted:a}}const Cr=5e3;function wr(e,t){if(typeof e!=`object`||!e)return null;let n=Object.getOwnPropertyDescriptor(e,t);return typeof n?.value==`string`?n.value:null}function Tr(e,t){if(typeof e!=`object`||!e)return null;let n=Object.getOwnPropertyDescriptor(e,t);return typeof n?.value==`number`?n.value:null}function Er(e,t){return typeof e!=`object`||!e?null:Object.getOwnPropertyDescriptor(e,t)?.value??null}async function Dr(e,t){return t?.aborted===!0?Promise.resolve():new Promise(n=>{let r,i,a=()=>{r!=null&&clearTimeout(r),t!=null&&i!=null&&t.removeEventListener(`abort`,i),n()};r=setTimeout(a,e),t!=null&&(i=a,t.addEventListener(`abort`,i,{once:!0}))})}async function Or(e,t,n,r){let i,a;try{let o=r==null?null:new Promise((e,t)=>{a=()=>t(Error(`${n} aborted`)),r.addEventListener(`abort`,a,{once:!0})});return await Promise.race([e,new Promise((e,r)=>{i=setTimeout(()=>{r(Error(`${n} timed out after ${t}ms`))},t)}),...o==null?[]:[o]])}finally{i!=null&&clearTimeout(i),r!=null&&a!=null&&r.removeEventListener(`abort`,a)}}async function kr(e,t,n,r){let i=async()=>Or(e(),Math.min(Cr,r?.remainingMs()??Cr),t,n);return r==null?i():r.run(i,t)}async function Ar(e,t,n,r,i,a,o){if(r?.baselineMessageIds==null)return null;if(typeof e.session.messages!=`function`)return i.debug(`session.messages() unavailable; skipping message activity poll`,{sessionId:t}),null;let s=await kr(async()=>e.session.messages({path:{id:t},query:{directory:n},signal:a}),`session.messages()`,a,o),c=Array.isArray(s.data)?s.data:[],l=null;for(let e of c){let t=Er(e,`info`),n=wr(t,`id`);n==null||r.baselineMessageIds.has(n)||wr(t,`role`)===`assistant`&&(l=t)}if(l==null)return null;r.firstMeaningfulEventReceived=!0;let u=wr(l,`id`),d=Tr(Er(l,`time`),`completed`);return u==null||d==null?(r.completedAssistantMessageId=void 0,null):r.completedAssistantMessageId===u?(r.currentTurnTerminalSignalReceived=!0,i.debug(`Session completion detected via stable completed assistant message`,{sessionId:t,messageId:u}),{completed:!0,error:null}):(r.completedAssistantMessageId=u,i.debug(`Completed assistant message observed; waiting for confirmation poll`,{sessionId:t,messageId:u}),null)}async function jr(e,t,n,r,i,a=_,o,s){let c=Date.now(),l=0,u=null;for(;!r.aborted;){let d=o?.terminalProviderError;if(d!=null)return{completed:!1,error:d.message};if(s?.isExpired()===!0)return{completed:!1,error:`Aborted`};try{let e=async()=>{await Dr(500,r)};s==null?await e():await s.run(e,`poll interval`)}catch{let e=o?.terminalProviderError;return e==null?{completed:!1,error:`Aborted`}:{completed:!1,error:e.message}}if(r.aborted){let e=o?.terminalProviderError;return e==null?{completed:!1,error:`Aborted`}:{completed:!1,error:e.message}}let f=o?.sessionError;u==null&&f!=null&&(u=f);let p=o?.terminalProviderError;if(p!=null)return{completed:!1,error:p.message};let m=u;if(m==null)l=0;else{if(l++,l>=3)return i.error(`Session error persisted through grace period`,{sessionId:t,error:m,graceCycles:l}),{completed:!1,error:`Session error: ${m}`};continue}if(o?.sessionIdle===!0&&o.currentTurnTerminalSignalReceived)return i.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let h=Date.now()-c;if(s==null&&a>0&&h>=a)return i.warning(`Poll timeout reached`,{elapsedMs:h,maxPollTimeMs:a}),{completed:!1,error:`Poll timeout after ${h}ms`};try{let a=await Ar(e,t,n,o,i,r,s);if(a!=null)return a;let l=((await kr(async()=>e.session.status({query:{directory:n},signal:r}),`session.status()`,r,s)).data??{})[t];if(l==null)i.debug(`Session status not found in poll response`,{sessionId:t});else if(l.type===`idle`)if(o!=null&&o.currentTurnTerminalSignalReceived!==!0)i.debug(`Session idle detected before terminal signal; continuing watchdog`,{sessionId:t});else return i.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else if(l.type===`retry`){let e=sr(l);if(e!=null)return s?.isExpired()===!0&&o?.terminalProviderError==null?{completed:!1,error:`Aborted`}:(i.error(`Session status retry classified as terminal provider error via poll`,{sessionId:t,type:l.type}),o!=null&&lr(null,e,o),{completed:!1,error:o?.terminalProviderError?.message??e.message});i.debug(`Session status`,{sessionId:t,type:l.type})}else i.debug(`Session status`,{sessionId:t,type:l.type});if(o!=null&&!o.firstMeaningfulEventReceived){let e=Date.now()-c;if(e>=9e4)return i.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){i.debug(`Poll request failed`,{error:E(e)})}}return{completed:!1,error:`Aborted`}}async function Mr(e,t=2e3,n){if(n?.aborted===!0)return;let r,i,a=n==null?null:new Promise(e=>{i=()=>e(),n.addEventListener(`abort`,i,{once:!0})});try{await Promise.race([e,new Promise(e=>{r=setTimeout(e,t)}),...a==null?[]:[a]])}finally{r!=null&&clearTimeout(r),n!=null&&i!=null&&n.removeEventListener(`abort`,i)}}function Nr(e){let t=Error(`${e} exceeded the execution deadline`);return t.name=`DeadlineExceededError`,t}function Pr(e,t){let n=new AbortController,r=e>0?Date.now()+e:null,i=null,a=!1,o=()=>{a||(a=!0,t.warning(`Execution timeout reached`,{timeoutMs:e}),n.abort())},s=()=>a?!0:r!=null&&Date.now()>=r?(o(),!0):!1;return r!=null&&(i=setTimeout(o,e)),{timeoutMs:e,signal:n.signal,isExpired:s,isTimedOut:()=>a,remainingMs:()=>{if(r==null)return 1/0;let e=Math.max(0,r-Date.now());return e===0&&o(),e},run:async(e,t)=>{if(s())throw Nr(t);if(r==null)return e();let i=null,o=new Promise((e,r)=>{i=()=>r(Nr(t)),n.signal.addEventListener(`abort`,i,{once:!0})}),c=Promise.resolve().then(e);try{let e=await Promise.race([c,o]);if(s())throw Nr(t);return e}catch(e){throw a?Nr(t):e}finally{i!=null&&n.signal.removeEventListener(`abort`,i)}},dispose:()=>{i!=null&&clearTimeout(i)}}}function Fr(e){if(typeof e!=`object`||!e)return null;let t=Object.getOwnPropertyDescriptor(e,`id`);return typeof t?.value==`string`?t.value:null}function Ir(e,t){if(typeof e!=`object`||!e)return null;let n=Object.getOwnPropertyDescriptor(e,t);return typeof n?.value==`string`?n.value:null}function Lr(e,t){if(typeof e!=`object`||!e)return null;let n=Object.getOwnPropertyDescriptor(e,t);return typeof n?.value==`number`?n.value:null}function Rr(e,t){return typeof e!=`object`||!e?null:Object.getOwnPropertyDescriptor(e,t)?.value??null}const zr=5e3;function Br(e,t){return[...e,...t.filter(t=>!e.includes(t))]}async function Vr(e,t,n,r){let i,a;try{let o=r==null?null:new Promise((e,t)=>{a=()=>t(Error(`${n} aborted`)),r.addEventListener(`abort`,a,{once:!0})});return await Promise.race([e,new Promise((e,r)=>{i=setTimeout(()=>{r(Error(`${n} timed out after ${t}ms`))},t)}),...o==null?[]:[o]])}finally{i!=null&&clearTimeout(i),r!=null&&a!=null&&r.removeEventListener(`abort`,a)}}async function Hr(e,t,n,r,i){if(typeof e.session.messages!=`function`)return null;try{let r=async()=>Vr(e.session.messages({path:{id:t},query:{directory:n},signal:i?.signal}),Math.min(zr,i?.remainingMs()??zr),`baseline session.messages()`,i?.signal),a=i==null?await r():await i.run(r,`baseline session.messages()`),o=Array.isArray(a.data)?a.data:[];return new Set(o.flatMap(e=>Fr(Rr(e,`info`))??[]))}catch(e){return r.debug(`Unable to read baseline session messages; disabling message activity fallback`,{sessionId:t,error:E(e)}),null}}async function Ur(e,t,n,r,i,a){if(r==null||typeof e.session.messages!=`function`)return null;try{let i=async()=>Vr(e.session.messages({path:{id:t},query:{directory:n},signal:a?.signal}),Math.min(zr,a?.remainingMs()??zr),`completed assistant session.messages()`,a?.signal),o=a==null?await i():await a.run(i,`completed assistant session.messages()`),s=Array.isArray(o.data)?o.data:[],c=null,l=-1/0;for(let e of s){let t=Rr(e,`info`),n=Ir(t,`id`);if(n==null||r.has(n)||Ir(t,`role`)!==`assistant`)continue;let i=Rr(t,`time`);if(Lr(i,`completed`)==null)continue;let a=Lr(i,`created`)??0;(c==null||a>=l)&&(c=e,l=a)}if(c!=null){let e=Rr(c,`parts`);if(Array.isArray(e))return Array.from(e,e=>e)}return null}catch(e){return i.debug(`Unable to read completed assistant message parts`,{sessionId:t,error:E(e)}),null}}function Wr(e,t){let n=Br(e.commentsPostedUrls??[],t.commentsPostedUrls??[]);return{...e,prsCreated:Br(e.prsCreated,t.prsCreated),commitsCreated:Br(e.commitsCreated,t.commitsCreated),commentsPostedUrls:n,commentsPosted:n.length>0?n.length:Math.max(e.commentsPosted,t.commentsPosted)}}const Gr=[5e3,15e3,3e4,6e4];function Kr(e){return e===`turn_failed_retryable`}async function qr(e){if(e==null)return null;try{let{createOpencodeClient:t}=await import(`./v2-DHi3eQ5C.js`);return t({baseUrl:e})}catch{return null}}async function Jr(e,t,n,r,i,a){let o=a==null?await qr(e):await a.run(async()=>qr(e),`v2 client creation`);if(o==null)return`fallback-to-poll`;try{let e=a==null?await o.v2.session.wait({sessionID:t},{signal:i}):await a.run(async()=>o.v2.session.wait({sessionID:t},{signal:i}),`v2 session wait`);if(e.error!=null)return r.debug(`v2.session.wait() returned error, relying on poll watchdog`,{sessionId:t,error:String(e.error)}),`fallback-to-poll`;let s=Date.now()+500;for(;n.currentTurnTerminalSignalReceived!==!0&&Date.now(){await Dr(10,i)};a==null?await e():await a.run(e,`v2 terminal grace wait`)}return n.currentTurnTerminalSignalReceived===!0?n.terminalProviderError==null?(r.debug(`v2.session.wait() resolved with terminal signal — session is done`,{sessionId:t}),`succeeded`):(r.debug(`v2.session.wait() resolved after terminal provider error — reporting failure, not success`,{sessionId:t}),`terminal-provider-failed`):(r.debug(`v2.session.wait() resolved without terminal signal — deferring to poll watchdog`,{sessionId:t}),`fallback-to-poll`)}catch(e){return r.debug(`v2.session.wait() threw, relying on poll watchdog`,{sessionId:t,error:E(e)}),`fallback-to-poll`}}async function Yr(e,t,n,r,i,a,o,s,c,l){let u=l??new AbortController,d=new AbortController,f=new AbortController,p=c==null?d.signal:AbortSignal.any([d.signal,c.signal]),m=c==null?f.signal:AbortSignal.any([f.signal,c.signal]),h={firstMeaningfulEventReceived:!1,currentTurnTerminalSignalReceived:!1,currentTurnArmed:s==null,baselineMessageIds:void 0,sessionIdle:!1,sessionError:null},g=c==null?u.signal:AbortSignal.any([u.signal,c.signal]),_=async()=>e.event.subscribe({signal:g}),v=a??(c==null?(await _()).stream:(await c.run(_,`event subscription`)).stream),y={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},b=xr(v,t,p,i,h,c).then(e=>{y=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&i.debug(`Event stream error`,{error:e.message})}),x=null,S=async()=>x??(u.abort(),f.abort(),d.abort(),x=Mr(b),x),C=async()=>{await S()};try{if(await Promise.resolve(),s!=null){h.baselineMessageIds=await Hr(e,t,n,i,c)??void 0,h.currentTurnArmed=!0;let r=c==null?await s():await c.run(s,`prompt submission`);if(r!=null){if(await C(),h.firstMeaningfulEventReceived===!0){let e=y.llmError??r.llmError,t=e?.retryable===!0?`turn_failed_retryable`:`turn_failed_terminal`;return{...r,error:r.error,llmError:e,outcome:t,shouldRetry:Kr(t),eventStreamResult:y}}return r}}let a=jr(e,t,n,p,i,r,h,c),l=Jr(o,t,h,i,m,c),u=await Promise.race([l.then(e=>e===`succeeded`?{completed:!0,error:null}:e===`terminal-provider-failed`?{completed:!1,error:h.terminalProviderError?.message??`Terminal provider error`}:a),a]);if(c?.isExpired()===!0&&h.terminalProviderError==null)throw Nr(`prompt attempt`);if(await C(),h.terminalProviderError!=null&&y.llmError?.type!==h.terminalProviderError.type&&(y={...y,llmError:h.terminalProviderError}),h.terminalProviderError!=null){let e=h.terminalProviderError,t=`turn_failed_terminal`;return{success:!1,error:e.message,llmError:e,outcome:t,shouldRetry:Kr(t),eventStreamResult:y}}if(!u.completed){let e=u.error??`Session did not reach idle state`;i.error(`Session completion polling failed`,{error:e,sessionId:t});let n=y.llmError?.retryable===!0?`turn_failed_retryable`:`turn_failed_terminal`;return{success:!1,error:e,llmError:y.llmError,outcome:n,shouldRetry:Kr(n),eventStreamResult:y}}if(c?.isTimedOut()===!0){let e=`timeout`;return{success:!0,error:null,llmError:null,outcome:e,shouldRetry:Kr(e),eventStreamResult:y}}let d=await Ur(e,t,n,h.baselineMessageIds,i,c);if(d!=null){let e=Sr(d,i),t=Wr(y,e),n=`completed`;return{success:!0,error:null,llmError:null,outcome:n,shouldRetry:Kr(n),eventStreamResult:t}}let f=`completed`;return{success:!0,error:null,llmError:null,outcome:f,shouldRetry:Kr(f),eventStreamResult:y}}finally{await S()}}function Xr(e,t){let n=t===!0?`Before taking any action, verify what has already landed, including external changes and response artifacts, and do not repeat completed side effects.`:`Inspect the current session state before continuing and do not repeat completed work.`;return[`The previous turn was accepted but ended with the observed failure type \`${e.type}\`.`,`Continue the remaining objective from the current session; do not resend or replay the original request.`,n].join(` -`)}const Zr=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:c.providerID,modelID:c.modelID}};async function Qr(e,t,n,r,i,a,o,s,c){let l={parts:[{type:`text`,text:n},...r??[]]},u=Zr(a);u!=null&&(l.model=u);let d=a?.agent??null;d!=null&&(l.agent=d);let f=new AbortController;try{let n=c==null?f.signal:AbortSignal.any([f.signal,c.signal]),r=async()=>e.event.subscribe({signal:n}),u=c==null?await r():await c.run(r,`event subscription`),d=(e,t)=>{let n=_t(t)?vt(e):null,r=`submit_failed`;return{success:!1,error:e,llmError:n,outcome:r,shouldRetry:Kr(r),eventStreamResult:{tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:n,classificationPath:n==null?`unclassified`:`fallback`}}},p=async()=>{let n=await e.session.promptAsync({path:{id:t},body:l,query:{directory:i},signal:c?.signal});return n.error==null?null:d(String(n.error),n.error)};return await(async()=>Yr(e,t,i,a?.timeoutMs??18e5,o,u.stream,s,p,c,f))()}finally{f.abort()}}function $r(e,t){return t?.eventType===`pull_request`?`pr-review`:e.issueType===`pr`?`pr-comment`:`issue-comment`}function ei(e){return e instanceof Error&&`code`in e&&e.code===`ENOENT`}async function ti(e,t,n){if(e==null)return`absent`;let r;try{r=await H.readFile(e,`utf8`)}catch(t){return ei(t)?`absent`:(n.warning(`Response-file status is unknown; declining recovery`,{responseFilePath:e,error:t instanceof Error?t.message:String(t)}),`unknown`)}let i=pe(r,{surface:t});return i.success===!0?`present`:(n.warning(`Response file is not a valid deliverable; allowing recovery`,{responseFilePath:e,reason:i.error.reason}),`absent`)}const ni=2e3;async function ri(e,t,n){if(typeof e.session.abort!=`function`)return;let r=new AbortController,i=null,a=!1;try{let n=e.session.abort({path:{id:t},signal:r.signal}),o=new Promise((e,t)=>{i=setTimeout(()=>{a=!0,r.abort(),t(Error(`Session abort timed out after ${ni}ms`))},ni)});await Promise.race([n,o])}catch(e){a?n.warning(`OpenCode session abort exceeded teardown budget; continuing teardown`,{sessionId:t}):n.debug(`OpenCode session abort failed; continuing teardown`,{sessionId:t,error:E(e)})}finally{i!=null&&clearTimeout(i)}}async function ii(e,n,r,i){let a=Date.now(),o=r?.timeoutMs??18e5,s=Pr(o,n),c=i==null,l=null,u=null,d=null,f={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},p=null,m=!0;n.info(`Executing OpenCode agent (SDK mode)`,{agent:r?.agent??`build (default)`,hasModelOverride:r?.model!=null,timeoutMs:o});let h=()=>({success:!1,exitCode:130,duration:Date.now()-a,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:f.tokens,model:f.model,cost:f.cost,prsCreated:f.prsCreated,commitsCreated:f.commitsCreated,commentsPosted:f.commentsPosted,llmError:p,classificationPath:f.classificationPath});try{let o=null;if(i==null){let e=await s.run(async()=>x(async()=>t({signal:s.signal}),n),`OpenCode server creation`);u=e.client,l=e.server,o=e.server.url}else u=i.client,o=i.server.url;if(u==null)throw Error(`OpenCode client was not initialized`);let c=u;if(r?.continueSessionId==null){let e=r?.sessionTitle==null?void 0:{body:{title:r.sessionTitle}},t=await s.run(async()=>e==null?c.session.create({signal:s.signal}):c.session.create({...e,signal:s.signal}),`session creation`);if(t.data==null||t.error!=null)throw Error(`Failed to create session: ${t.error==null?`No data returned`:String(t.error)}`);d=t.data.id,n.info(`Created new OpenCode session`,{sessionId:d,sessionTitle:r?.sessionTitle??null})}else d=r.continueSessionId,n.info(`Continuing existing OpenCode session`,{sessionId:d});if(d==null)throw Error(`OpenCode session was not initialized`);let g=d,{text:_,referenceFiles:v}=le({...e,sessionId:d},n),y=ue(),b=Me();if(await s.run(async()=>H.mkdir(b,{recursive:!0}),`OpenCode log directory creation`),C()){let e=qe.createHash(`sha256`).update(_).digest(`hex`),t=U.join(b,`prompt-${d}-${e.slice(0,8)}.txt`);try{await s.run(async()=>H.writeFile(t,_,`utf8`),`prompt artifact write`),n.info(`Prompt artifact written`,{hash:e,path:t})}catch(e){n.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:t})}}let S=await s.run(async()=>Ft(v,b,n),`reference file materialization`),w=[...e.fileParts??[],...S],ee=null,T=!1,E={kind:`initial`};for(let t=1;t<=4;t++){if(s.isExpired())return h();let i=Gr[Math.min(t-1,Gr.length-1)]??Gr[0],l=E.kind===`initial`?_:Xr(E.error,r?.credentialProvisioned===!0),u=w.length>0?w:void 0,v=await(async()=>{try{let e=await Qr(c,g,l,u,y,r,n,o,s);return m=!1,e}finally{s.isExpired()===!1&&await $t(c,g,r?.sessionTitle,n,{signal:s.signal,isExpired:s.isExpired,remainingMs:s.remainingMs})}})();if(f=Wr(v.eventStreamResult,f),v.success)return{success:!0,exitCode:0,duration:Date.now()-a,sessionId:d,error:null,tokenUsage:f.tokens,model:f.model,cost:f.cost,prsCreated:f.prsCreated,commitsCreated:f.commitsCreated,commentsPosted:f.commentsPosted,llmError:null,classificationPath:f.classificationPath};ee=v.error,p=v.llmError;let b=T;if(v.outcome!==`submit_failed`&&(T=!0),await ti(e.responseFilePath,$r(e.context,e.triggerContext),n)!==`absent`)break;let x=v.outcome===`submit_failed`&&b===!1&&v.llmError?.retryable===!0,S=v.outcome===`turn_failed_retryable`;if(x===!1&&S===!1||t>=4||s.isExpired())break;if(S){if(v.llmError==null)break;E={kind:`continuation`,error:v.llmError}}else E={kind:`initial`};m=!0,n.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:t,maxAttempts:4,error:v.error,delayMs:i,sessionId:d}),await s.run(async()=>{await Dr(i,s.signal)},`retry delay`)}return{success:!1,exitCode:1,duration:Date.now()-a,sessionId:d,error:ee??`Unknown error`,tokenUsage:f.tokens,model:f.model,cost:f.cost,prsCreated:f.prsCreated,commitsCreated:f.commitsCreated,commentsPosted:f.commentsPosted,llmError:p,classificationPath:f.classificationPath}}catch(e){if(s.isTimedOut())return h();let t=Date.now()-a,r=E(e),i=_t(e);return n.error(`OpenCode execution failed`,{error:r,durationMs:t}),{success:!1,exitCode:1,duration:t,sessionId:d,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:i?vt(r):null,classificationPath:i?`fallback`:`unclassified`}}finally{m&&s.isTimedOut()&&u!=null&&d!=null&&await ri(u,d,n),s.dispose(),c&&l?.close()}}async function ai(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await An(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function oi(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await Nn(e,t.repo,`agent: working`,`fcf2e1`,`Agent is currently working on this`,n)&&await Pn(e,t.repo,t.issueNumber,[`agent: working`],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function si(e,t,n){await Promise.all([ai(e,t,n),oi(e,t,n)])}async function ci(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await jn(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Mn(e,t.repo,t.commentId,r.id,n)}async function li(e,t,n,r){t.commentId!=null&&await An(e,t.repo,t.commentId,n,r)}async function ui(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await ci(e,t,n),await li(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:E(e)})}}async function di(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await ci(e,t,n),await li(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:E(e)})}}async function fi(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Fn(e,t.repo,t.issueNumber,`agent: working`,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function pi(e,t,n,r){n?await ui(e,t,r):await di(e,t,r),await fi(e,t,r)}var X=e(ce(),1),mi=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())})},hi=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 mi(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},Z=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())})},gi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const _i=process.platform===`win32`;process.platform;function vi(e,t,n,r){return Z(this,void 0,void 0,function*(){return t||=V.join(Ni(),He.randomUUID()),yield a(V.dirname(t)),L(`Downloading ${e}`),L(`Destination ${t}`),yield new hi(3,Pi(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Pi(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>Z(this,void 0,void 0,function*(){return yield yi(e,t||``,n,r)}),e=>!(e instanceof gi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function yi(e,t,n,r){return Z(this,void 0,void 0,function*(){if(B.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new s(`actions/tool-cache`,[],{allowRetries:!1});n&&(L(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new gi(a.message.statusCode);throw L(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=We.promisify(ft.pipeline),c=Pi(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,B.createWriteStream(t)),L(`download complete`),l=!0,t}finally{if(!l){L(`download failed`);try{yield Fe(t)}catch(e){L(`Failed to delete '${t}'. ${e.message}`)}}}})}function bi(e,t){return Z(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Di(t),L(`Checking tar --version`);let r=``;yield A(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),L(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],ve()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return _i&&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 A(`tar`,a),t})}function xi(e,t){return Z(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Di(t),_i?yield Si(e,t):yield Ci(e,t),t})}function Si(e,t){return Z(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 T(`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(` `)];L(`Using pwsh at path: ${i}`),yield A(`"${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 T(`powershell`,!0);L(`Using powershell at path: ${t}`),yield A(`"${t}"`,e)}})}function Ci(e,t){return Z(this,void 0,void 0,function*(){let n=yield T(`unzip`,!0),r=[e];ve()||r.unshift(`-q`),r.unshift(`-o`),yield A(`"${n}"`,r,{cwd:t})})}function wi(e,t,n,r){return Z(this,void 0,void 0,function*(){if(n=X.clean(n)||n,r||=Ve.arch(),L(`Caching tool ${t} ${n} ${r}`),L(`source dir: ${e}`),!B.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield Oi(t,n,r);for(let t of B.readdirSync(e))yield w(V.join(e,t),i,{recursive:!0});return ki(t,n,r),i})}function Ti(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=Ve.arch(),Ai(t)||(t=ji(Ei(e,n),t));let r=``;if(t){t=X.clean(t)||``;let i=V.join(Mi(),e,t,n);L(`checking cache: ${i}`),B.existsSync(i)&&B.existsSync(`${i}.complete`)?(L(`Found tool in cache ${e} ${t} ${n}`),r=i):L(`not found`)}return r}function Ei(e,t){let n=[];t||=Ve.arch();let r=V.join(Mi(),e);if(B.existsSync(r)){let e=B.readdirSync(r);for(let i of e)if(Ai(i)){let e=V.join(r,i,t||``);B.existsSync(e)&&B.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Di(e){return Z(this,void 0,void 0,function*(){return e||=V.join(Ni(),He.randomUUID()),yield a(e),e})}function Oi(e,t,n){return Z(this,void 0,void 0,function*(){let r=V.join(Mi(),e,X.clean(t)||t,n||``);L(`destination ${r}`);let i=`${r}.complete`;return yield Fe(r),yield Fe(i),yield a(r),r})}function ki(e,t,n){let r=`${V.join(Mi(),e,X.clean(t)||t,n||``)}.complete`;B.writeFileSync(r,``),L(`finished caching tool`)}function Ai(e){let t=X.clean(e)||``;L(`isExplicit: ${t}`);let n=X.valid(t)!=null;return L(`explicit? ${n}`),n}function ji(e,t){let n=``;L(`evaluating ${e.length} versions`),e=e.sort((e,t)=>X.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(X.satisfies(i,t)){n=i;break}}return L(n?`matched: ${n}`:`match not found`),n}function Mi(){let e=process.env.RUNNER_TOOL_CACHE||``;return Ue(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function Ni(){let e=process.env.RUNNER_TEMP||``;return Ue(e,`Expected RUNNER_TEMP to be defined`),e}function Pi(e,t){let n=global[e];return n===void 0?t:n}function Fi(){return{find:Ti,downloadTool:vi,extractTar:bi,extractZip:xi,cacheDir:wi}}function Ii(){return{exec:A,getExecOutput:Le}}function Li(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 Ri(e,t,n){let r=U.join(t,`auth.json`);await H.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await H.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function zi(){let e=z.platform,t=z.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Bi(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 Vi(e,t,n,r,i=Pe){let a=zi(),o=t.find(`bun`,i,a.arch);if(o.length>0)return e.info(`Bun found in cache`,{version:i,path:o}),r(o),await Ui(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Bi(i,a);try{let o=await t.downloadTool(s);if(z.platform!==`win32`&&!await Wi(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Hi(await t.extractZip(o),t),l=nt.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Ui(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=E(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Hi(e,t){for(let n of await Xe.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=nt.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Hi(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Hi(i,t)}throw Error(`Could not find executable: bun`)}async function Ui(e){let t=e=>z.platform===`win32`?`${e}.exe`:e,n=nt.join(e,t(`bun`));try{await Xe.symlink(n,nt.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 Wi(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}}const Gi=[`oh-my-openagent`],Ki=[`oh-my-opencode-slim`],qi=[`1.1.1`];function Ji(e){return qi.includes(e)}function Yi(e){let t=e.lastIndexOf(`@`);return t>0?e.slice(0,t):e}function Xi(e){let t=Yi(e);return Gi.includes(t)}function Zi(e){let t=Yi(e);return Ki.includes(t)}function Qi(e){let t=e.filter(e=>typeof e==`string`&&Xi(e)).length;return{cleaned:e.filter(e=>typeof e!=`string`||!Xi(e)),removed:t>0}}function $i(e){let t=e.filter(e=>typeof e==`string`&&Zi(e)).length;return{cleaned:e.filter(e=>typeof e!=`string`||!Zi(e)),removed:t>0}}function ea(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ta(e,t){let n=ea(e.agent)?e.agent:{},r=ea(n.build)?n.build:{},i=ea(r.permission)?r.permission:{},a=t!=null&&t.length>0?{"*":`deny`,[U.join(t,ke,`*`)]:`allow`}:`deny`;e.agent={...n,build:{...r,permission:{...i,external_directory:a}}}}function na(e,t){let n=e.enableOmoSlim??!1,r=e.omoSlimVersion??`1.1.2`,i=e.omoSlimPreset??`openai`,a={autoupdate:!1};if(e.opencodeConfig!=null){let t;try{t=JSON.parse(e.opencodeConfig)}catch{return{config:a,error:`opencode-config must be valid JSON`}}if(typeof t!=`object`||!t||Array.isArray(t))return{config:a,error:`opencode-config must be a JSON object`};Object.assign(a,t)}let o=Array.isArray(a.plugin)?a.plugin:[],s=o.some(e=>typeof e==`string`&&Xi(e)),c=o.some(e=>typeof e==`string`&&Zi(e));if(s&&c)return{config:a,error:`oMo and OMO Slim plugins cannot both be present`};if(n&&!qi.includes(r))return{config:a,error:`OMO Slim version ${r} is not verified to register the orchestrator agent (known-good: ${qi.join(`, `)})`};let l=`@fro.bot/systematic@${e.systematicVersion}`,u=Array.isArray(a.plugin)?a.plugin:[];if(u.some(e=>typeof e==`string`&&e.startsWith(`@fro.bot/systematic`))||(a.plugin=[...u,l]),n){let{cleaned:n}=Qi(Array.isArray(a.plugin)?a.plugin:[]),{cleaned:o}=$i(n),s=`oh-my-opencode-slim@${r}`;a.plugin=[...o,s],`plugins`in a&&delete a.plugins,a.default_agent=`orchestrator`,t.debug(`Built CI OpenCode config (slim mode)`,{hasUserConfig:e.opencodeConfig!=null,pluginCount:Array.isArray(a.plugin)?a.plugin.length:0,preset:i})}else if(e.enableOmo)t.debug(`Built CI OpenCode config`,{hasUserConfig:e.opencodeConfig!=null,pluginCount:Array.isArray(a.plugin)?a.plugin.length:0});else{let n=[],{cleaned:r,removed:i}=Qi(Array.isArray(a.plugin)?a.plugin:[]);i&&(n.push(`plugin`),a.plugin=r),`plugins`in a&&(delete a.plugins,n.push(`plugins`));let o=a.default_agent;a.default_agent=`build`,ta(a,z.env.RUNNER_TEMP),o!=null&&o!==`build`&&n.push(`default_agent`),n.length>0&&t.warning(`OpenCode config rewritten for disabled oMo mode (enable-omo: false): ${n.join(`, `)}. oMo plugin entries are stripped and default_agent is pinned to "build". Set enable-omo: true to use oMo features.`),t.debug(`Built CI OpenCode config`,{hasUserConfig:e.opencodeConfig!=null,pluginCount:Array.isArray(a.plugin)?a.plugin.length:0})}return{config:a,error:null}}function ra(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function ia(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),Ae(t,{log:ra(n)})}async function aa(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 oa(e,t,n,r,i,a=!0){let o=t??n,s=t==null?n.length>0?`github-token`:`none`:`app-token`;if(o.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};if(a?z.env.GH_TOKEN=o:delete z.env.GH_CONFIG_DIR,r.info(`Configured authentication`,{method:s}),a&&o.length>0)try{let e=await $e(W(z.env.RUNNER_TEMP!=null&&z.env.RUNNER_TEMP.length>0?z.env.RUNNER_TEMP:ct(),`gh-config-`));await Ze(e,448);let t={...z.env,GH_CONFIG_DIR:e};delete t.GH_TOKEN,delete t.GITHUB_TOKEN;let n=await i.getExecOutput(`gh`,[`auth`,`login`,`--with-token`],{env:t,input:Ke.from(o,`utf8`),silent:!0,ignoreReturnCode:!0});if(n.exitCode===0){z.env.GH_CONFIG_DIR=e;try{await Ze(W(e,`hosts.yml`),384)}catch{}}else r.warning(`gh auth login failed; model gh CLI usage in the child may be unauthenticated`,{exitCode:n.exitCode})}catch(e){r.warning(`Failed to configure off-environment gh auth; child gh CLI will be unauthenticated`,{error:E(e)})}let c=null;return e!=null&&(c=await aa(e,r)),{authenticated:!0,method:s,botLogin:c}}async function sa(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 ca(e,t,n,r){let i=await sa(`user.name`,r),a=await sa(`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 zn(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})}async function la(e,t,n){let{logger:r,execAdapter:i}=t;r.info(`Installing Oh My OpenCode Slim plugin`,{version:e,preset:n});let a=``,o=[`oh-my-opencode-slim@${e}`,`install`,`--no-tui`,`--reset`,`--preset=${n}`];try{let t=await i.exec(`bunx`,o,{listeners:{stdout:e=>{a+=e.toString()},stderr:e=>{a+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-opencode-slim install returned exit code ${t}`;return r.error(e,{output:a.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${a.slice(0,500)}`}}let n=/oh-my-opencode-slim@(\d+\.\d+\.\d+)/i.exec(a),s=n!=null&&n[1]!=null?n[1]:e;return r.info(`OMO Slim plugin installed`,{version:s}),{installed:!0,version:s,error:null}}catch(e){let t=E(e),n=a.length>0?`${t}\nOutput: ${a.slice(0,500)}`:t;return r.error(`Failed to run OMO Slim installer`,{error:t,output:a.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-opencode-slim install failed: ${n}`}}}async function ua(e,t,n={}){let{logger:r,execAdapter:i}=t,{claude:a=`no`,copilot:o=`no`,gemini:s=`no`,openai:c=`no`,opencodeZen:l=`no`,zaiCodingPlan:u=`no`,kimiForCoding:d=`no`}=n;r.info(`Installing Oh My OpenAgent plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u,kimiForCoding:d});let f=``,p=[`oh-my-openagent@${e}`,`install`,`--no-tui`,`--skip-auth`,`--claude=${a}`,`--copilot=${o}`,`--gemini=${s}`,`--openai=${c}`,`--opencode-zen=${l}`,`--zai-coding-plan=${u}`,`--kimi-for-coding=${d}`];try{let t=await i.exec(`bunx`,p,{listeners:{stdout:e=>{f+=e.toString()},stderr:e=>{f+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-openagent install returned exit code ${t}`;return r.error(e,{output:f.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${f.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(f),a=n!=null&&n[1]!=null?n[1]:e;return r.info(`oMo plugin installed`,{version:a}),{installed:!0,version:a,error:null}}catch(e){let t=E(e),n=f.length>0?`${t}\nOutput: ${f.slice(0,500)}`:t;return r.error(`Failed to run oMo installer`,{error:t,output:f.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-openagent install failed: ${n}`}}}const da=`opencode`,fa=`https://github.com/fro-bot/agent/releases/download`,pa=`+harness.`,ma=`1.18.14`,ha=/^\d+\.\d+\.\d+(?:[.-][\w.-]+)?(?:\+[\w.-]+)?$/;function ga(e){return e.includes(pa)}function _a(e){return e.includes(pa)?e.replace(pa,`-harness.`):e}function va(){let e=ot.platform(),t=ot.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 ya(e){return(e.startsWith(`v`)?e.slice(1):e).replaceAll(`+`,`%2B`)}function ba(e){let t=e.startsWith(`v`)?e.slice(1):e;if(!ha.test(t))throw Error(`Invalid version string: "${e}". Must match semver-ish pattern (no path traversal or shell metacharacters).`)}function xa(e,t){ba(e);let n=`opencode-${t.os}-${t.arch}${t.ext}`;if(ga(e)){let t=ya(e);return`${fa}/${t}/${n}`}return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${n}`}function Sa(e){if(ba(e),!ga(e))throw Error(`buildChecksumsUrl requires a harness version (must contain +harness.)`);let t=ya(e);return`${fa}/${t}/SHA256SUMS`}async function Ca(e,t,n,r,i){let a=Sa(t);i.debug(`Downloading SHA256SUMS for harness release`,{url:a});let o=dt(await r.downloadTool(a),`utf8`),s=`opencode-${n.os}-${n.arch}${n.ext}`,c=o.split(` +`)}const Zr=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:c.providerID,modelID:c.modelID}};async function Qr(e,t,n,r,i,a,o,s,c){let l={parts:[{type:`text`,text:n},...r??[]]},u=Zr(a);u!=null&&(l.model=u);let d=a?.agent??null;d!=null&&(l.agent=d);let f=new AbortController;try{let n=c==null?f.signal:AbortSignal.any([f.signal,c.signal]),r=async()=>e.event.subscribe({signal:n}),u=c==null?await r():await c.run(r,`event subscription`),d=(e,t)=>{let n=_t(t)?vt(e):null,r=`submit_failed`;return{success:!1,error:e,llmError:n,outcome:r,shouldRetry:Kr(r),eventStreamResult:{tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:n,classificationPath:n==null?`unclassified`:`fallback`}}},p=async()=>{let n=await e.session.promptAsync({path:{id:t},body:l,query:{directory:i},signal:c?.signal});return n.error==null?null:d(String(n.error),n.error)};return await(async()=>Yr(e,t,i,a?.timeoutMs??18e5,o,u.stream,s,p,c,f))()}finally{f.abort()}}function $r(e,t){return t?.eventType===`pull_request`?`pr-review`:e.issueType===`pr`?`pr-comment`:`issue-comment`}function ei(e){return e instanceof Error&&`code`in e&&e.code===`ENOENT`}async function ti(e,t,n){if(e==null)return`absent`;let r;try{r=await H.readFile(e,`utf8`)}catch(t){return ei(t)?`absent`:(n.warning(`Response-file status is unknown; declining recovery`,{responseFilePath:e,error:t instanceof Error?t.message:String(t)}),`unknown`)}let i=pe(r,{surface:t});return i.success===!0?`present`:(n.warning(`Response file is not a valid deliverable; allowing recovery`,{responseFilePath:e,reason:i.error.reason}),`absent`)}const ni=2e3;async function ri(e,t,n){if(typeof e.session.abort!=`function`)return;let r=new AbortController,i=null,a=!1;try{let n=e.session.abort({path:{id:t},signal:r.signal}),o=new Promise((e,t)=>{i=setTimeout(()=>{a=!0,r.abort(),t(Error(`Session abort timed out after ${ni}ms`))},ni)});await Promise.race([n,o])}catch(e){a?n.warning(`OpenCode session abort exceeded teardown budget; continuing teardown`,{sessionId:t}):n.debug(`OpenCode session abort failed; continuing teardown`,{sessionId:t,error:E(e)})}finally{i!=null&&clearTimeout(i)}}async function ii(e,n,r,i){let a=Date.now(),o=r?.timeoutMs??18e5,s=Pr(o,n),c=i==null,l=null,u=null,d=null,f={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},p=null,m=!0;n.info(`Executing OpenCode agent (SDK mode)`,{agent:r?.agent??`build (default)`,hasModelOverride:r?.model!=null,timeoutMs:o});let h=()=>({success:!1,exitCode:130,duration:Date.now()-a,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:f.tokens,model:f.model,cost:f.cost,prsCreated:f.prsCreated,commitsCreated:f.commitsCreated,commentsPosted:f.commentsPosted,llmError:p,classificationPath:f.classificationPath});try{let o=null;if(i==null){let e=await s.run(async()=>x(async()=>t({signal:s.signal}),n),`OpenCode server creation`);u=e.client,l=e.server,o=e.server.url}else u=i.client,o=i.server.url;if(u==null)throw Error(`OpenCode client was not initialized`);let c=u;if(r?.continueSessionId==null){let e=r?.sessionTitle==null?void 0:{body:{title:r.sessionTitle}},t=await s.run(async()=>e==null?c.session.create({signal:s.signal}):c.session.create({...e,signal:s.signal}),`session creation`);if(t.data==null||t.error!=null)throw Error(`Failed to create session: ${t.error==null?`No data returned`:String(t.error)}`);d=t.data.id,n.info(`Created new OpenCode session`,{sessionId:d,sessionTitle:r?.sessionTitle??null})}else d=r.continueSessionId,n.info(`Continuing existing OpenCode session`,{sessionId:d});if(d==null)throw Error(`OpenCode session was not initialized`);let g=d,{text:_,referenceFiles:v}=le({...e,sessionId:d},n),y=ue(),b=Me();if(await s.run(async()=>H.mkdir(b,{recursive:!0}),`OpenCode log directory creation`),C()){let e=qe.createHash(`sha256`).update(_).digest(`hex`),t=U.join(b,`prompt-${d}-${e.slice(0,8)}.txt`);try{await s.run(async()=>H.writeFile(t,_,`utf8`),`prompt artifact write`),n.info(`Prompt artifact written`,{hash:e,path:t})}catch(e){n.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:t})}}let S=await s.run(async()=>Ft(v,b,n),`reference file materialization`),w=[...e.fileParts??[],...S],ee=null,T=!1,E={kind:`initial`};for(let t=1;t<=4;t++){if(s.isExpired())return h();let i=Gr[Math.min(t-1,Gr.length-1)]??Gr[0],l=E.kind===`initial`?_:Xr(E.error,r?.credentialProvisioned===!0),u=w.length>0?w:void 0,v=await(async()=>{try{let e=await Qr(c,g,l,u,y,r,n,o,s);return m=!1,e}finally{s.isExpired()===!1&&await $t(c,g,r?.sessionTitle,n,{signal:s.signal,isExpired:s.isExpired,remainingMs:s.remainingMs})}})();if(f=Wr(v.eventStreamResult,f),v.success)return{success:!0,exitCode:0,duration:Date.now()-a,sessionId:d,error:null,tokenUsage:f.tokens,model:f.model,cost:f.cost,prsCreated:f.prsCreated,commitsCreated:f.commitsCreated,commentsPosted:f.commentsPosted,llmError:null,classificationPath:f.classificationPath};ee=v.error,p=v.llmError;let b=T;if(v.outcome!==`submit_failed`&&(T=!0),await ti(e.responseFilePath,$r(e.context,e.triggerContext),n)!==`absent`)break;let x=v.outcome===`submit_failed`&&b===!1&&v.llmError?.retryable===!0,S=v.outcome===`turn_failed_retryable`;if(x===!1&&S===!1||t>=4||s.isExpired())break;if(S){if(v.llmError==null)break;E={kind:`continuation`,error:v.llmError}}else E={kind:`initial`};m=!0,n.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:t,maxAttempts:4,error:v.error,delayMs:i,sessionId:d}),await s.run(async()=>{await Dr(i,s.signal)},`retry delay`)}return{success:!1,exitCode:1,duration:Date.now()-a,sessionId:d,error:ee??`Unknown error`,tokenUsage:f.tokens,model:f.model,cost:f.cost,prsCreated:f.prsCreated,commitsCreated:f.commitsCreated,commentsPosted:f.commentsPosted,llmError:p,classificationPath:f.classificationPath}}catch(e){if(s.isTimedOut())return h();let t=Date.now()-a,r=E(e),i=_t(e);return n.error(`OpenCode execution failed`,{error:r,durationMs:t}),{success:!1,exitCode:1,duration:t,sessionId:d,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:i?vt(r):null,classificationPath:i?`fallback`:`unclassified`}}finally{m&&s.isTimedOut()&&u!=null&&d!=null&&await ri(u,d,n),s.dispose(),c&&l?.close()}}async function ai(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await An(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function oi(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await Nn(e,t.repo,`agent: working`,`fcf2e1`,`Agent is currently working on this`,n)&&await Pn(e,t.repo,t.issueNumber,[`agent: working`],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function si(e,t,n){await Promise.all([ai(e,t,n),oi(e,t,n)])}async function ci(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await jn(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Mn(e,t.repo,t.commentId,r.id,n)}async function li(e,t,n,r){t.commentId!=null&&await An(e,t.repo,t.commentId,n,r)}async function ui(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await ci(e,t,n),await li(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:E(e)})}}async function di(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await ci(e,t,n),await li(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:E(e)})}}async function fi(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Fn(e,t.repo,t.issueNumber,`agent: working`,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function pi(e,t,n,r){n?await ui(e,t,r):await di(e,t,r),await fi(e,t,r)}var X=e(ce(),1),mi=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())})},hi=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 mi(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},Z=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())})},gi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const _i=process.platform===`win32`;process.platform;function vi(e,t,n,r){return Z(this,void 0,void 0,function*(){return t||=V.join(Ni(),He.randomUUID()),yield a(V.dirname(t)),L(`Downloading ${e}`),L(`Destination ${t}`),yield new hi(3,Pi(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Pi(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>Z(this,void 0,void 0,function*(){return yield yi(e,t||``,n,r)}),e=>!(e instanceof gi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function yi(e,t,n,r){return Z(this,void 0,void 0,function*(){if(B.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new s(`actions/tool-cache`,[],{allowRetries:!1});n&&(L(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new gi(a.message.statusCode);throw L(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=We.promisify(ft.pipeline),c=Pi(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,B.createWriteStream(t)),L(`download complete`),l=!0,t}finally{if(!l){L(`download failed`);try{yield Fe(t)}catch(e){L(`Failed to delete '${t}'. ${e.message}`)}}}})}function bi(e,t){return Z(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Di(t),L(`Checking tar --version`);let r=``;yield A(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),L(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],ve()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return _i&&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 A(`tar`,a),t})}function xi(e,t){return Z(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Di(t),_i?yield Si(e,t):yield Ci(e,t),t})}function Si(e,t){return Z(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 T(`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(` `)];L(`Using pwsh at path: ${i}`),yield A(`"${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 T(`powershell`,!0);L(`Using powershell at path: ${t}`),yield A(`"${t}"`,e)}})}function Ci(e,t){return Z(this,void 0,void 0,function*(){let n=yield T(`unzip`,!0),r=[e];ve()||r.unshift(`-q`),r.unshift(`-o`),yield A(`"${n}"`,r,{cwd:t})})}function wi(e,t,n,r){return Z(this,void 0,void 0,function*(){if(n=X.clean(n)||n,r||=Ve.arch(),L(`Caching tool ${t} ${n} ${r}`),L(`source dir: ${e}`),!B.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield Oi(t,n,r);for(let t of B.readdirSync(e))yield w(V.join(e,t),i,{recursive:!0});return ki(t,n,r),i})}function Ti(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=Ve.arch(),Ai(t)||(t=ji(Ei(e,n),t));let r=``;if(t){t=X.clean(t)||``;let i=V.join(Mi(),e,t,n);L(`checking cache: ${i}`),B.existsSync(i)&&B.existsSync(`${i}.complete`)?(L(`Found tool in cache ${e} ${t} ${n}`),r=i):L(`not found`)}return r}function Ei(e,t){let n=[];t||=Ve.arch();let r=V.join(Mi(),e);if(B.existsSync(r)){let e=B.readdirSync(r);for(let i of e)if(Ai(i)){let e=V.join(r,i,t||``);B.existsSync(e)&&B.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Di(e){return Z(this,void 0,void 0,function*(){return e||=V.join(Ni(),He.randomUUID()),yield a(e),e})}function Oi(e,t,n){return Z(this,void 0,void 0,function*(){let r=V.join(Mi(),e,X.clean(t)||t,n||``);L(`destination ${r}`);let i=`${r}.complete`;return yield Fe(r),yield Fe(i),yield a(r),r})}function ki(e,t,n){let r=`${V.join(Mi(),e,X.clean(t)||t,n||``)}.complete`;B.writeFileSync(r,``),L(`finished caching tool`)}function Ai(e){let t=X.clean(e)||``;L(`isExplicit: ${t}`);let n=X.valid(t)!=null;return L(`explicit? ${n}`),n}function ji(e,t){let n=``;L(`evaluating ${e.length} versions`),e=e.sort((e,t)=>X.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(X.satisfies(i,t)){n=i;break}}return L(n?`matched: ${n}`:`match not found`),n}function Mi(){let e=process.env.RUNNER_TOOL_CACHE||``;return Ue(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function Ni(){let e=process.env.RUNNER_TEMP||``;return Ue(e,`Expected RUNNER_TEMP to be defined`),e}function Pi(e,t){let n=global[e];return n===void 0?t:n}function Fi(){return{find:Ti,downloadTool:vi,extractTar:bi,extractZip:xi,cacheDir:wi}}function Ii(){return{exec:A,getExecOutput:Le}}function Li(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 Ri(e,t,n){let r=U.join(t,`auth.json`);await H.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await H.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function zi(){let e=z.platform,t=z.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Bi(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 Vi(e,t,n,r,i=Pe){let a=zi(),o=t.find(`bun`,i,a.arch);if(o.length>0)return e.info(`Bun found in cache`,{version:i,path:o}),r(o),await Ui(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Bi(i,a);try{let o=await t.downloadTool(s);if(z.platform!==`win32`&&!await Wi(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Hi(await t.extractZip(o),t),l=nt.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Ui(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=E(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Hi(e,t){for(let n of await Xe.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=nt.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Hi(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Hi(i,t)}throw Error(`Could not find executable: bun`)}async function Ui(e){let t=e=>z.platform===`win32`?`${e}.exe`:e,n=nt.join(e,t(`bun`));try{await Xe.symlink(n,nt.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 Wi(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}}const Gi=[`oh-my-openagent`],Ki=[`oh-my-opencode-slim`],qi=[`1.1.1`];function Ji(e){return qi.includes(e)}function Yi(e){let t=e.lastIndexOf(`@`);return t>0?e.slice(0,t):e}function Xi(e){let t=Yi(e);return Gi.includes(t)}function Zi(e){let t=Yi(e);return Ki.includes(t)}function Qi(e){let t=e.filter(e=>typeof e==`string`&&Xi(e)).length;return{cleaned:e.filter(e=>typeof e!=`string`||!Xi(e)),removed:t>0}}function $i(e){let t=e.filter(e=>typeof e==`string`&&Zi(e)).length;return{cleaned:e.filter(e=>typeof e!=`string`||!Zi(e)),removed:t>0}}function ea(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ta(e,t){let n=ea(e.agent)?e.agent:{},r=ea(n.build)?n.build:{},i=ea(r.permission)?r.permission:{},a=t!=null&&t.length>0?{"*":`deny`,[U.join(t,ke,`*`)]:`allow`}:`deny`;e.agent={...n,build:{...r,permission:{...i,external_directory:a}}}}function na(e,t){let n=e.enableOmoSlim??!1,r=e.omoSlimVersion??`1.1.2`,i=e.omoSlimPreset??`openai`,a={autoupdate:!1};if(e.opencodeConfig!=null){let t;try{t=JSON.parse(e.opencodeConfig)}catch{return{config:a,error:`opencode-config must be valid JSON`}}if(typeof t!=`object`||!t||Array.isArray(t))return{config:a,error:`opencode-config must be a JSON object`};Object.assign(a,t)}let o=Array.isArray(a.plugin)?a.plugin:[],s=o.some(e=>typeof e==`string`&&Xi(e)),c=o.some(e=>typeof e==`string`&&Zi(e));if(s&&c)return{config:a,error:`oMo and OMO Slim plugins cannot both be present`};if(n&&!qi.includes(r))return{config:a,error:`OMO Slim version ${r} is not verified to register the orchestrator agent (known-good: ${qi.join(`, `)})`};let l=`@fro.bot/systematic@${e.systematicVersion}`,u=Array.isArray(a.plugin)?a.plugin:[];if(u.some(e=>typeof e==`string`&&e.startsWith(`@fro.bot/systematic`))||(a.plugin=[...u,l]),n){let{cleaned:n}=Qi(Array.isArray(a.plugin)?a.plugin:[]),{cleaned:o}=$i(n),s=`oh-my-opencode-slim@${r}`;a.plugin=[...o,s],`plugins`in a&&delete a.plugins,a.default_agent=`orchestrator`,t.debug(`Built CI OpenCode config (slim mode)`,{hasUserConfig:e.opencodeConfig!=null,pluginCount:Array.isArray(a.plugin)?a.plugin.length:0,preset:i})}else if(e.enableOmo)t.debug(`Built CI OpenCode config`,{hasUserConfig:e.opencodeConfig!=null,pluginCount:Array.isArray(a.plugin)?a.plugin.length:0});else{let n=[],{cleaned:r,removed:i}=Qi(Array.isArray(a.plugin)?a.plugin:[]);i&&(n.push(`plugin`),a.plugin=r),`plugins`in a&&(delete a.plugins,n.push(`plugins`));let o=a.default_agent;a.default_agent=`build`,ta(a,z.env.RUNNER_TEMP),o!=null&&o!==`build`&&n.push(`default_agent`),n.length>0&&t.warning(`OpenCode config rewritten for disabled oMo mode (enable-omo: false): ${n.join(`, `)}. oMo plugin entries are stripped and default_agent is pinned to "build". Set enable-omo: true to use oMo features.`),t.debug(`Built CI OpenCode config`,{hasUserConfig:e.opencodeConfig!=null,pluginCount:Array.isArray(a.plugin)?a.plugin.length:0})}return{config:a,error:null}}function ra(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function ia(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),Ae(t,{log:ra(n)})}async function aa(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 oa(e,t,n,r,i,a=!0){let o=t??n,s=t==null?n.length>0?`github-token`:`none`:`app-token`;if(o.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};if(a?z.env.GH_TOKEN=o:delete z.env.GH_CONFIG_DIR,r.info(`Configured authentication`,{method:s}),a&&o.length>0)try{let e=await $e(W(z.env.RUNNER_TEMP!=null&&z.env.RUNNER_TEMP.length>0?z.env.RUNNER_TEMP:ct(),`gh-config-`));await Ze(e,448);let t={...z.env,GH_CONFIG_DIR:e};delete t.GH_TOKEN,delete t.GITHUB_TOKEN;let n=await i.getExecOutput(`gh`,[`auth`,`login`,`--with-token`],{env:t,input:Ke.from(o,`utf8`),silent:!0,ignoreReturnCode:!0});if(n.exitCode===0){z.env.GH_CONFIG_DIR=e;try{await Ze(W(e,`hosts.yml`),384)}catch{}}else r.warning(`gh auth login failed; model gh CLI usage in the child may be unauthenticated`,{exitCode:n.exitCode})}catch(e){r.warning(`Failed to configure off-environment gh auth; child gh CLI will be unauthenticated`,{error:E(e)})}let c=null;return e!=null&&(c=await aa(e,r)),{authenticated:!0,method:s,botLogin:c}}async function sa(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 ca(e,t,n,r){let i=await sa(`user.name`,r),a=await sa(`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 zn(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})}async function la(e,t,n){let{logger:r,execAdapter:i}=t;r.info(`Installing Oh My OpenCode Slim plugin`,{version:e,preset:n});let a=``,o=[`oh-my-opencode-slim@${e}`,`install`,`--no-tui`,`--reset`,`--preset=${n}`];try{let t=await i.exec(`bunx`,o,{listeners:{stdout:e=>{a+=e.toString()},stderr:e=>{a+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-opencode-slim install returned exit code ${t}`;return r.error(e,{output:a.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${a.slice(0,500)}`}}let n=/oh-my-opencode-slim@(\d+\.\d+\.\d+)/i.exec(a),s=n!=null&&n[1]!=null?n[1]:e;return r.info(`OMO Slim plugin installed`,{version:s}),{installed:!0,version:s,error:null}}catch(e){let t=E(e),n=a.length>0?`${t}\nOutput: ${a.slice(0,500)}`:t;return r.error(`Failed to run OMO Slim installer`,{error:t,output:a.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-opencode-slim install failed: ${n}`}}}async function ua(e,t,n={}){let{logger:r,execAdapter:i}=t,{claude:a=`no`,copilot:o=`no`,gemini:s=`no`,openai:c=`no`,opencodeZen:l=`no`,zaiCodingPlan:u=`no`,kimiForCoding:d=`no`}=n;r.info(`Installing Oh My OpenAgent plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u,kimiForCoding:d});let f=``,p=[`oh-my-openagent@${e}`,`install`,`--no-tui`,`--skip-auth`,`--claude=${a}`,`--copilot=${o}`,`--gemini=${s}`,`--openai=${c}`,`--opencode-zen=${l}`,`--zai-coding-plan=${u}`,`--kimi-for-coding=${d}`];try{let t=await i.exec(`bunx`,p,{listeners:{stdout:e=>{f+=e.toString()},stderr:e=>{f+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-openagent install returned exit code ${t}`;return r.error(e,{output:f.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${f.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(f),a=n!=null&&n[1]!=null?n[1]:e;return r.info(`oMo plugin installed`,{version:a}),{installed:!0,version:a,error:null}}catch(e){let t=E(e),n=f.length>0?`${t}\nOutput: ${f.slice(0,500)}`:t;return r.error(`Failed to run oMo installer`,{error:t,output:f.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-openagent install failed: ${n}`}}}const da=`opencode`,fa=`https://github.com/fro-bot/agent/releases/download`,pa=`+harness.`,ma=`1.18.18`,ha=/^\d+\.\d+\.\d+(?:[.-][\w.-]+)?(?:\+[\w.-]+)?$/;function ga(e){return e.includes(pa)}function _a(e){return e.includes(pa)?e.replace(pa,`-harness.`):e}function va(){let e=ot.platform(),t=ot.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 ya(e){return(e.startsWith(`v`)?e.slice(1):e).replaceAll(`+`,`%2B`)}function ba(e){let t=e.startsWith(`v`)?e.slice(1):e;if(!ha.test(t))throw Error(`Invalid version string: "${e}". Must match semver-ish pattern (no path traversal or shell metacharacters).`)}function xa(e,t){ba(e);let n=`opencode-${t.os}-${t.arch}${t.ext}`;if(ga(e)){let t=ya(e);return`${fa}/${t}/${n}`}return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${n}`}function Sa(e){if(ba(e),!ga(e))throw Error(`buildChecksumsUrl requires a harness version (must contain +harness.)`);let t=ya(e);return`${fa}/${t}/SHA256SUMS`}async function Ca(e,t,n,r,i){let a=Sa(t);i.debug(`Downloading SHA256SUMS for harness release`,{url:a});let o=dt(await r.downloadTool(a),`utf8`),s=`opencode-${n.os}-${n.arch}${n.ext}`,c=o.split(` `).map(e=>e.trim()).find(e=>{let t=e.split(/\s+/);return t.length>=2&&t.at(-1)===s});if(c===void 0)throw Error(`SHA256SUMS does not contain an entry for ${s}`);let l=c.split(/\s+/)[0];if(l===void 0||l.length===0)throw Error(`Could not parse hash from SHA256SUMS line: ${c}`);let u=Je(`sha256`);await new Promise((t,n)=>{let r=ut(e);r.on(`error`,n),r.on(`data`,e=>{u.update(e)}),r.on(`end`,()=>{t()})});let d=u.digest(`hex`);if(d.toLowerCase()!==l.toLowerCase())throw Error(`SHA256 mismatch for ${s}: expected ${l}, got ${d}`);i.debug(`Harness archive SHA256 verified`,{filename:s,hash:d})}async function wa(e,t,n,r){if(z.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 Ta(e,t,n,r,i=ma){let a=va(),o=n.find(da,_a(e),a.arch);if(o.length>0)return t.info(`OpenCode found in cache`,{version:e,path:o}),{path:o,version:e,cached:!0};try{return await Ea(e,a,t,n,r)}catch(n){if(ga(e))throw Error(`Harness OpenCode download/verify failed for explicit pin "${e}": ${E(n)}. No stock fallback is attempted for an explicit harness pin (fail-closed).`);t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:E(n)})}if(e!==i)try{let e=await Ea(i,a,t,n,r);return t.info(`Installed fallback version`,{version:i}),e}catch(t){throw Error(`Failed to install OpenCode (tried ${e} and ${i}): ${E(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Ea(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=xa(e,t),o=await r.downloadTool(a);if(ga(e))await Ca(o,e,t,r,n);else if(!await wa(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,da,_a(e),t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function Da(e,t){if(t!==void 0&&ga(t))return e.debug(`Skipping stock latest fetch for harness-pinned version`,{version:t}),t;let n=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!n.ok)throw Error(`Failed to fetch latest OpenCode version: ${n.statusText}`);let r=(await n.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:r}),r}function Oa(){return new URL(`./session-tools.js`,import.meta.url)}async function ka(e,t,n=Oa){let r=n();try{let n=await H.readFile(r),i=U.join(e,`tool`);await H.mkdir(i,{recursive:!0});let a=U.join(i,`session.js`);await H.writeFile(a,n),t.info(`Wrote session tools file`,{path:a,bytes:n.byteLength})}catch(e){t.warning(`Session tools asset unavailable, skipping (native session tools will be absent)`,{path:r.toString(),error:String(e)})}}const Aa=new Set([`__proto__`,`prototype`,`constructor`]);function ja(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ma(e,t){let n=Object.create(null);for(let[t,r]of Object.entries(e))Aa.has(t)||(n[t]=r);for(let[e,r]of Object.entries(t)){if(Aa.has(e))continue;let t=n[e];ja(r)&&ja(t)?n[e]=Ma(t,r):n[e]=r}return n}function Na(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function Pa(e,t,n){let r=JSON.parse(e);if(!Na(r))throw Error(`systematic-config must be a JSON object (non-null, non-array)`);await H.mkdir(t,{recursive:!0});let i=U.join(t,`systematic.json`),a={};try{let e=await H.readFile(i,`utf8`),t=JSON.parse(e);Na(t)&&(a=t)}catch(e){n.debug(`Using empty base Systematic config`,{path:i,error:String(e)})}let o=Ma(a,r);await H.writeFile(i,JSON.stringify(o,null,2)),n.info(`Wrote Systematic config`,{path:i,keyCount:Object.keys(r).length})}const Fa={restoreCache:async(e,t,n)=>xe(e,t,n),saveCache:async(e,t)=>Ee(e,t)};function Ia(e){let{os:t,bunVersion:n,opencodeVersion:r,omoVersion:i,systematicVersion:a,cacheMode:o}=e;return o===`disabled`?`${b}-${t}-disabled-oc-${r}-sys-${a}-bun-${n}`:`${b}-${t}-enabled-oc-${r}-omo-${i}-sys-${a}-bun-${n}`}function La(e){let{os:t,bunVersion:n,opencodeVersion:r,omoVersion:i,systematicVersion:a,cacheMode:o}=e;return o===`disabled`?[`${b}-${t}-disabled-oc-${r}-sys-${a}-bun-${n}-`]:[`${b}-${t}-enabled-oc-${r}-omo-${i}-sys-${a}-bun-${n}-`]}function Ra(e){let{cacheMode:t,toolCachePath:n,bunCachePath:r,omoConfigPath:i,opencodeCachePath:a}=e;return t===`disabled`?[n,a]:[n,r,i,a]}async function za(e){let{logger:t,os:n,bunVersion:r,opencodeVersion:i,omoVersion:a,systematicVersion:o,cacheMode:s,toolCachePath:c,bunCachePath:l,omoConfigPath:u,opencodeCachePath:d,cacheAdapter:f=Fa}=e,p=Ia({os:n,bunVersion:r,opencodeVersion:i,omoVersion:a,systematicVersion:o,cacheMode:s}),m=La({os:n,bunVersion:r,opencodeVersion:i,omoVersion:a,systematicVersion:o,cacheMode:s}),h=Ra({cacheMode:s,toolCachePath:c,bunCachePath:l,omoConfigPath:u,opencodeCachePath:d});t.info(`Restoring tools cache`,{primaryKey:p,restoreKeys:[...m],paths:h});try{let e=await f.restoreCache([...h],p,[...m]);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:E(e)}),{hit:!1,restoredKey:null}}}async function Ba(e){let{logger:t,os:n,bunVersion:r,opencodeVersion:i,omoVersion:a,systematicVersion:o,cacheMode:s,toolCachePath:c,bunCachePath:l,omoConfigPath:u,opencodeCachePath:d,cacheAdapter:f=Fa}=e,p=Ia({os:n,bunVersion:r,opencodeVersion:i,omoVersion:a,systematicVersion:o,cacheMode:s}),m=Ra({cacheMode:s,toolCachePath:c,bunCachePath:l,omoConfigPath:u,opencodeCachePath:d});t.info(`Saving tools cache`,{saveKey:p,paths:m});try{return await f.saveCache([...m],p)===-1?(t.warning(`Tools cache save did not persist`,{saveKey:p}),!1):(t.info(`Tools cache saved`,{saveKey:p}),!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:E(e)}),!1)}}async function Va(e,t){let n=Date.now(),r=P({component:`setup`}),i=Fi(),a=Ii();try{r.info(`Starting setup`,{version:e.opencodeVersion,enableOmo:e.enableOmo});let o;try{o=Li(e.authJson)}catch(e){return F(`Invalid auth-json: ${E(e)}`),null}let s=e.opencodeVersion;if(s===`latest`)try{s=await Da(r)}catch(e){r.warning(`Failed to get latest version, using fallback`,{error:E(e)}),s=ma}let c=e.omoVersion,l=e.systematicVersion,u=z.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,d=W(u,`opencode`),f=W(u,`bun`),p=W(st(),`.config`,`opencode`),m=W(st(),`.cache`,`opencode`),h=se(),g=await za({logger:r,os:h,bunVersion:Pe,opencodeVersion:s,omoVersion:c,systematicVersion:l,cacheMode:e.enableOmo||e.enableOmoSlim?`enabled`:`disabled`,toolCachePath:d,bunCachePath:f,omoConfigPath:p,opencodeCachePath:m}),_=g.hit?`hit`:`miss`,v,y=`skipped`,b=null,x=`skipped`,S=null;if(g.hit){let e=i.find(`opencode`,_a(s));e.length>0?(v={path:e,version:s,cached:!0},r.info(`Tools cache hit, using cached OpenCode CLI`,{version:s,omoVersion:c})):r.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:s,restoredKey:g.restoredKey})}if(v==null)try{v=await Ta(s,r,i,a)}catch(e){return F(`Failed to install OpenCode: ${E(e)}`),null}if(e.enableOmo){let t=!1;try{await Vi(r,i,a,j,Pe),t=!0}catch(e){r.warning(`Bun installation failed, oMo will be unavailable`,{error:E(e)})}if(je(`OMO_SEND_ANONYMOUS_TELEMETRY`,`0`),je(`OMO_DISABLE_POSTHOG`,`1`),t){let t=await ua(c,{logger:r,execAdapter:a},e.omoProviders);t.installed?(r.info(`oMo installed`,{version:t.version}),y=`installed`):(r.warning(`oMo installation failed, continuing without oMo`,{error:t.error??`unknown error`}),y=`failed`),b=t.error}else y=`failed`,b=`Bun installation failed`}else if(e.enableOmoSlim){if(!Ji(e.omoSlimVersion))return F(`OMO Slim version ${e.omoSlimVersion} is not verified to register the orchestrator agent (known-good: 1.1.1)`),null;let t=!1;try{await Vi(r,i,a,j,Pe),t=!0}catch(e){r.warning(`Bun installation failed, OMO Slim will be unavailable`,{error:E(e)})}let n=!1;if(t){let t=await la(e.omoSlimVersion,{logger:r,execAdapter:a},e.omoSlimPreset);t.installed?(r.info(`OMO Slim installed`,{version:t.version}),x=`installed`,n=!0):(r.warning(`OMO Slim installation failed, continuing without OMO Slim`,{error:t.error??`unknown error`}),x=`failed`),S=t.error}else x=`failed`,S=`Bun installation failed`;e={...e,enableOmoSlim:n}}else r.info(`oMo disabled, skipping oMo install`);if(e.systematicConfig!=null)try{await Pa(e.systematicConfig,p,r)}catch(e){r.warning(`systematic-config write failed: ${E(e)}`)}await ka(p,r);let C=na({opencodeConfig:e.opencodeConfig,systematicVersion:l,enableOmo:e.enableOmo,enableOmoSlim:e.enableOmoSlim,omoSlimVersion:e.omoSlimVersion,omoSlimPreset:e.omoSlimPreset},r);if(C.error!=null)return F(C.error),null;let w=W(p,`opencode.json`);if(await Qe(p,{recursive:!0}),e.enableOmo){let e={};try{let t=await et(w,`utf8`),n=JSON.parse(t);typeof n==`object`&&n&&!Array.isArray(n)&&(e=n)}catch{}delete e.plugins;let t=(e=>e.map(e=>typeof e==`string`&&(e===`oh-my-openagent`||e===`oh-my-openagent@latest`)?`oh-my-openagent@${c}`:e))(Array.isArray(e.plugin)?e.plugin:[]),n=Array.isArray(C.config.plugin)?C.config.plugin:[],i=[...t];for(let e of n){if(typeof e!=`string`)continue;let t=Yi(e);i.some(e=>typeof e==`string`&&Yi(e)===t)||i.push(e)}let a={...e,...C.config,plugin:i},o=JSON.stringify(a,null,2);je(`OPENCODE_CONFIG_CONTENT`,o),await tt(w,o),r.info(`Wrote merged OpenCode config`,{path:w,pluginCount:i.length,plugins:i})}else{let e=JSON.stringify(C.config,null,2);je(`OPENCODE_CONFIG_CONTENT`,e),await tt(w,e),r.info(`Wrote fresh OpenCode config (disabled oMo)`,{path:w,pluginCount:Array.isArray(C.config.plugin)?C.config.plugin.length:0})}g.hit||await Ba({logger:r,os:h,bunVersion:Pe,opencodeVersion:s,omoVersion:c,systematicVersion:l,cacheMode:e.enableOmo||e.enableOmoSlim?`enabled`:`disabled`,toolCachePath:d,bunCachePath:f,omoConfigPath:p,opencodeCachePath:m}),j(v.path),D(`opencode-path`,v.path),D(`opencode-version`,v.version),r.info(`OpenCode ready`,{version:v.version,cached:v.cached});let ee=Ae(t),T=e.credential===`provision`,te=await oa(ee,null,t,r,a,T);T?(je(`GH_TOKEN`,t),z.env.GH_CONFIG_DIR!=null&&z.env.GH_CONFIG_DIR.length>0&&je(`GH_CONFIG_DIR`,z.env.GH_CONFIG_DIR),r.info(`GitHub CLI configured`)):r.info(`GitHub CLI credential withheld from child (affected trigger)`),await ca(ee,te.botLogin,r,a);let ne=W(Ie(),`opencode`),re=await Ri(o,ne,r);D(`auth-json-path`,re),r.info(`auth.json populated`,{path:re});let ie=Date.now()-n,ae={opencodePath:v.path,opencodeVersion:v.version,ghAuthenticated:te.authenticated,omoStatus:y,omoError:b,omoSlimStatus:x,omoSlimError:S,toolsCacheStatus:_,duration:ie};return r.info(`Setup complete`,{duration:ie}),ae}catch(e){let t=E(e);return r.error(`Setup failed`,{error:t}),F(t),null}}const Ha={verifyOpenCodeAvailable:async(e,t)=>{let n=e??`opencode`;try{let e=``;await A(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}}},runSetup:async(e,t)=>Va(e,t),addToPath:e=>{j(e)}};async function Ua(e,t){return re(e,t)}async function Wa(e){return ae(e,Ha)}async function Ga(e,t){let n={repo:e.agentContext.repo,commentId:e.agentContext.commentId,issueNumber:e.agentContext.issueNumber,issueType:e.agentContext.issueType,botLogin:e.botLogin},r=P({phase:`acknowledgment`});return await si(e.githubClient,n,r),t.debug(`Acknowledgment phase completed`),n}async function Ka(e){let{storeConfig:t,repo:n,runId:r,runAttempt:i}=e,a=e.logger??P({phase:`acquire-lock`});if(t.enabled===!1)return a.debug(`coordination-disabled`,{reason:`s3-not-configured`}),{outcome:`s3-disabled`};let o=u(t,a),s=`action:${r}:${i}`,c=await hn({storeAdapter:o,storeConfig:t,lockTtlSeconds:900,heartbeatIntervalMs:0,staleThresholdMs:_n,pendingStaleThresholdMs:vn},n,s,`github`,r,a);return c.success===!1?(a.warning(`Lock acquisition failed`,{error:c.error.message,repo:n,holderId:s}),{outcome:`error`,error:c.error}):c.data.acquired===!0?(a.info(`Lock acquired`,{repo:n,holderId:s,etag:c.data.etag}),{outcome:`acquired`,lockEtag:c.data.etag}):(a.info(`lock-held-by-other-surface`,{repo:n,holderId:s,heldBy:c.data.holder?.holder_id??null,surface:c.data.holder?.surface??null}),{outcome:`held-by-other`,holder:c.data.holder})}async function qa(e,t,n){let r;try{r=await e.getExecOutput(`git`,[`config`,`--local`,`--get-regexp`,String.raw`^http\..*\.extraheader$`],{cwd:t,ignoreReturnCode:!0,silent:!0})}catch(e){return n.debug(`git-credential-check: git unavailable or not a repo, treating as no persisted credentials`,{error:e instanceof Error?e.message:String(e)}),R(void 0)}if(r.exitCode===0&&r.stdout.trim().length>0)return k(`Persisted git credential found in local config (${r.stdout.trim().split(` `)[0]?.split(` `)[0]??`http.*.extraheader`}) on a withhold run — set persist-credentials: false on actions/checkout`);let i;try{i=await e.getExecOutput(`git`,[`remote`,`get-url`,`origin`],{cwd:t,ignoreReturnCode:!0,silent:!0})}catch(e){return n.debug(`git-credential-check: could not read origin remote, treating as no persisted credentials`,{error:e instanceof Error?e.message:String(e)}),R(void 0)}return i.exitCode===0&&Ja(i.stdout.trim())?k(`Persisted git credential found embedded in the origin remote URL on a withhold run — set persist-credentials: false on actions/checkout`):R(void 0)}function Ja(e){let t=e.indexOf(`@`);if(t===-1)return!1;let n=e.indexOf(`://`),r=n===-1?e.slice(0,t):e.slice(n+3,t);return r.includes(`x-access-token:`)||r.includes(`:`)}function Ya(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function Xa(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}const Za=new Set([`sisyphus`,`hephaestus`,`oracle`,`librarian`,`prometheus`,`explore`]);function Qa(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 $a(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 eo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`],to=[`auto`,`working-dir`,`branch-pr`],no=[`github`,`none`];function ro(e){if(!Pt.includes(e))throw Error(`Invalid omo-slim-preset value: "${e}". Valid values: ${Pt.join(`, `)}`);return e}function io(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(!eo.includes(e))throw Error(`Invalid omo-providers value: "${e}". Valid values: ${eo.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(e){return typeof e==`object`&&!!e}function oo(e){if(ao(e)===!1)return!1;let t=e.pull_request;if(ao(t)===!1)return!1;let n=t.head;if(ao(n)===!1)return!1;let r=n.repo;return ao(r)!==!1&&r.fork===!0}function so(e){if(e.length!==0){if(e===`aws:kms`||e===`AES256`)return e;throw Error(`s3-sse-encryption must be either 'aws:kms' or 'AES256'`)}}function co(){try{let e=z.env.AWS_ACCESS_KEY_ID?.trim()??``;e.length>0&&Ne(e);let t=z.env.AWS_SECRET_ACCESS_KEY?.trim()??``;t.length>0&&Ne(t);let i=N(`github-token`,{required:!0}).trim();if(i.length===0)return k(Error(`github-token is required but was not provided`));Ne(i),delete z.env[`INPUT_GITHUB-TOKEN`];let a=N(`auth-json`,{required:!0}).trim();if(a.length===0)return k(Error(`auth-json is required but was not provided`));Ya(a,`auth-json`),Ne(a),delete z.env[`INPUT_AUTH-JSON`];let o=N(`trusted-head-sha`).trim(),s=N(`prompt`).trim(),c=s.length>0?s:null,l=N(`output-mode`).trim().toLowerCase(),u=l.length>0?lo(l):`auto`,d=N(`response-mode`).trim().toLowerCase(),f=d.length>0?uo(d):`github`,p=N(`review-skip-label`).trim(),m=p.length>0?p:null,h=N(`session-retention`).trim(),g=h.length>0?Xa(h,`session-retention`):50,b=N(`s3-backup`).trim().toLowerCase()===`true`,x=N(`s3-bucket`).trim(),S=x.length>0?x:``,C=N(`aws-region`).trim(),w=C.length>0?C:``,T=N(`s3-endpoint`).trim(),E=T.length>0?T:void 0,te=N(`s3-prefix`).trim(),ne=te.length>0?te:n,re=N(`s3-expected-bucket-owner`).trim(),ie=re.length>0?re:void 0,ae=N(`s3-allow-insecure-endpoint`).trim().toLowerCase()===`true`,oe=N(`s3-sse-kms-key-id`).trim(),D=oe.length>0?oe:void 0,O={enabled:b,bucket:S,region:w,prefix:ne,endpoint:E,expectedBucketOwner:ie,allowInsecureEndpoint:ae,sseEncryption:so(N(`s3-sse-encryption`).trim()),sseKmsKeyId:D};if(O.enabled){if(O.bucket.length===0)throw Error(`s3-bucket is required when s3-backup is enabled`);let e=r(O.prefix);if(!e.success)throw e.error;if(O.endpoint!=null){let e=Be(O.endpoint,O.allowInsecureEndpoint===!0);if(!e.success)throw e.error}oo(ge.payload)&&(ze(`S3 object store is disabled for fork pull requests`),O={...O,enabled:!1})}let se=N(`enable-omo`).trim().toLowerCase()===`true`,A=N(`enable-omo-slim`).trim().toLowerCase()===`true`;if(se&&A)throw Error(`enable-omo and enable-omo-slim are mutually exclusive. Enable only one orchestration plugin.`);let ce=N(`agent`).trim(),j=ce.length>0?ce:null,M=N(`model`).trim(),le=M.length>0?Qa(M):null,P=N(`timeout`).trim(),ue=P.length>0?$a(P):_,F=N(`opencode-version`).trim(),de=F.length>0?F:he,I=N(`skip-cache`).trim().toLowerCase()===`true`,fe=N(`omo-version`).trim(),pe=fe.length>0?fe:y,L=N(`systematic-version`).trim(),_e=L.length>0?L:me,ve=N(`omo-providers`).trim(),ye=se?io(ve.length>0?ve:``):v,be=N(`omo-slim-preset`).trim(),xe=be.length>0?ro(be):`openai`,Se=N(`opencode-config`).trim(),Ce=Se.length>0?Se:null,we=N(`systematic-config`).trim(),Te=we.length>0?we:null,Ee=N(`dedup-window`).trim(),De=Ee.length>0?$a(Ee,`dedup-window`):ee;if(Ce!=null){Ya(Ce,`opencode-config`);let e=JSON.parse(Ce);if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Input 'opencode-config' must be a JSON object`)}if(!se){let e=[];ve.length>0&&e.push(`omo-providers`),fe.length>0&&fe!==`3.17.15`&&e.push(`omo-version`),e.length>0&&ze(`oMo is disabled (enable-omo: false). The following inputs are ignored: ${e.join(`, `)}. Set enable-omo: true to use oMo features.`),j!=null&&Za.has(j.toLowerCase())&&ze(`Agent "${j}" is a known oMo-provided agent but oMo is disabled (enable-omo: false). Set enable-omo: true to use oMo agents, or configure "${j}" via your OpenCode config.`)}return R({githubToken:i,authJson:a,trustedHeadSha:o,prompt:c,outputMode:u,responseMode:f,sessionRetention:g,storeConfig:O,agent:j,model:le,timeoutMs:ue,enableOmo:se,enableOmoSlim:A,opencodeVersion:de,skipCache:I,omoVersion:pe,systematicVersion:_e,omoProviders:ye,omoSlimPreset:xe,opencodeConfig:Ce,systematicConfig:Te,dedupWindow:De,reviewSkipLabel:m})}catch(e){return k(e instanceof Error?e:Error(String(e)))}}function lo(e){switch(e){case`auto`:case`working-dir`:case`branch-pr`:return e;default:throw Error(`Invalid output-mode value: "${e}". Valid values: ${to.join(`, `)}`)}}function uo(e){switch(e){case`github`:case`none`:return e;default:throw Error(`Invalid response-mode value: "${e}". Valid values: ${no.join(`, `)}`)}}async function fo(e){let t=co();if(!t.success)return F(`Invalid inputs: ${t.error.message}`),null;let n=t.data,r=P({phase:`main`});r.info(`Action inputs parsed`,{sessionRetention:n.sessionRetention,s3Backup:n.storeConfig.enabled,hasGithubToken:n.githubToken.length>0,hasPrompt:n.prompt!=null,outputMode:n.outputMode,agent:n.agent,hasModelOverride:n.model!=null,timeoutMs:n.timeoutMs});let{credential:i,delivery:a}=Bt(ge.eventName,n.responseMode);if(i===`withhold`){let e=z.env.GITHUB_WORKSPACE??z.cwd(),t=await qa(Ii(),e,r);if(t.success===!1)return F(`Refusing to proceed with credential withheld: ${t.error}`),null}let s=await po(a,r),c=await Wa({logger:r,opencodeVersion:n.opencodeVersion,githubToken:n.githubToken,authJson:n.authJson,enableOmo:n.enableOmo,omoVersion:n.omoVersion,systematicVersion:n.systematicVersion,omoProviders:n.omoProviders,opencodeConfig:n.opencodeConfig,systematicConfig:n.systematicConfig,enableOmoSlim:n.enableOmoSlim,omoSlimVersion:o,omoSlimPreset:n.omoSlimPreset,credential:i});return c.didSetup?r.info(`OpenCode auto-setup completed`,{version:c.version}):r.info(`OpenCode already available`,{version:c.version}),I(M.OPENCODE_VERSION,c.version),I(M.S3_ENABLED,String(n.storeConfig.enabled)),I(M.S3_BUCKET,n.storeConfig.bucket),I(M.S3_REGION,n.storeConfig.region),I(M.S3_PREFIX,n.storeConfig.prefix),I(M.S3_ENDPOINT,n.storeConfig.endpoint??``),I(M.S3_EXPECTED_BUCKET_OWNER,n.storeConfig.expectedBucketOwner??``),I(M.S3_ALLOW_INSECURE_ENDPOINT,String(n.storeConfig.allowInsecureEndpoint===!0)),I(M.S3_SSE_ENCRYPTION,n.storeConfig.sseEncryption??``),I(M.S3_SSE_KMS_KEY_ID,n.storeConfig.sseKmsKeyId??``),e.debug(`Bootstrap phase completed`,{opencodeVersion:c.version}),{inputs:n,logger:r,opencodeResult:c,delivery:a,responseFilePath:s,trustedHeadSha:n.trustedHeadSha}}async function po(e,t){if(e!==`file-convention`)return null;let n=z.env.RUNNER_TEMP;if(n==null||n.trim().length===0)throw Error(`RUNNER_TEMP is required for file-convention response delivery but was not set`);let r=de(),i=_e(),a=qe.randomUUID(),o=be({runnerTemp:n,runId:r,runAttempt:i}),s=Te({runnerTemp:n,runId:r,runAttempt:i,nonce:a});if(await H.mkdir(o,{recursive:!0}),await H.access(s).then(()=>!0).catch(()=>!1))throw Error(`Response file already exists before execution (preseed guard tripped): ${s}`);return t.debug(`Resolved response file path`,{path:s}),s}const mo=/^[0-9a-f]{40}$/i;function ho(){return{exec:A,getExecOutput:Le}}async function go(e){let{workspacePath:t,logger:n,execAdapter:r=ho()}=e,i=U.join(t,`.git`),a=U.join(i,`opencode`);try{let e=(await H.readFile(a,`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:E(e)})}try{let e=await H.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=U.resolve(t,n[1]),a=U.join(i,`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:i}=await r.getExecOutput(`git`,[`rev-list`,`--max-parents=0`,`--all`],{cwd:t,silent:!0});if(i!==0||e.trim().length===0)return{projectId:null,source:`error`,error:`No commits found in repository`};let o=e.trim().split(` `).map(e=>e.trim()).filter(e=>e.length>0).sort();if(o.length===0)return{projectId:null,source:`error`,error:`No root commits found`};let s=o[0];try{await H.writeFile(a,s,{encoding:`utf8`,flag:`wx`}),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){(typeof e==`object`?e.code:void 0)===`EEXIST`?n.debug(`Project ID file already written by concurrent process, skipping`,{projectId:s}):n.warning(`Failed to cache project ID (continuing)`,{error:E(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:E(e)}}}async function _o(e,t){let n=O(),r=P({phase:`cache`}),i=ue(),a=U.join(i,`.git`,`opencode`),o=await we({components:n,logger:r,storagePath:Re(),authPath:oe(),projectIdPath:a,opencodeVersion:e.opencodeResult.version,storeConfig:e.inputs.storeConfig}),s=o.corrupted?`corrupted`:o.hit?`hit`:`miss`;t.setCacheStatus(s),t.setCacheSource(o.source),e.logger.info(`Cache restore completed`,{cacheStatus:s,key:o.key});let c=await go({workspacePath:i,logger:r});c.source===`error`?r.warning(`Failed to generate project ID (continuing)`,{error:c.error}):r.debug(`Project ID ready`,{projectId:c.projectId,source:c.source});let l=P({phase:`server-bootstrap`}),u=await Ua(new AbortController().signal,l);if(!u.success)return F(`OpenCode server bootstrap failed: ${u.error.message}`),null;let d=u.data;return l.info(`SDK server bootstrapped successfully`),{cacheResult:o,cacheStatus:s,serverHandle:d}}const vo={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 yo(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function bo(e){let t=[],n=new Set;return yo(vo.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&ir(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),yo(vo.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&ir(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),yo(vo.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&ir(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),vo.htmlImage.lastIndex=0,t}function xo(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 So={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`]},Co=[`github.com`,`githubusercontent.com`];async function wo(e,t,n,r,i){i.debug(`Downloading attachment`,{url:e.url});try{let a=await fetch(e.url,{headers:{Authorization:`Bearer ${n}`,Accept:`*/*`,"User-Agent":`fro-bot-agent`},redirect:`manual`}),o=a;if(a.status>=300&&a.status<400){let t=a.headers.get(`location`);if(t==null)return i.warning(`Redirect without location`,{url:e.url}),null;let n=new URL(t);if(!Co.some(e=>n.hostname===e||n.hostname.endsWith(`.${e}`)))return i.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 i.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>r.maxFileSizeBytes)return i.warning(`Attachment exceeds size limit (Content-Length)`,{url:e.url,size:t,limit:r.maxFileSizeBytes}),null}let c=Ke.from(await o.arrayBuffer());if(c.length>r.maxFileSizeBytes)return i.warning(`Attachment exceeds size limit`,{url:e.url,size:c.length,limit:r.maxFileSizeBytes}),null;let l=o.headers.get(`content-type`)??`application/octet-stream`,u=xo(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await H.mkdtemp(U.join(at.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=U.join(p,m);return await H.writeFile(h,c),i.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 i.warning(`Attachment download error`,{url:e.url,error:E(t)}),null}}async function To(e,t,n=So,r){return Promise.all(e.map(async(e,i)=>wo(e,i,t,n,r)))}async function Eo(e,t){for(let n of e)try{await H.unlink(n);let e=U.dirname(n);await H.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:E(e)})}}function Do(e){return e.map(e=>({type:`file`,mime:e.mime,url:Ye(e.tempPath).toString(),filename:e.filename}))}function Oo(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 ko(e,t,n,r){return{processed:n,skipped:r,modifiedBody:Oo(e,t,n),fileParts:Do(n),tempFiles:n.map(e=>e.tempPath)}}function Ao(e,t=So,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 (${De(o.sizeBytes)} > ${De(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 (${De(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!jo(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 jo(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 Mo(e){let t=U.resolve(e);return t.endsWith(U.sep)&&t.length>1?t.slice(0,-1):t}async function No(e){let{bootstrapLogger:t,reactionCtx:n,githubClient:r,agentSuccess:i,attachmentResult:a,serverHandle:o,detectedOpencodeVersion:s,storeConfig:c,metrics:l,agentIdentity:d,repo:f,runId:m,lockEtag:h}=e;try{if(a!=null){let e=P({phase:`attachment-cleanup`});await Eo(a.tempFiles,e)}n!=null&&r!=null&&await pi(r,n,i,P({phase:`cleanup`}));let e=P({phase:`prune`}),h=ue();if(o!=null){let t=Mo(h),n=await Qt(o.client,t,Zt,e);n.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:n.prunedCount,remaining:n.remainingCount})}if(o!=null)try{o.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}if(c.enabled===!0&&f!==``&&m!==``){let e=P({phase:`object-store-artifacts`});try{let t=u(c,e),n=await p(t,c,d,f,m,Me(),e),r=l.getMetrics(),i=[...new Set([...r.sessionsUsed,...r.sessionsCreated])];await g(t,c,d,f,m,{runId:m,timestamp:new Date().toISOString(),tokenUsage:r.tokenUsage,timing:{startTime:r.startTime,endTime:r.endTime,duration:r.duration},cacheStatus:r.cacheStatus,cacheSource:r.cacheSource,sessionIds:i,sessionsUsed:r.sessionsUsed,sessionsCreated:r.sessionsCreated,prsCreated:r.prsCreated,commitsCreated:r.commitsCreated,commentsPosted:r.commentsPosted,model:r.model,cost:r.cost,errors:r.errors,artifactUpload:n},e)}catch(t){e.warning(`Object store artifact or metadata sync failed (non-fatal)`,{error:t instanceof Error?t.message:String(t)})}}let _=O(),v=P({phase:`cache-save`}),y=U.join(h,`.git`,`opencode`);if(await ye({components:_,runId:de(),logger:v,storagePath:Re(),authPath:oe(),projectIdPath:y,opencodeVersion:s,storeConfig:c})&&I(M.CACHE_SAVED,`true`),C()){let e=P({phase:`artifact-upload`});await Oe({logPath:Me(),runId:de(),runAttempt:_e(),logger:e})&&I(M.ARTIFACT_UPLOADED,`true`)}}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(h!=null&&c.enabled===!0){let e=P({phase:`lock-release`});try{let t=await gn({storeAdapter:u(c,e),storeConfig:c,lockTtlSeconds:900,heartbeatIntervalMs:3e4,staleThresholdMs:_n,pendingStaleThresholdMs:vn},f,h,e);t.success===!1?e.warning(`Lock release failed (non-fatal)`,{error:t.error.message,repo:f}):e.debug(`Lock released`,{repo:f})}catch(t){e.warning(`Lock release threw (non-fatal)`,{error:t instanceof Error?t.message:String(t),repo:f})}}}}const Po=U.join(ot.homedir(),`.cache`,`fro-bot-dedup`);function Fo(e){return e.replaceAll(`/`,`-`)}function Io(e,t){let n=Fo(e);return U.join(Po,`${n}-${t.entityType}-${t.entityNumber}`)}function Lo(e,t){return`${i}-${Fo(e)}-${t.entityType}-${t.entityNumber}-`}function Ro(e,t,n){return`${Lo(e,t)}${n}`}async function zo(e,t,n,r=fe){let i=Io(e,t),a=U.join(i,`sentinel.json`),o=Lo(e,t);try{if(await H.rm(i,{recursive:!0,force:!0}),await H.mkdir(i,{recursive:!0}),await r.restoreCache([i],o,[])==null)return null;let e=await H.readFile(a,`utf8`);return JSON.parse(e)}catch(e){return n.debug(`Dedup marker restore failed; proceeding without marker`,{error:E(e),entityType:t.entityType,entityNumber:t.entityNumber}),null}}async function Bo(e,t,n,r,i=fe){let a=Io(e,t),o=U.join(a,`sentinel.json`),s=Ro(e,t,n.runId);try{return await H.mkdir(a,{recursive:!0}),await H.writeFile(o,JSON.stringify(n),`utf8`),await i.saveCache([a],s)===-1?(r.warning(`Dedup marker cache save did not persist`,{saveKey:s}),!1):!0}catch(e){return E(e).toLowerCase().includes(`already exists`)?!0:(r.debug(`Dedup marker save failed`,{error:E(e),entityType:t.entityType,entityNumber:t.entityNumber,saveKey:s}),!1)}}const Vo=new Set([`pull_request`,`issues`]),Ho=new Set([`synchronize`,`reopened`]);function Uo(e){return e.target==null||!Vo.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 Wo(e,t,n,r,i=P({phase:`dedup`}),a){let o=Uo(t);if(e===0)return{shouldProceed:!0,entity:o};if(o==null)return{shouldProceed:!0,entity:null};if(t.action!=null&&Ho.has(t.action))return i.debug(`Dedup bypassed for action`,{action:t.action}),{shouldProceed:!0,entity:o};let s=await zo(n,o,i,a);if(s==null||s.runId===t.runId)return{shouldProceed:!0,entity:o};let c=new Date(s.timestamp).getTime();if(Number.isNaN(c))return i.warning(`Dedup marker timestamp is invalid; proceeding without dedup`,{markerTimestamp:s.timestamp}),{shouldProceed:!0,entity:o};let l=Date.now()-c;if(l<-6e4)return i.warning(`Dedup marker timestamp is too far in the future; proceeding without dedup`,{markerTimestamp:s.timestamp,markerAge:l}),{shouldProceed:!0,entity:o};let u=Math.max(0,l);return u>e?{shouldProceed:!0,entity:o}:(i.info(`Skipping duplicate trigger within dedup window`,{eventType:t.eventType,action:t.action,runId:t.runId,markerRunId:s.runId,markerTimestamp:s.timestamp,dedupWindow:e,entityType:o.entityType,entityNumber:o.entityNumber}),On({sessionId:null,resolvedOutputMode:null,cacheStatus:`miss`,duration:Date.now()-r}),await Ko(t,o,s,u,e,i),{shouldProceed:!1,entity:o})}async function Go(e,t,n,r=P({phase:`dedup`}),i){await Bo(n,t,{timestamp:new Date().toISOString(),runId:e.runId,action:e.action??`unknown`,eventType:e.eventType,entityType:t.entityType,entityNumber:t.entityNumber},r,i)}async function Ko(e,t,n,r,i,a){try{let a=Math.round(r/1e3),o=Math.round(i/1e3),s=`${t.entityType} #${t.entityNumber}`,c=`https://github.com/${e.repo.owner}/${e.repo.repo}/actions/runs/${n.runId}`;l.addHeading(`Fro Bot Agent Run — Skipped (Dedup)`,2).addRaw(`Execution skipped because the agent already ran for **${s}** recently.\n\n`).addTable([[{data:`Detail`,header:!0},{data:`Value`,header:!0}],[`Current action`,`\`${e.eventType}.${e.action??`unknown`}\``],[`Prior run`,`[${n.runId}](${c})`],[`Prior action`,`\`${n.eventType}.${n.action}\``],[`Time since prior run`,`${a}s`],[`Dedup window`,`${o}s`]]).addRaw(` diff --git a/src/services/setup/opencode.ts b/src/services/setup/opencode.ts index e5c7fb3c37..aa9ef64258 100644 --- a/src/services/setup/opencode.ts +++ b/src/services/setup/opencode.ts @@ -16,7 +16,7 @@ const HARNESS_MARKER = '+harness.' * Known stable stock version for fallback when latest-fetch fails or for non-harness paths. * This is a plain anomalyco/opencode release — not a harness build. */ -export const FALLBACK_VERSION = '1.18.14' +export const FALLBACK_VERSION = '1.18.18' /** * Semver-ish pattern for version validation (defense-in-depth, path-traversal guard).