From 1ad9e83c3869e6afc3d9a59828ac52dbadcf9833 Mon Sep 17 00:00:00 2001 From: "Marcus R. Brown" Date: Thu, 26 Feb 2026 13:54:56 -0700 Subject: [PATCH 1/8] chore: update the project banner --- assets/banner.svg | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/assets/banner.svg b/assets/banner.svg index 39111ea6..7b2fb060 100644 --- a/assets/banner.svg +++ b/assets/banner.svg @@ -72,7 +72,7 @@ - + @@ -107,22 +107,14 @@ - + - + - - - - - - - - - + @@ -130,17 +122,17 @@ fro-bot/agent - + agent - + - Autonomous AI for every channel, every workflow - + Autonomous AI for every channel, every workflow + - @fro-bot — mention it anywhere. Watch it work. + @fro-bot — mention it anywhere. Watch it work. - - \ No newline at end of file + + From aeb067909e935169efd27707f331f3bbdce5db62 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 07:45:33 -0700 Subject: [PATCH 2/8] feat(setup): export OPENCODE_CONFIG_CONTENT for CI-safe OpenCode config isolation (#263) feat(setup): export OPENCODE_CONFIG_CONTENT for CI-safe OpenCode config Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- dist/main.js | 32 +++++++++++++-------------- src/lib/setup/setup.test.ts | 44 +++++++++++++++++++++++++++++++++++++ src/lib/setup/setup.ts | 9 ++++++++ 3 files changed, 69 insertions(+), 16 deletions(-) diff --git a/dist/main.js b/dist/main.js index d220038f..19c7d7ab 100644 --- a/dist/main.js +++ b/dist/main.js @@ -1,7 +1,7 @@ -import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,Q as g,R as _,S as v,T as y,U as b,V as x,W as S,X as C,Y as w,Z as T,_ as E,a as ee,b as te,c as D,d as ne,f as O,g as k,h as A,i as j,j as M,k as N,l as re,m as P,n as ie,o as ae,p as oe,q as F,r as se,s as ce,t as I,u as le,v as ue,w as de,x as fe,y as pe,z as L}from"./state-keys-CDII8qo6.js";import*as R from"node:path";import me,{join as z}from"node:path";import B from"node:process";import*as he from"os";import{EOL as ge}from"os";import*as _e from"crypto";import*as V from"fs";import{existsSync as ve,readFileSync as ye}from"fs";import*as H from"path";import{ok as be}from"assert";import*as xe from"util";import{Buffer as Se}from"node:buffer";import*as Ce from"node:crypto";import{pathToFileURL as we}from"node:url";import*as U from"node:fs/promises";import Te from"node:fs/promises";import{spawn as Ee}from"node:child_process";import*as De from"node:os";import Oe,{homedir as ke}from"node:os";import*as Ae from"stream";const je={maxComments:50,maxCommits:100,maxFiles:100,maxReviews:100,maxBodyBytes:10*1024,maxTotalBytes:100*1024},Me=`…[truncated]`;function Ne(e,t){if(e.length===0)return{text:``,truncated:!1};let n=new TextEncoder,r=n.encode(e);if(r.length<=t)return{text:e,truncated:!1};let i=t-n.encode(Me).length;if(i<=0)return{text:Me,truncated:!0};let a=r.slice(0,i),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);for(;o.length>0&&o.charCodeAt(o.length-1)===65533;)a=a.slice(0,-1),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);return{text:o+Me,truncated:!0}}function Pe(e){return e.length===0?``:`**Labels:** ${e.map(e=>`\`${e.name}\``).join(`, `)}\n`}function Fe(e){return e.length===0?``:`**Assignees:** ${e.map(e=>`@${e.login}`).join(`, `)}\n`}function Ie(e){let t=[];t.push(`## Issue #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`);let n=Pe(e.labels);n.length>0&&t.push(n.trimEnd());let r=Fe(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Body`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Body was truncated due to size limits.*`)),e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),e.commentsTruncated&&(t.push(``),t.push(`*Note: Comments were truncated due to limits.*`)),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` -`)}function Le(e){let t=[];t.push(`## Pull Request #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`),t.push(`**Base:** ${e.baseBranch} ← **Head:** ${e.headBranch}`),e.isFork&&t.push(`**Fork:** Yes (external contributor)`);let n=Pe(e.labels);n.length>0&&t.push(n.trimEnd());let r=Fe(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Description`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Description was truncated due to size limits.*`)),e.files.length>0){t.push(``),t.push(`### Files Changed (${e.files.length}${e.filesTruncated?` of ${e.totalFiles}`:``})`),t.push(``),t.push(`| File | +/- |`),t.push(`|------|-----|`);for(let n of e.files)t.push(`| \`${n.path}\` | +${n.additions}/-${n.deletions} |`)}if(e.commits.length>0){t.push(``),t.push(`### Commits (${e.commits.length}${e.commitsTruncated?` of ${e.totalCommits}`:``})`),t.push(``);for(let n of e.commits){let e=n.oid.slice(0,7);t.push(`- \`${e}\` ${n.message.split(` +import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,Q as g,R as _,S as v,T as y,U as b,V as x,W as S,X as C,Y as w,Z as T,_ as E,a as ee,b as te,c as D,d as ne,f as re,g as O,h as k,i as A,j,k as M,l as ie,m as N,n as ae,o as oe,p as se,q as P,r as F,s as ce,t as I,u as L,v as le,w as ue,x as de,y as fe,z as R}from"./state-keys-CDII8qo6.js";import*as z from"node:path";import pe,{join as B}from"node:path";import V from"node:process";import*as me from"os";import{EOL as he}from"os";import*as ge from"crypto";import*as H from"fs";import{existsSync as _e,readFileSync as ve}from"fs";import*as U from"path";import{ok as ye}from"assert";import*as be from"util";import{Buffer as xe}from"node:buffer";import*as Se from"node:crypto";import{pathToFileURL as Ce}from"node:url";import*as W from"node:fs/promises";import we from"node:fs/promises";import{spawn as Te}from"node:child_process";import*as Ee from"node:os";import De,{homedir as Oe}from"node:os";import*as ke from"stream";const Ae={maxComments:50,maxCommits:100,maxFiles:100,maxReviews:100,maxBodyBytes:10*1024,maxTotalBytes:100*1024},je=`…[truncated]`;function Me(e,t){if(e.length===0)return{text:``,truncated:!1};let n=new TextEncoder,r=n.encode(e);if(r.length<=t)return{text:e,truncated:!1};let i=t-n.encode(je).length;if(i<=0)return{text:je,truncated:!0};let a=r.slice(0,i),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);for(;o.length>0&&o.charCodeAt(o.length-1)===65533;)a=a.slice(0,-1),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);return{text:o+je,truncated:!0}}function Ne(e){return e.length===0?``:`**Labels:** ${e.map(e=>`\`${e.name}\``).join(`, `)}\n`}function Pe(e){return e.length===0?``:`**Assignees:** ${e.map(e=>`@${e.login}`).join(`, `)}\n`}function Fe(e){let t=[];t.push(`## Issue #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`);let n=Ne(e.labels);n.length>0&&t.push(n.trimEnd());let r=Pe(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Body`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Body was truncated due to size limits.*`)),e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),e.commentsTruncated&&(t.push(``),t.push(`*Note: Comments were truncated due to limits.*`)),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` +`)}function Ie(e){let t=[];t.push(`## Pull Request #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`),t.push(`**Base:** ${e.baseBranch} ← **Head:** ${e.headBranch}`),e.isFork&&t.push(`**Fork:** Yes (external contributor)`);let n=Ne(e.labels);n.length>0&&t.push(n.trimEnd());let r=Pe(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Description`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Description was truncated due to size limits.*`)),e.files.length>0){t.push(``),t.push(`### Files Changed (${e.files.length}${e.filesTruncated?` of ${e.totalFiles}`:``})`),t.push(``),t.push(`| File | +/- |`),t.push(`|------|-----|`);for(let n of e.files)t.push(`| \`${n.path}\` | +${n.additions}/-${n.deletions} |`)}if(e.commits.length>0){t.push(``),t.push(`### Commits (${e.commits.length}${e.commitsTruncated?` of ${e.totalCommits}`:``})`),t.push(``);for(let n of e.commits){let e=n.oid.slice(0,7);t.push(`- \`${e}\` ${n.message.split(` `)[0]}`)}}if(e.reviews.length>0){t.push(``),t.push(`### Reviews (${e.reviews.length}${e.reviewsTruncated?` of ${e.totalReviews}`:``})`),t.push(``);for(let n of e.reviews)t.push(`**${n.author??`unknown`}** - ${n.state}`),n.body.length>0&&t.push(n.body),t.push(``)}if(e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` -`)}function Re(e){return e.type===`issue`?Ie(e):Le(e)}async function ze(e,t,n,r,i,a){try{let[a,o]=await Promise.all([e.rest.issues.get({owner:t,repo:n,issue_number:r}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),s=a.data,c=Ne(s.body??``,i.maxBodyBytes),l=o.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),u=(s.labels??[]).filter(e=>typeof e==`object`&&!!e&&`name`in e).map(e=>({name:e.name??``,color:e.color})),d=(s.assignees??[]).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.user?.login??null,createdAt:s.created_at,labels:u,assignees:d,comments:l,commentsTruncated:o.data.length>=i.maxComments,totalComments:o.data.length}}catch(e){return a.warning(`REST issue fallback failed`,{owner:t,repo:n,number:r,error:N(e)}),null}}async function Be(e,t,n,r,i,a){try{let[o,s,c,l,u]=await Promise.all([e.rest.pulls.get({owner:t,repo:n,pull_number:r}),e.rest.pulls.listCommits({owner:t,repo:n,pull_number:r,per_page:i.maxCommits}),e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:i.maxFiles}),e.rest.pulls.listReviews({owner:t,repo:n,pull_number:r,per_page:i.maxReviews}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),d=await e.rest.pulls.listRequestedReviewers({owner:t,repo:n,pull_number:r}).catch(e=>(a.warning(`Failed to fetch requested reviewers, defaulting to empty`,{owner:t,repo:n,number:r,error:N(e)}),{data:{users:[],teams:[]}})),f=o.data,p=Ne(f.body??``,i.maxBodyBytes),m=f.base.repo?.owner.login,h=f.head.repo?.owner.login,g=h==null||m!==h,_=u.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),v=s.data.slice(0,i.maxCommits).map(e=>({oid:e.sha,message:e.commit.message,author:e.commit.author?.name??null})),y=c.data.slice(0,i.maxFiles).map(e=>({path:e.filename,additions:e.additions,deletions:e.deletions,status:e.status})),b=l.data.slice(0,i.maxReviews).map(e=>({author:e.user?.login??null,state:e.state,body:e.body??``,createdAt:e.submitted_at??``,comments:[]})),x=(f.labels??[]).map(e=>({name:e.name??``,color:e.color})),S=(f.assignees??[]).map(e=>({login:e?.login??``})),C=(d.data.users??[]).map(e=>e.login),w=(d.data.teams??[]).map(e=>e.name);return{type:`pull_request`,number:f.number,title:f.title,body:p.text,bodyTruncated:p.truncated,state:f.state,author:f.user?.login??null,createdAt:f.created_at,baseBranch:f.base.ref,headBranch:f.head.ref,isFork:g,labels:x,assignees:S,comments:_,commentsTruncated:u.data.length>=i.maxComments,totalComments:u.data.length,commits:v,commitsTruncated:s.data.length>=i.maxCommits,totalCommits:s.data.length,files:y,filesTruncated:c.data.length>=i.maxFiles,totalFiles:c.data.length,reviews:b,reviewsTruncated:l.data.length>=i.maxReviews,totalReviews:l.data.length,authorAssociation:f.author_association,requestedReviewers:C,requestedReviewerTeams:w}}catch(e){return a.warning(`REST pull request fallback failed`,{owner:t,repo:n,number:r,error:N(e)}),null}}async function Ve(e,t,n,r,i,a){try{return await e.graphql(` +`)}function Le(e){return e.type===`issue`?Fe(e):Ie(e)}async function Re(e,t,n,r,i,a){try{let[a,o]=await Promise.all([e.rest.issues.get({owner:t,repo:n,issue_number:r}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),s=a.data,c=Me(s.body??``,i.maxBodyBytes),l=o.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),u=(s.labels??[]).filter(e=>typeof e==`object`&&!!e&&`name`in e).map(e=>({name:e.name??``,color:e.color})),d=(s.assignees??[]).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.user?.login??null,createdAt:s.created_at,labels:u,assignees:d,comments:l,commentsTruncated:o.data.length>=i.maxComments,totalComments:o.data.length}}catch(e){return a.warning(`REST issue fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function ze(e,t,n,r,i,a){try{let[o,s,c,l,u]=await Promise.all([e.rest.pulls.get({owner:t,repo:n,pull_number:r}),e.rest.pulls.listCommits({owner:t,repo:n,pull_number:r,per_page:i.maxCommits}),e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:i.maxFiles}),e.rest.pulls.listReviews({owner:t,repo:n,pull_number:r,per_page:i.maxReviews}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),d=await e.rest.pulls.listRequestedReviewers({owner:t,repo:n,pull_number:r}).catch(e=>(a.warning(`Failed to fetch requested reviewers, defaulting to empty`,{owner:t,repo:n,number:r,error:M(e)}),{data:{users:[],teams:[]}})),f=o.data,p=Me(f.body??``,i.maxBodyBytes),m=f.base.repo?.owner.login,h=f.head.repo?.owner.login,g=h==null||m!==h,_=u.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),v=s.data.slice(0,i.maxCommits).map(e=>({oid:e.sha,message:e.commit.message,author:e.commit.author?.name??null})),y=c.data.slice(0,i.maxFiles).map(e=>({path:e.filename,additions:e.additions,deletions:e.deletions,status:e.status})),b=l.data.slice(0,i.maxReviews).map(e=>({author:e.user?.login??null,state:e.state,body:e.body??``,createdAt:e.submitted_at??``,comments:[]})),x=(f.labels??[]).map(e=>({name:e.name??``,color:e.color})),S=(f.assignees??[]).map(e=>({login:e?.login??``})),C=(d.data.users??[]).map(e=>e.login),w=(d.data.teams??[]).map(e=>e.name);return{type:`pull_request`,number:f.number,title:f.title,body:p.text,bodyTruncated:p.truncated,state:f.state,author:f.user?.login??null,createdAt:f.created_at,baseBranch:f.base.ref,headBranch:f.head.ref,isFork:g,labels:x,assignees:S,comments:_,commentsTruncated:u.data.length>=i.maxComments,totalComments:u.data.length,commits:v,commitsTruncated:s.data.length>=i.maxCommits,totalCommits:s.data.length,files:y,filesTruncated:c.data.length>=i.maxFiles,totalFiles:c.data.length,reviews:b,reviewsTruncated:l.data.length>=i.maxReviews,totalReviews:l.data.length,authorAssociation:f.author_association,requestedReviewers:C,requestedReviewerTeams:w}}catch(e){return a.warning(`REST pull request fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function Be(e,t,n,r,i,a){try{return await e.graphql(` query GetIssue($owner: String!, $repo: String!, $number: Int!, $maxComments: Int!) { repository(owner: $owner, name: $repo) { issue(number: $number) { @@ -31,7 +31,7 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a } } } -`,{owner:t,repo:n,number:r,maxComments:i})}catch(e){return a.warning(`GraphQL issue query failed`,{owner:t,repo:n,number:r,error:N(e)}),null}}async function He(e,t,n,r,i,a,o,s,c){try{return await e.graphql(` +`,{owner:t,repo:n,number:r,maxComments:i})}catch(e){return a.warning(`GraphQL issue query failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function Ve(e,t,n,r,i,a,o,s,c){try{return await e.graphql(` query GetPullRequest( $owner: String!, $repo: String!, @@ -119,15 +119,15 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a } } } -`,{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:N(e)}),null}}async function Ue(e,t,n,r,i,a){let o=await Ve(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=Ne(s.body??``,i.maxBodyBytes),l=s.comments.nodes.slice(0,i.maxComments),u=s.comments.totalCount>l.length,d=l.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),f=s.labels.nodes.map(e=>({name:e.name,color:e.color})),p=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:f,assignees:p,comments:d,commentsTruncated:u,totalComments:s.comments.totalCount}}async function We(e,t,n,r,i,a){let o=await He(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=Ne(s.body??``,i.maxBodyBytes),l=s.baseRepository?.owner.login,u=s.headRepository?.owner.login,d=u==null||l!==u,f=s.comments.nodes.slice(0,i.maxComments),p=s.comments.totalCount>f.length,m=f.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),h=s.commits.nodes.slice(0,i.maxCommits),g=s.commits.totalCount>h.length,_=h.map(e=>({oid:e.commit.oid,message:e.commit.message,author:e.commit.author?.name??null})),v=s.files.nodes.slice(0,i.maxFiles),y=s.files.totalCount>v.length,b=v.map(e=>({path:e.path,additions:e.additions,deletions:e.deletions})),x=s.reviews.nodes.slice(0,i.maxReviews),S=s.reviews.totalCount>x.length,C=x.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}))})),w=s.labels.nodes.map(e=>({name:e.name,color:e.color})),T=s.assignees.nodes.map(e=>({login:e.login})),E=s.reviewRequests.nodes.map(e=>`login`in e.requestedReviewer?e.requestedReviewer.login:null).filter(e=>e!=null),ee=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:w,assignees:T,comments:m,commentsTruncated:p,totalComments:s.comments.totalCount,commits:_,commitsTruncated:g,totalCommits:s.commits.totalCount,files:b,filesTruncated:y,totalFiles:s.files.totalCount,reviews:C,reviewsTruncated:S,totalReviews:s.reviews.totalCount,authorAssociation:s.authorAssociation,requestedReviewers:E,requestedReviewerTeams:ee}}function W(e){let[t,n]=e.split(`/`);if(t==null||n==null||t.length===0||n.length===0)throw Error(`Invalid repository string: ${e}`);return{owner:t,repo:n}}async function Ge(e,t,n,r,i){try{let{owner:a,repo:o}=W(t),{data:s}=await e.rest.reactions.createForIssueComment({owner:a,repo:o,comment_id:n,content:r});return i.debug(`Created comment reaction`,{commentId:n,content:r,reactionId:s.id}),{id:s.id}}catch(e){return i.warning(`Failed to create comment reaction`,{commentId:n,content:r,error:N(e)}),null}}async function Ke(e,t,n,r){try{let{owner:r,repo:i}=W(t),{data:a}=await e.rest.reactions.listForIssueComment({owner:r,repo:i,comment_id:n,per_page:100});return a.map(e=>({id:e.id,content:e.content,userLogin:e.user?.login??null}))}catch(e){return r.warning(`Failed to list comment reactions`,{commentId:n,error:N(e)}),[]}}async function qe(e,t,n,r,i){try{let{owner:a,repo:o}=W(t);return await e.rest.reactions.deleteForIssueComment({owner:a,repo:o,comment_id:n,reaction_id:r}),i.debug(`Deleted comment reaction`,{commentId:n,reactionId:r}),!0}catch(e){return i.warning(`Failed to delete comment reaction`,{commentId:n,reactionId:r,error:N(e)}),!1}}async function Je(e,t,n,r,i,a){let{owner:o,repo:s}=W(t);try{return await e.rest.issues.createLabel({owner:o,repo:s,name:n,color:r,description:i}),a.debug(`Created label`,{name:n,color:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===422?(a.debug(`Label already exists`,{name:n}),!0):(a.warning(`Failed to create label`,{name:n,error:N(e)}),!1)}}async function Ye(e,t,n,r,i){try{let{owner:a,repo:o}=W(t);return await e.rest.issues.addLabels({owner:a,repo:o,issue_number:n,labels:[...r]}),i.debug(`Added labels to issue`,{issueNumber:n,labels:r}),!0}catch(e){return i.warning(`Failed to add labels to issue`,{issueNumber:n,labels:r,error:N(e)}),!1}}async function Xe(e,t,n,r,i){try{let{owner:a,repo:o}=W(t);return await e.rest.issues.removeLabel({owner:a,repo:o,issue_number:n,name:r}),i.debug(`Removed label from issue`,{issueNumber:n,label:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===404?(i.debug(`Label was not present on issue`,{issueNumber:n,label:r}),!0):(i.warning(`Failed to remove label from issue`,{issueNumber:n,label:r,error:N(e)}),!1)}}async function Ze(e,t,n){try{let{owner:n,repo:r}=W(t),{data:i}=await e.rest.repos.get({owner:n,repo:r});return i.default_branch}catch(e){return n.warning(`Failed to get default branch`,{repo:t,error:N(e)}),`main`}}async function Qe(e,t,n){try{let{data:n}=await e.rest.users.getByUsername({username:t});return{id:n.id,login:n.login}}catch(e){return n.debug(`Failed to get user by username`,{username:t,error:N(e)}),null}}const $e={PER_PAGE:100,MAX_PAGES:50};async function et(e,t,n,r,i){i.debug(`Fetching PR diff`,{prNumber:r});let a=[],o=1,s=!1;for(;o<=$e.MAX_PAGES;){let{data:c}=await e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:$e.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.length<$e.PER_PAGE)break;o++,o>$e.MAX_PAGES&&(s=!0,i.warning(`PR diff pagination limit reached`,{filesLoaded:a.length,maxPages:$e.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}}async function tt(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 et(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:N(e)}),null}}async function nt(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?.number??null,g=l?.title??null,_=u?.login??null,v=await tt(r,n,p,t),y=await rt(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):!1;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 Ze(n,p,t),diffContext:v,hydratedContext:y,authorAssociation:x,isRequestedReviewer:S}}async function rt(e,t,n,r,i,a){if(r==null||i==null)return null;let o=je;return i===`issue`?await Ue(e,t,n,r,o,a)??ze(e,t,n,r,o,a):await We(e,t,n,r,o,a)??Be(e,t,n,r,o,a)}const it=({onSseError:e,onSseEvent:t,responseTransformer:n,responseValidator:r,sseDefaultRetryDelay:i,sseMaxRetryAttempts:a,sseMaxRetryDelay:o,sseSleepFn:s,url:c,...l})=>{let u,d=s??(e=>new Promise(t=>setTimeout(t,e)));return{stream:async function*(){let s=i??3e3,f=0,p=l.signal??new AbortController().signal;for(;!p.aborted;){f++;let i=l.headers instanceof Headers?l.headers:new Headers(l.headers);u!==void 0&&i.set(`Last-Event-ID`,u);try{let e=await fetch(c,{...l,headers:i,signal:p});if(!e.ok)throw Error(`SSE failed: ${e.status} ${e.statusText}`);if(!e.body)throw Error(`No body in SSE response`);let a=e.body.pipeThrough(new TextDecoderStream).getReader(),o=``,d=()=>{try{a.cancel()}catch{}};p.addEventListener(`abort`,d);try{for(;;){let{done:e,value:i}=await a.read();if(e)break;o+=i;let c=o.split(` +`,{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:M(e)}),null}}async function He(e,t,n,r,i,a){let o=await Be(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=Me(s.body??``,i.maxBodyBytes),l=s.comments.nodes.slice(0,i.maxComments),u=s.comments.totalCount>l.length,d=l.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),f=s.labels.nodes.map(e=>({name:e.name,color:e.color})),p=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:f,assignees:p,comments:d,commentsTruncated:u,totalComments:s.comments.totalCount}}async function Ue(e,t,n,r,i,a){let o=await Ve(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=Me(s.body??``,i.maxBodyBytes),l=s.baseRepository?.owner.login,u=s.headRepository?.owner.login,d=u==null||l!==u,f=s.comments.nodes.slice(0,i.maxComments),p=s.comments.totalCount>f.length,m=f.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),h=s.commits.nodes.slice(0,i.maxCommits),g=s.commits.totalCount>h.length,_=h.map(e=>({oid:e.commit.oid,message:e.commit.message,author:e.commit.author?.name??null})),v=s.files.nodes.slice(0,i.maxFiles),y=s.files.totalCount>v.length,b=v.map(e=>({path:e.path,additions:e.additions,deletions:e.deletions})),x=s.reviews.nodes.slice(0,i.maxReviews),S=s.reviews.totalCount>x.length,C=x.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}))})),w=s.labels.nodes.map(e=>({name:e.name,color:e.color})),T=s.assignees.nodes.map(e=>({login:e.login})),E=s.reviewRequests.nodes.map(e=>`login`in e.requestedReviewer?e.requestedReviewer.login:null).filter(e=>e!=null),ee=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:w,assignees:T,comments:m,commentsTruncated:p,totalComments:s.comments.totalCount,commits:_,commitsTruncated:g,totalCommits:s.commits.totalCount,files:b,filesTruncated:y,totalFiles:s.files.totalCount,reviews:C,reviewsTruncated:S,totalReviews:s.reviews.totalCount,authorAssociation:s.authorAssociation,requestedReviewers:E,requestedReviewerTeams:ee}}function G(e){let[t,n]=e.split(`/`);if(t==null||n==null||t.length===0||n.length===0)throw Error(`Invalid repository string: ${e}`);return{owner:t,repo:n}}async function We(e,t,n,r,i){try{let{owner:a,repo:o}=G(t),{data:s}=await e.rest.reactions.createForIssueComment({owner:a,repo:o,comment_id:n,content:r});return i.debug(`Created comment reaction`,{commentId:n,content:r,reactionId:s.id}),{id:s.id}}catch(e){return i.warning(`Failed to create comment reaction`,{commentId:n,content:r,error:M(e)}),null}}async function Ge(e,t,n,r){try{let{owner:r,repo:i}=G(t),{data:a}=await e.rest.reactions.listForIssueComment({owner:r,repo:i,comment_id:n,per_page:100});return a.map(e=>({id:e.id,content:e.content,userLogin:e.user?.login??null}))}catch(e){return r.warning(`Failed to list comment reactions`,{commentId:n,error:M(e)}),[]}}async function Ke(e,t,n,r,i){try{let{owner:a,repo:o}=G(t);return await e.rest.reactions.deleteForIssueComment({owner:a,repo:o,comment_id:n,reaction_id:r}),i.debug(`Deleted comment reaction`,{commentId:n,reactionId:r}),!0}catch(e){return i.warning(`Failed to delete comment reaction`,{commentId:n,reactionId:r,error:M(e)}),!1}}async function qe(e,t,n,r,i,a){let{owner:o,repo:s}=G(t);try{return await e.rest.issues.createLabel({owner:o,repo:s,name:n,color:r,description:i}),a.debug(`Created label`,{name:n,color:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===422?(a.debug(`Label already exists`,{name:n}),!0):(a.warning(`Failed to create label`,{name:n,error:M(e)}),!1)}}async function Je(e,t,n,r,i){try{let{owner:a,repo:o}=G(t);return await e.rest.issues.addLabels({owner:a,repo:o,issue_number:n,labels:[...r]}),i.debug(`Added labels to issue`,{issueNumber:n,labels:r}),!0}catch(e){return i.warning(`Failed to add labels to issue`,{issueNumber:n,labels:r,error:M(e)}),!1}}async function Ye(e,t,n,r,i){try{let{owner:a,repo:o}=G(t);return await e.rest.issues.removeLabel({owner:a,repo:o,issue_number:n,name:r}),i.debug(`Removed label from issue`,{issueNumber:n,label:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===404?(i.debug(`Label was not present on issue`,{issueNumber:n,label:r}),!0):(i.warning(`Failed to remove label from issue`,{issueNumber:n,label:r,error:M(e)}),!1)}}async function Xe(e,t,n){try{let{owner:n,repo:r}=G(t),{data:i}=await e.rest.repos.get({owner:n,repo:r});return i.default_branch}catch(e){return n.warning(`Failed to get default branch`,{repo:t,error:M(e)}),`main`}}async function Ze(e,t,n){try{let{data:n}=await e.rest.users.getByUsername({username:t});return{id:n.id,login:n.login}}catch(e){return n.debug(`Failed to get user by username`,{username:t,error:M(e)}),null}}const Qe={PER_PAGE:100,MAX_PAGES:50};async function $e(e,t,n,r,i){i.debug(`Fetching PR diff`,{prNumber:r});let a=[],o=1,s=!1;for(;o<=Qe.MAX_PAGES;){let{data:c}=await e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:Qe.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.lengthQe.MAX_PAGES&&(s=!0,i.warning(`PR diff pagination limit reached`,{filesLoaded:a.length,maxPages:Qe.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}}async function et(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 $e(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:M(e)}),null}}async function tt(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?.number??null,g=l?.title??null,_=u?.login??null,v=await et(r,n,p,t),y=await nt(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):!1;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 Xe(n,p,t),diffContext:v,hydratedContext:y,authorAssociation:x,isRequestedReviewer:S}}async function nt(e,t,n,r,i,a){if(r==null||i==null)return null;let o=Ae;return i===`issue`?await He(e,t,n,r,o,a)??Re(e,t,n,r,o,a):await Ue(e,t,n,r,o,a)??ze(e,t,n,r,o,a)}const rt=({onSseError:e,onSseEvent:t,responseTransformer:n,responseValidator:r,sseDefaultRetryDelay:i,sseMaxRetryAttempts:a,sseMaxRetryDelay:o,sseSleepFn:s,url:c,...l})=>{let u,d=s??(e=>new Promise(t=>setTimeout(t,e)));return{stream:async function*(){let s=i??3e3,f=0,p=l.signal??new AbortController().signal;for(;!p.aborted;){f++;let i=l.headers instanceof Headers?l.headers:new Headers(l.headers);u!==void 0&&i.set(`Last-Event-ID`,u);try{let e=await fetch(c,{...l,headers:i,signal:p});if(!e.ok)throw Error(`SSE failed: ${e.status} ${e.statusText}`);if(!e.body)throw Error(`No body in SSE response`);let a=e.body.pipeThrough(new TextDecoderStream).getReader(),o=``,d=()=>{try{a.cancel()}catch{}};p.addEventListener(`abort`,d);try{for(;;){let{done:e,value:i}=await a.read();if(e)break;o+=i;let c=o.split(` `);o=c.pop()??``;for(let e of c){let i=e.split(` `),a=[],o;for(let e of i)if(e.startsWith(`data:`))a.push(e.replace(/^data:\s*/,``));else if(e.startsWith(`event:`))o=e.replace(/^event:\s*/,``);else if(e.startsWith(`id:`))u=e.replace(/^id:\s*/,``);else if(e.startsWith(`retry:`)){let t=Number.parseInt(e.replace(/^retry:\s*/,``),10);Number.isNaN(t)||(s=t)}let c,l=!1;if(a.length){let e=a.join(` -`);try{c=JSON.parse(e),l=!0}catch{c=e}}l&&(r&&await r(c),n&&(c=await n(c))),t?.({data:c,event:o,id:u,retry:s}),a.length&&(yield c)}}}finally{p.removeEventListener(`abort`,d),a.releaseLock()}break}catch(t){if(e?.(t),a!==void 0&&f>=a)break;await d(Math.min(s*2**(f-1),o??3e4))}}}()}},at=async(e,t)=>{let n=typeof t==`function`?await t(e):t;if(n)return e.scheme===`bearer`?`Bearer ${n}`:e.scheme===`basic`?`Basic ${btoa(n)}`:n},ot={bodySerializer:e=>JSON.stringify(e,(e,t)=>typeof t==`bigint`?t.toString():t)},st=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},ct=e=>{switch(e){case`form`:return`,`;case`pipeDelimited`:return`|`;case`spaceDelimited`:return`%20`;default:return`,`}},lt=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},ut=({allowReserved:e,explode:t,name:n,style:r,value:i})=>{if(!t){let t=(e?i:i.map(e=>encodeURIComponent(e))).join(ct(r));switch(r){case`label`:return`.${t}`;case`matrix`:return`;${n}=${t}`;case`simple`:return t;default:return`${n}=${t}`}}let a=st(r),o=i.map(t=>r===`label`||r===`simple`?e?t:encodeURIComponent(t):dt({allowReserved:e,name:n,value:t})).join(a);return r===`label`||r===`matrix`?a+o:o},dt=({allowReserved:e,name:t,value:n})=>{if(n==null)return``;if(typeof n==`object`)throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${t}=${e?n:encodeURIComponent(n)}`},ft=({allowReserved:e,explode:t,name:n,style:r,value:i,valueOnly:a})=>{if(i instanceof Date)return a?i.toISOString():`${n}=${i.toISOString()}`;if(r!==`deepObject`&&!t){let t=[];Object.entries(i).forEach(([n,r])=>{t=[...t,n,e?r:encodeURIComponent(r)]});let a=t.join(`,`);switch(r){case`form`:return`${n}=${a}`;case`label`:return`.${a}`;case`matrix`:return`;${n}=${a}`;default:return a}}let o=lt(r),s=Object.entries(i).map(([t,i])=>dt({allowReserved:e,name:r===`deepObject`?`${n}[${t}]`:t,value:i})).join(o);return r===`label`||r===`matrix`?o+s:s},pt=/\{[^{}]+\}/g,mt=({path:e,url:t})=>{let n=t,r=t.match(pt);if(r)for(let t of r){let r=!1,i=t.substring(1,t.length-1),a=`simple`;i.endsWith(`*`)&&(r=!0,i=i.substring(0,i.length-1)),i.startsWith(`.`)?(i=i.substring(1),a=`label`):i.startsWith(`;`)&&(i=i.substring(1),a=`matrix`);let o=e[i];if(o==null)continue;if(Array.isArray(o)){n=n.replace(t,ut({explode:r,name:i,style:a,value:o}));continue}if(typeof o==`object`){n=n.replace(t,ft({explode:r,name:i,style:a,value:o,valueOnly:!0}));continue}if(a===`matrix`){n=n.replace(t,`;${dt({name:i,value:o})}`);continue}let s=encodeURIComponent(a===`label`?`.${o}`:o);n=n.replace(t,s)}return n},ht=({baseUrl:e,path:t,query:n,querySerializer:r,url:i})=>{let a=i.startsWith(`/`)?i:`/${i}`,o=(e??``)+a;t&&(o=mt({path:t,url:o}));let s=n?r(n):``;return s.startsWith(`?`)&&(s=s.substring(1)),s&&(o+=`?${s}`),o},gt=({allowReserved:e,array:t,object:n}={})=>r=>{let i=[];if(r&&typeof r==`object`)for(let a in r){let o=r[a];if(o!=null)if(Array.isArray(o)){let n=ut({allowReserved:e,explode:!0,name:a,style:`form`,value:o,...t});n&&i.push(n)}else if(typeof o==`object`){let t=ft({allowReserved:e,explode:!0,name:a,style:`deepObject`,value:o,...n});t&&i.push(t)}else{let t=dt({allowReserved:e,name:a,value:o});t&&i.push(t)}}return i.join(`&`)},_t=e=>{if(!e)return`stream`;let t=e.split(`;`)[0]?.trim();if(t){if(t.startsWith(`application/json`)||t.endsWith(`+json`))return`json`;if(t===`multipart/form-data`)return`formData`;if([`application/`,`audio/`,`image/`,`video/`].some(e=>t.startsWith(e)))return`blob`;if(t.startsWith(`text/`))return`text`}},vt=(e,t)=>t?!!(e.headers.has(t)||e.query?.[t]||e.headers.get(`Cookie`)?.includes(`${t}=`)):!1,yt=async({security:e,...t})=>{for(let n of e){if(vt(t,n.name))continue;let e=await at(n,t.auth);if(!e)continue;let r=n.name??`Authorization`;switch(n.in){case`query`:t.query||={},t.query[r]=e;break;case`cookie`:t.headers.append(`Cookie`,`${r}=${e}`);break;default:t.headers.set(r,e);break}}},bt=e=>ht({baseUrl:e.baseUrl,path:e.path,query:e.query,querySerializer:typeof e.querySerializer==`function`?e.querySerializer:gt(e.querySerializer),url:e.url}),xt=(e,t)=>{let n={...e,...t};return n.baseUrl?.endsWith(`/`)&&(n.baseUrl=n.baseUrl.substring(0,n.baseUrl.length-1)),n.headers=St(e.headers,t.headers),n},St=(...e)=>{let t=new Headers;for(let n of e){if(!n||typeof n!=`object`)continue;let e=n instanceof Headers?n.entries():Object.entries(n);for(let[n,r]of e)if(r===null)t.delete(n);else if(Array.isArray(r))for(let e of r)t.append(n,e);else r!==void 0&&t.set(n,typeof r==`object`?JSON.stringify(r):r)}return t};var Ct=class{_fns;constructor(){this._fns=[]}clear(){this._fns=[]}getInterceptorIndex(e){return typeof e==`number`?this._fns[e]?e:-1:this._fns.indexOf(e)}exists(e){let t=this.getInterceptorIndex(e);return!!this._fns[t]}eject(e){let t=this.getInterceptorIndex(e);this._fns[t]&&(this._fns[t]=null)}update(e,t){let n=this.getInterceptorIndex(e);return this._fns[n]?(this._fns[n]=t,e):!1}use(e){return this._fns=[...this._fns,e],this._fns.length-1}};const wt=()=>({error:new Ct,request:new Ct,response:new Ct}),Tt=gt({allowReserved:!1,array:{explode:!0,style:`form`},object:{explode:!0,style:`deepObject`}}),Et={"Content-Type":`application/json`},Dt=(e={})=>({...ot,headers:Et,parseAs:`auto`,querySerializer:Tt,...e}),Ot=(e={})=>{let t=xt(Dt(),e),n=()=>({...t}),r=e=>(t=xt(t,e),n()),i=wt(),a=async e=>{let n={...t,...e,fetch:e.fetch??t.fetch??globalThis.fetch,headers:St(t.headers,e.headers),serializedBody:void 0};return n.security&&await yt({...n,security:n.security}),n.requestValidator&&await n.requestValidator(n),n.body&&n.bodySerializer&&(n.serializedBody=n.bodySerializer(n.body)),(n.serializedBody===void 0||n.serializedBody===``)&&n.headers.delete(`Content-Type`),{opts:n,url:bt(n)}},o=async e=>{let{opts:t,url:n}=await a(e),r={redirect:`follow`,...t,body:t.serializedBody},o=new Request(n,r);for(let e of i.request._fns)e&&(o=await e(o,t));let s=t.fetch,c=await s(o);for(let e of i.response._fns)e&&(c=await e(c,o,t));let l={request:o,response:c};if(c.ok){if(c.status===204||c.headers.get(`Content-Length`)===`0`)return t.responseStyle===`data`?{}:{data:{},...l};let e=(t.parseAs===`auto`?_t(c.headers.get(`Content-Type`)):t.parseAs)??`json`,n;switch(e){case`arrayBuffer`:case`blob`:case`formData`:case`json`:case`text`:n=await c[e]();break;case`stream`:return t.responseStyle===`data`?c.body:{data:c.body,...l}}return e===`json`&&(t.responseValidator&&await t.responseValidator(n),t.responseTransformer&&(n=await t.responseTransformer(n))),t.responseStyle===`data`?n:{data:n,...l}}let u=await c.text(),d;try{d=JSON.parse(u)}catch{}let f=d??u,p=f;for(let e of i.error._fns)e&&(p=await e(f,c,o,t));if(p||={},t.throwOnError)throw p;return t.responseStyle===`data`?void 0:{error:p,...l}},s=e=>{let t=t=>o({...t,method:e});return t.sse=async t=>{let{opts:n,url:r}=await a(t);return it({...n,body:n.body,headers:n.headers,method:e,url:r})},t};return{buildUrl:bt,connect:s(`CONNECT`),delete:s(`DELETE`),get:s(`GET`),getConfig:n,head:s(`HEAD`),interceptors:i,options:s(`OPTIONS`),patch:s(`PATCH`),post:s(`POST`),put:s(`PUT`),request:o,setConfig:r,trace:s(`TRACE`)}};Object.entries({$body_:`body`,$headers_:`headers`,$path_:`path`,$query_:`query`});const kt=Ot(Dt({baseUrl:`http://localhost:4096`}));var G=class{_client=kt;constructor(e){e?.client&&(this._client=e.client)}},At=class extends G{event(e){return(e?.client??this._client).get.sse({url:`/global/event`,...e})}},jt=class extends G{list(e){return(e?.client??this._client).get({url:`/project`,...e})}current(e){return(e?.client??this._client).get({url:`/project/current`,...e})}},Mt=class extends G{list(e){return(e?.client??this._client).get({url:`/pty`,...e})}create(e){return(e?.client??this._client).post({url:`/pty`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}remove(e){return(e.client??this._client).delete({url:`/pty/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/pty/{id}`,...e})}update(e){return(e.client??this._client).put({url:`/pty/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}connect(e){return(e.client??this._client).get({url:`/pty/{id}/connect`,...e})}},Nt=class extends G{get(e){return(e?.client??this._client).get({url:`/config`,...e})}update(e){return(e?.client??this._client).patch({url:`/config`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}providers(e){return(e?.client??this._client).get({url:`/config/providers`,...e})}},Pt=class extends G{ids(e){return(e?.client??this._client).get({url:`/experimental/tool/ids`,...e})}list(e){return(e.client??this._client).get({url:`/experimental/tool`,...e})}},Ft=class extends G{dispose(e){return(e?.client??this._client).post({url:`/instance/dispose`,...e})}},It=class extends G{get(e){return(e?.client??this._client).get({url:`/path`,...e})}},Lt=class extends G{get(e){return(e?.client??this._client).get({url:`/vcs`,...e})}},Rt=class extends G{list(e){return(e?.client??this._client).get({url:`/session`,...e})}create(e){return(e?.client??this._client).post({url:`/session`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}status(e){return(e?.client??this._client).get({url:`/session/status`,...e})}delete(e){return(e.client??this._client).delete({url:`/session/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/session/{id}`,...e})}update(e){return(e.client??this._client).patch({url:`/session/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}children(e){return(e.client??this._client).get({url:`/session/{id}/children`,...e})}todo(e){return(e.client??this._client).get({url:`/session/{id}/todo`,...e})}init(e){return(e.client??this._client).post({url:`/session/{id}/init`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}fork(e){return(e.client??this._client).post({url:`/session/{id}/fork`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}abort(e){return(e.client??this._client).post({url:`/session/{id}/abort`,...e})}unshare(e){return(e.client??this._client).delete({url:`/session/{id}/share`,...e})}share(e){return(e.client??this._client).post({url:`/session/{id}/share`,...e})}diff(e){return(e.client??this._client).get({url:`/session/{id}/diff`,...e})}summarize(e){return(e.client??this._client).post({url:`/session/{id}/summarize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}messages(e){return(e.client??this._client).get({url:`/session/{id}/message`,...e})}prompt(e){return(e.client??this._client).post({url:`/session/{id}/message`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}message(e){return(e.client??this._client).get({url:`/session/{id}/message/{messageID}`,...e})}promptAsync(e){return(e.client??this._client).post({url:`/session/{id}/prompt_async`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}command(e){return(e.client??this._client).post({url:`/session/{id}/command`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}shell(e){return(e.client??this._client).post({url:`/session/{id}/shell`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}revert(e){return(e.client??this._client).post({url:`/session/{id}/revert`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}unrevert(e){return(e.client??this._client).post({url:`/session/{id}/unrevert`,...e})}},zt=class extends G{list(e){return(e?.client??this._client).get({url:`/command`,...e})}},Bt=class extends G{authorize(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/authorize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}callback(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Vt=class extends G{list(e){return(e?.client??this._client).get({url:`/provider`,...e})}auth(e){return(e?.client??this._client).get({url:`/provider/auth`,...e})}oauth=new Bt({client:this._client})},Ht=class extends G{text(e){return(e.client??this._client).get({url:`/find`,...e})}files(e){return(e.client??this._client).get({url:`/find/file`,...e})}symbols(e){return(e.client??this._client).get({url:`/find/symbol`,...e})}},Ut=class extends G{list(e){return(e.client??this._client).get({url:`/file`,...e})}read(e){return(e.client??this._client).get({url:`/file/content`,...e})}status(e){return(e?.client??this._client).get({url:`/file/status`,...e})}},Wt=class extends G{log(e){return(e?.client??this._client).post({url:`/log`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}agents(e){return(e?.client??this._client).get({url:`/agent`,...e})}},Gt=class extends G{remove(e){return(e.client??this._client).delete({url:`/mcp/{name}/auth`,...e})}start(e){return(e.client??this._client).post({url:`/mcp/{name}/auth`,...e})}callback(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}authenticate(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/authenticate`,...e})}set(e){return(e.client??this._client).put({url:`/auth/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Kt=class extends G{status(e){return(e?.client??this._client).get({url:`/mcp`,...e})}add(e){return(e?.client??this._client).post({url:`/mcp`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}connect(e){return(e.client??this._client).post({url:`/mcp/{name}/connect`,...e})}disconnect(e){return(e.client??this._client).post({url:`/mcp/{name}/disconnect`,...e})}auth=new Gt({client:this._client})},qt=class extends G{status(e){return(e?.client??this._client).get({url:`/lsp`,...e})}},Jt=class extends G{status(e){return(e?.client??this._client).get({url:`/formatter`,...e})}},Yt=class extends G{next(e){return(e?.client??this._client).get({url:`/tui/control/next`,...e})}response(e){return(e?.client??this._client).post({url:`/tui/control/response`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}},Xt=class extends G{appendPrompt(e){return(e?.client??this._client).post({url:`/tui/append-prompt`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}openHelp(e){return(e?.client??this._client).post({url:`/tui/open-help`,...e})}openSessions(e){return(e?.client??this._client).post({url:`/tui/open-sessions`,...e})}openThemes(e){return(e?.client??this._client).post({url:`/tui/open-themes`,...e})}openModels(e){return(e?.client??this._client).post({url:`/tui/open-models`,...e})}submitPrompt(e){return(e?.client??this._client).post({url:`/tui/submit-prompt`,...e})}clearPrompt(e){return(e?.client??this._client).post({url:`/tui/clear-prompt`,...e})}executeCommand(e){return(e?.client??this._client).post({url:`/tui/execute-command`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}showToast(e){return(e?.client??this._client).post({url:`/tui/show-toast`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}publish(e){return(e?.client??this._client).post({url:`/tui/publish`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}control=new Yt({client:this._client})},Zt=class extends G{subscribe(e){return(e?.client??this._client).get.sse({url:`/event`,...e})}},Qt=class extends G{postSessionIdPermissionsPermissionId(e){return(e.client??this._client).post({url:`/session/{id}/permissions/{permissionID}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}global=new At({client:this._client});project=new jt({client:this._client});pty=new Mt({client:this._client});config=new Nt({client:this._client});tool=new Pt({client:this._client});instance=new Ft({client:this._client});path=new It({client:this._client});vcs=new Lt({client:this._client});session=new Rt({client:this._client});command=new zt({client:this._client});provider=new Vt({client:this._client});find=new Ht({client:this._client});file=new Ut({client:this._client});app=new Wt({client:this._client});mcp=new Kt({client:this._client});lsp=new qt({client:this._client});formatter=new Jt({client:this._client});tui=new Xt({client:this._client});auth=new Gt({client:this._client});event=new Zt({client:this._client})};function $t(e){if(!e?.fetch){let t=e=>(e.timeout=!1,fetch(e));e={...e,fetch:t}}return e?.directory&&(e.headers={...e.headers,"x-opencode-directory":encodeURIComponent(e.directory)}),new Qt({client:Ot(e)})}async function en(e){e=Object.assign({hostname:`127.0.0.1`,port:4096,timeout:5e3},e??{});let t=[`serve`,`--hostname=${e.hostname}`,`--port=${e.port}`];e.config?.logLevel&&t.push(`--log-level=${e.config.logLevel}`);let n=Ee(`opencode`,t,{signal:e.signal,env:{...process.env,OPENCODE_CONFIG_CONTENT:JSON.stringify(e.config??{})}});return{url:await new Promise((t,r)=>{let i=setTimeout(()=>{r(Error(`Timeout waiting for server to start after ${e.timeout}ms`))},e.timeout),a=``;n.stdout?.on(`data`,e=>{a+=e.toString();let n=a.split(` -`);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function tn(e){let t=await en({...e});return{client:$t({baseUrl:t.url}),server:t}}async function nn(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const rn={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},an=`\x1B[0m`;function on(){return B.env.NO_COLOR==null}function sn(e,t){let[n,r]=rn[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);on()?B.stdout.write(`\n${r}|${an} ${i} ${an}${t}\n`):B.stdout.write(`\n| ${i} ${t}\n`)}function cn(e){B.stdout.write(`\n${e}\n`)}const ln={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function un(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function dn(e){let t=un(e),n=ln[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` -`)}function fn(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const pn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function mn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return pn.some(e=>e.test(t))}function hn(e,t){return fn(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function gn(e,t){return fn(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}function _n(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function vn(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 yn(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(_n)}function bn(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)]}var xn=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(ve(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(ye(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${ge}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},Sn=T((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),Cn=e(T((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[d.Accept]=this._getExistingOrDefaultHeader(t,d.Accept,f.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===u.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&m.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!h.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},x(this.requestOptions.headers),x(e||{})):x(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[d.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[d.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new l.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===u.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let x=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),wn=w(),Tn=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function En(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function Dn(e){return new Cn.HttpClient().getAgent(e)}function On(e){return new Cn.HttpClient().getAgentDispatcher(e)}function kn(e){let t=On(e);return(e,n)=>Tn(this,void 0,void 0,function*(){return(0,wn.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function An(){return process.env.GITHUB_API_URL||`https://api.github.com`}function jn(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function Mn(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>Mn.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function Nn(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function Pn(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const Fn=Function.bind,In=Fn.bind(Fn);function Ln(e,t,n){let r=In(Pn,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=In(Nn,null).apply(null,i)})}function Rn(){let e=Symbol(`Singular`),t={registry:{}},n=Mn.bind(null,t,e);return Ln(n,t,e),n}function zn(){let e={registry:{}},t=Mn.bind(null,e);return Ln(t,e),t}var Bn={Singular:Rn,Collection:zn},Vn=`octokit-endpoint.js/0.0.0-development ${jn()}`,Hn={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":Vn},mediaType:{format:``}};function Un(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Wn(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Gn(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Wn(t[r])&&r in e?n[r]=Gn(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Kn(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function qn(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Un(n.headers),Kn(n),Kn(n.headers);let r=Gn(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function Jn(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var Yn=/\{[^{}}]+\}/g;function Xn(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Qn(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function $n(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function K(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function er(e,t,n){return t=e===`+`||e===`#`?$n(t):K(t),n?K(n)+`=`+t:t}function q(e){return e!=null}function tr(e){return e===`;`||e===`&`||e===`?`}function nr(e,t,n,r){var i=e[n],a=[];if(q(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push(er(t,i,tr(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(q).forEach(function(e){a.push(er(t,e,tr(t)?n:``))}):Object.keys(i).forEach(function(e){q(i[e])&&a.push(er(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(q).forEach(function(n){e.push(er(t,n))}):Object.keys(i).forEach(function(n){q(i[n])&&(e.push(K(n)),e.push(er(t,i[n].toString())))}),tr(t)?a.push(K(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?q(i)&&a.push(K(n)):i===``&&(t===`&`||t===`?`)?a.push(K(n)+`=`):i===``&&a.push(``);return a}function rr(e){return{expand:ir.bind(null,e)}}function ir(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(nr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return $n(i)}),e===`/`?e:e.replace(/\/$/,``)}function ar(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Qn(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Zn(n);n=rr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Qn(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=Jn(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function or(e,t,n){return ar(qn(e,t,n))}function sr(e,t){let n=qn(e,t),r=or.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:sr.bind(null,n),merge:qn.bind(null,n),parse:ar})}var cr=sr(null,Hn),lr=T(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))(),ur=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function hr(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=pr(e.body)||Array.isArray(e.body)?JSON.stringify(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new ur(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new ur(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await gr(o),new ur(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await gr(o),new ur(vr(u.data),s,{response:u,request:e});return u.data=r?await gr(o):o.body,u}async function gr(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(mr);let n=(0,lr.safeParse)(t);if(_r(n)){let t=``;try{return t=await e.text(),JSON.parse(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(mr);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function _r(e){return e.type===`application/json`||e.type===`application/scim+json`}function vr(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function yr(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return hr(n.parse(r));let i=(e,t)=>hr(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:yr.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:yr.bind(null,n)})}var br=yr(cr,fr),xr=`0.0.0-development`;function Sr(e){return`Request failed due to following response errors: +`);try{c=JSON.parse(e),l=!0}catch{c=e}}l&&(r&&await r(c),n&&(c=await n(c))),t?.({data:c,event:o,id:u,retry:s}),a.length&&(yield c)}}}finally{p.removeEventListener(`abort`,d),a.releaseLock()}break}catch(t){if(e?.(t),a!==void 0&&f>=a)break;await d(Math.min(s*2**(f-1),o??3e4))}}}()}},it=async(e,t)=>{let n=typeof t==`function`?await t(e):t;if(n)return e.scheme===`bearer`?`Bearer ${n}`:e.scheme===`basic`?`Basic ${btoa(n)}`:n},at={bodySerializer:e=>JSON.stringify(e,(e,t)=>typeof t==`bigint`?t.toString():t)},ot=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},st=e=>{switch(e){case`form`:return`,`;case`pipeDelimited`:return`|`;case`spaceDelimited`:return`%20`;default:return`,`}},ct=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},lt=({allowReserved:e,explode:t,name:n,style:r,value:i})=>{if(!t){let t=(e?i:i.map(e=>encodeURIComponent(e))).join(st(r));switch(r){case`label`:return`.${t}`;case`matrix`:return`;${n}=${t}`;case`simple`:return t;default:return`${n}=${t}`}}let a=ot(r),o=i.map(t=>r===`label`||r===`simple`?e?t:encodeURIComponent(t):ut({allowReserved:e,name:n,value:t})).join(a);return r===`label`||r===`matrix`?a+o:o},ut=({allowReserved:e,name:t,value:n})=>{if(n==null)return``;if(typeof n==`object`)throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${t}=${e?n:encodeURIComponent(n)}`},dt=({allowReserved:e,explode:t,name:n,style:r,value:i,valueOnly:a})=>{if(i instanceof Date)return a?i.toISOString():`${n}=${i.toISOString()}`;if(r!==`deepObject`&&!t){let t=[];Object.entries(i).forEach(([n,r])=>{t=[...t,n,e?r:encodeURIComponent(r)]});let a=t.join(`,`);switch(r){case`form`:return`${n}=${a}`;case`label`:return`.${a}`;case`matrix`:return`;${n}=${a}`;default:return a}}let o=ct(r),s=Object.entries(i).map(([t,i])=>ut({allowReserved:e,name:r===`deepObject`?`${n}[${t}]`:t,value:i})).join(o);return r===`label`||r===`matrix`?o+s:s},ft=/\{[^{}]+\}/g,pt=({path:e,url:t})=>{let n=t,r=t.match(ft);if(r)for(let t of r){let r=!1,i=t.substring(1,t.length-1),a=`simple`;i.endsWith(`*`)&&(r=!0,i=i.substring(0,i.length-1)),i.startsWith(`.`)?(i=i.substring(1),a=`label`):i.startsWith(`;`)&&(i=i.substring(1),a=`matrix`);let o=e[i];if(o==null)continue;if(Array.isArray(o)){n=n.replace(t,lt({explode:r,name:i,style:a,value:o}));continue}if(typeof o==`object`){n=n.replace(t,dt({explode:r,name:i,style:a,value:o,valueOnly:!0}));continue}if(a===`matrix`){n=n.replace(t,`;${ut({name:i,value:o})}`);continue}let s=encodeURIComponent(a===`label`?`.${o}`:o);n=n.replace(t,s)}return n},mt=({baseUrl:e,path:t,query:n,querySerializer:r,url:i})=>{let a=i.startsWith(`/`)?i:`/${i}`,o=(e??``)+a;t&&(o=pt({path:t,url:o}));let s=n?r(n):``;return s.startsWith(`?`)&&(s=s.substring(1)),s&&(o+=`?${s}`),o},ht=({allowReserved:e,array:t,object:n}={})=>r=>{let i=[];if(r&&typeof r==`object`)for(let a in r){let o=r[a];if(o!=null)if(Array.isArray(o)){let n=lt({allowReserved:e,explode:!0,name:a,style:`form`,value:o,...t});n&&i.push(n)}else if(typeof o==`object`){let t=dt({allowReserved:e,explode:!0,name:a,style:`deepObject`,value:o,...n});t&&i.push(t)}else{let t=ut({allowReserved:e,name:a,value:o});t&&i.push(t)}}return i.join(`&`)},gt=e=>{if(!e)return`stream`;let t=e.split(`;`)[0]?.trim();if(t){if(t.startsWith(`application/json`)||t.endsWith(`+json`))return`json`;if(t===`multipart/form-data`)return`formData`;if([`application/`,`audio/`,`image/`,`video/`].some(e=>t.startsWith(e)))return`blob`;if(t.startsWith(`text/`))return`text`}},_t=(e,t)=>t?!!(e.headers.has(t)||e.query?.[t]||e.headers.get(`Cookie`)?.includes(`${t}=`)):!1,vt=async({security:e,...t})=>{for(let n of e){if(_t(t,n.name))continue;let e=await it(n,t.auth);if(!e)continue;let r=n.name??`Authorization`;switch(n.in){case`query`:t.query||={},t.query[r]=e;break;case`cookie`:t.headers.append(`Cookie`,`${r}=${e}`);break;default:t.headers.set(r,e);break}}},yt=e=>mt({baseUrl:e.baseUrl,path:e.path,query:e.query,querySerializer:typeof e.querySerializer==`function`?e.querySerializer:ht(e.querySerializer),url:e.url}),bt=(e,t)=>{let n={...e,...t};return n.baseUrl?.endsWith(`/`)&&(n.baseUrl=n.baseUrl.substring(0,n.baseUrl.length-1)),n.headers=xt(e.headers,t.headers),n},xt=(...e)=>{let t=new Headers;for(let n of e){if(!n||typeof n!=`object`)continue;let e=n instanceof Headers?n.entries():Object.entries(n);for(let[n,r]of e)if(r===null)t.delete(n);else if(Array.isArray(r))for(let e of r)t.append(n,e);else r!==void 0&&t.set(n,typeof r==`object`?JSON.stringify(r):r)}return t};var St=class{_fns;constructor(){this._fns=[]}clear(){this._fns=[]}getInterceptorIndex(e){return typeof e==`number`?this._fns[e]?e:-1:this._fns.indexOf(e)}exists(e){let t=this.getInterceptorIndex(e);return!!this._fns[t]}eject(e){let t=this.getInterceptorIndex(e);this._fns[t]&&(this._fns[t]=null)}update(e,t){let n=this.getInterceptorIndex(e);return this._fns[n]?(this._fns[n]=t,e):!1}use(e){return this._fns=[...this._fns,e],this._fns.length-1}};const Ct=()=>({error:new St,request:new St,response:new St}),wt=ht({allowReserved:!1,array:{explode:!0,style:`form`},object:{explode:!0,style:`deepObject`}}),Tt={"Content-Type":`application/json`},Et=(e={})=>({...at,headers:Tt,parseAs:`auto`,querySerializer:wt,...e}),Dt=(e={})=>{let t=bt(Et(),e),n=()=>({...t}),r=e=>(t=bt(t,e),n()),i=Ct(),a=async e=>{let n={...t,...e,fetch:e.fetch??t.fetch??globalThis.fetch,headers:xt(t.headers,e.headers),serializedBody:void 0};return n.security&&await vt({...n,security:n.security}),n.requestValidator&&await n.requestValidator(n),n.body&&n.bodySerializer&&(n.serializedBody=n.bodySerializer(n.body)),(n.serializedBody===void 0||n.serializedBody===``)&&n.headers.delete(`Content-Type`),{opts:n,url:yt(n)}},o=async e=>{let{opts:t,url:n}=await a(e),r={redirect:`follow`,...t,body:t.serializedBody},o=new Request(n,r);for(let e of i.request._fns)e&&(o=await e(o,t));let s=t.fetch,c=await s(o);for(let e of i.response._fns)e&&(c=await e(c,o,t));let l={request:o,response:c};if(c.ok){if(c.status===204||c.headers.get(`Content-Length`)===`0`)return t.responseStyle===`data`?{}:{data:{},...l};let e=(t.parseAs===`auto`?gt(c.headers.get(`Content-Type`)):t.parseAs)??`json`,n;switch(e){case`arrayBuffer`:case`blob`:case`formData`:case`json`:case`text`:n=await c[e]();break;case`stream`:return t.responseStyle===`data`?c.body:{data:c.body,...l}}return e===`json`&&(t.responseValidator&&await t.responseValidator(n),t.responseTransformer&&(n=await t.responseTransformer(n))),t.responseStyle===`data`?n:{data:n,...l}}let u=await c.text(),d;try{d=JSON.parse(u)}catch{}let f=d??u,p=f;for(let e of i.error._fns)e&&(p=await e(f,c,o,t));if(p||={},t.throwOnError)throw p;return t.responseStyle===`data`?void 0:{error:p,...l}},s=e=>{let t=t=>o({...t,method:e});return t.sse=async t=>{let{opts:n,url:r}=await a(t);return rt({...n,body:n.body,headers:n.headers,method:e,url:r})},t};return{buildUrl:yt,connect:s(`CONNECT`),delete:s(`DELETE`),get:s(`GET`),getConfig:n,head:s(`HEAD`),interceptors:i,options:s(`OPTIONS`),patch:s(`PATCH`),post:s(`POST`),put:s(`PUT`),request:o,setConfig:r,trace:s(`TRACE`)}};Object.entries({$body_:`body`,$headers_:`headers`,$path_:`path`,$query_:`query`});const Ot=Dt(Et({baseUrl:`http://localhost:4096`}));var K=class{_client=Ot;constructor(e){e?.client&&(this._client=e.client)}},kt=class extends K{event(e){return(e?.client??this._client).get.sse({url:`/global/event`,...e})}},At=class extends K{list(e){return(e?.client??this._client).get({url:`/project`,...e})}current(e){return(e?.client??this._client).get({url:`/project/current`,...e})}},jt=class extends K{list(e){return(e?.client??this._client).get({url:`/pty`,...e})}create(e){return(e?.client??this._client).post({url:`/pty`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}remove(e){return(e.client??this._client).delete({url:`/pty/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/pty/{id}`,...e})}update(e){return(e.client??this._client).put({url:`/pty/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}connect(e){return(e.client??this._client).get({url:`/pty/{id}/connect`,...e})}},Mt=class extends K{get(e){return(e?.client??this._client).get({url:`/config`,...e})}update(e){return(e?.client??this._client).patch({url:`/config`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}providers(e){return(e?.client??this._client).get({url:`/config/providers`,...e})}},Nt=class extends K{ids(e){return(e?.client??this._client).get({url:`/experimental/tool/ids`,...e})}list(e){return(e.client??this._client).get({url:`/experimental/tool`,...e})}},Pt=class extends K{dispose(e){return(e?.client??this._client).post({url:`/instance/dispose`,...e})}},Ft=class extends K{get(e){return(e?.client??this._client).get({url:`/path`,...e})}},It=class extends K{get(e){return(e?.client??this._client).get({url:`/vcs`,...e})}},Lt=class extends K{list(e){return(e?.client??this._client).get({url:`/session`,...e})}create(e){return(e?.client??this._client).post({url:`/session`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}status(e){return(e?.client??this._client).get({url:`/session/status`,...e})}delete(e){return(e.client??this._client).delete({url:`/session/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/session/{id}`,...e})}update(e){return(e.client??this._client).patch({url:`/session/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}children(e){return(e.client??this._client).get({url:`/session/{id}/children`,...e})}todo(e){return(e.client??this._client).get({url:`/session/{id}/todo`,...e})}init(e){return(e.client??this._client).post({url:`/session/{id}/init`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}fork(e){return(e.client??this._client).post({url:`/session/{id}/fork`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}abort(e){return(e.client??this._client).post({url:`/session/{id}/abort`,...e})}unshare(e){return(e.client??this._client).delete({url:`/session/{id}/share`,...e})}share(e){return(e.client??this._client).post({url:`/session/{id}/share`,...e})}diff(e){return(e.client??this._client).get({url:`/session/{id}/diff`,...e})}summarize(e){return(e.client??this._client).post({url:`/session/{id}/summarize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}messages(e){return(e.client??this._client).get({url:`/session/{id}/message`,...e})}prompt(e){return(e.client??this._client).post({url:`/session/{id}/message`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}message(e){return(e.client??this._client).get({url:`/session/{id}/message/{messageID}`,...e})}promptAsync(e){return(e.client??this._client).post({url:`/session/{id}/prompt_async`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}command(e){return(e.client??this._client).post({url:`/session/{id}/command`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}shell(e){return(e.client??this._client).post({url:`/session/{id}/shell`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}revert(e){return(e.client??this._client).post({url:`/session/{id}/revert`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}unrevert(e){return(e.client??this._client).post({url:`/session/{id}/unrevert`,...e})}},Rt=class extends K{list(e){return(e?.client??this._client).get({url:`/command`,...e})}},zt=class extends K{authorize(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/authorize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}callback(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Bt=class extends K{list(e){return(e?.client??this._client).get({url:`/provider`,...e})}auth(e){return(e?.client??this._client).get({url:`/provider/auth`,...e})}oauth=new zt({client:this._client})},Vt=class extends K{text(e){return(e.client??this._client).get({url:`/find`,...e})}files(e){return(e.client??this._client).get({url:`/find/file`,...e})}symbols(e){return(e.client??this._client).get({url:`/find/symbol`,...e})}},Ht=class extends K{list(e){return(e.client??this._client).get({url:`/file`,...e})}read(e){return(e.client??this._client).get({url:`/file/content`,...e})}status(e){return(e?.client??this._client).get({url:`/file/status`,...e})}},Ut=class extends K{log(e){return(e?.client??this._client).post({url:`/log`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}agents(e){return(e?.client??this._client).get({url:`/agent`,...e})}},Wt=class extends K{remove(e){return(e.client??this._client).delete({url:`/mcp/{name}/auth`,...e})}start(e){return(e.client??this._client).post({url:`/mcp/{name}/auth`,...e})}callback(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}authenticate(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/authenticate`,...e})}set(e){return(e.client??this._client).put({url:`/auth/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Gt=class extends K{status(e){return(e?.client??this._client).get({url:`/mcp`,...e})}add(e){return(e?.client??this._client).post({url:`/mcp`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}connect(e){return(e.client??this._client).post({url:`/mcp/{name}/connect`,...e})}disconnect(e){return(e.client??this._client).post({url:`/mcp/{name}/disconnect`,...e})}auth=new Wt({client:this._client})},Kt=class extends K{status(e){return(e?.client??this._client).get({url:`/lsp`,...e})}},qt=class extends K{status(e){return(e?.client??this._client).get({url:`/formatter`,...e})}},Jt=class extends K{next(e){return(e?.client??this._client).get({url:`/tui/control/next`,...e})}response(e){return(e?.client??this._client).post({url:`/tui/control/response`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}},Yt=class extends K{appendPrompt(e){return(e?.client??this._client).post({url:`/tui/append-prompt`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}openHelp(e){return(e?.client??this._client).post({url:`/tui/open-help`,...e})}openSessions(e){return(e?.client??this._client).post({url:`/tui/open-sessions`,...e})}openThemes(e){return(e?.client??this._client).post({url:`/tui/open-themes`,...e})}openModels(e){return(e?.client??this._client).post({url:`/tui/open-models`,...e})}submitPrompt(e){return(e?.client??this._client).post({url:`/tui/submit-prompt`,...e})}clearPrompt(e){return(e?.client??this._client).post({url:`/tui/clear-prompt`,...e})}executeCommand(e){return(e?.client??this._client).post({url:`/tui/execute-command`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}showToast(e){return(e?.client??this._client).post({url:`/tui/show-toast`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}publish(e){return(e?.client??this._client).post({url:`/tui/publish`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}control=new Jt({client:this._client})},Xt=class extends K{subscribe(e){return(e?.client??this._client).get.sse({url:`/event`,...e})}},Zt=class extends K{postSessionIdPermissionsPermissionId(e){return(e.client??this._client).post({url:`/session/{id}/permissions/{permissionID}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}global=new kt({client:this._client});project=new At({client:this._client});pty=new jt({client:this._client});config=new Mt({client:this._client});tool=new Nt({client:this._client});instance=new Pt({client:this._client});path=new Ft({client:this._client});vcs=new It({client:this._client});session=new Lt({client:this._client});command=new Rt({client:this._client});provider=new Bt({client:this._client});find=new Vt({client:this._client});file=new Ht({client:this._client});app=new Ut({client:this._client});mcp=new Gt({client:this._client});lsp=new Kt({client:this._client});formatter=new qt({client:this._client});tui=new Yt({client:this._client});auth=new Wt({client:this._client});event=new Xt({client:this._client})};function Qt(e){if(!e?.fetch){let t=e=>(e.timeout=!1,fetch(e));e={...e,fetch:t}}return e?.directory&&(e.headers={...e.headers,"x-opencode-directory":encodeURIComponent(e.directory)}),new Zt({client:Dt(e)})}async function $t(e){e=Object.assign({hostname:`127.0.0.1`,port:4096,timeout:5e3},e??{});let t=[`serve`,`--hostname=${e.hostname}`,`--port=${e.port}`];e.config?.logLevel&&t.push(`--log-level=${e.config.logLevel}`);let n=Te(`opencode`,t,{signal:e.signal,env:{...process.env,OPENCODE_CONFIG_CONTENT:JSON.stringify(e.config??{})}});return{url:await new Promise((t,r)=>{let i=setTimeout(()=>{r(Error(`Timeout waiting for server to start after ${e.timeout}ms`))},e.timeout),a=``;n.stdout?.on(`data`,e=>{a+=e.toString();let n=a.split(` +`);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function en(e){let t=await $t({...e});return{client:Qt({baseUrl:t.url}),server:t}}async function tn(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const nn={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},rn=`\x1B[0m`;function an(){return V.env.NO_COLOR==null}function on(e,t){let[n,r]=nn[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);an()?V.stdout.write(`\n${r}|${rn} ${i} ${rn}${t}\n`):V.stdout.write(`\n| ${i} ${t}\n`)}function sn(e){V.stdout.write(`\n${e}\n`)}const cn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function ln(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function un(e){let t=ln(e),n=cn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` +`)}function dn(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const fn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function pn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return fn.some(e=>e.test(t))}function mn(e,t){return dn(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function hn(e,t){return dn(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}function gn(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function _n(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 vn(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(gn)}function yn(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)]}var bn=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(_e(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(ve(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${he}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},xn=T((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),Sn=e(T((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[d.Accept]=this._getExistingOrDefaultHeader(t,d.Accept,f.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===u.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&m.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!h.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},x(this.requestOptions.headers),x(e||{})):x(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[d.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[d.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new l.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===u.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let x=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),Cn=w(),wn=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function Tn(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function En(e){return new Sn.HttpClient().getAgent(e)}function Dn(e){return new Sn.HttpClient().getAgentDispatcher(e)}function On(e){let t=Dn(e);return(e,n)=>wn(this,void 0,void 0,function*(){return(0,Cn.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function kn(){return process.env.GITHUB_API_URL||`https://api.github.com`}function An(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function jn(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>jn.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function Mn(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function Nn(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const Pn=Function.bind,Fn=Pn.bind(Pn);function In(e,t,n){let r=Fn(Nn,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=Fn(Mn,null).apply(null,i)})}function Ln(){let e=Symbol(`Singular`),t={registry:{}},n=jn.bind(null,t,e);return In(n,t,e),n}function Rn(){let e={registry:{}},t=jn.bind(null,e);return In(t,e),t}var zn={Singular:Ln,Collection:Rn},Bn=`octokit-endpoint.js/0.0.0-development ${An()}`,Vn={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":Bn},mediaType:{format:``}};function Hn(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Un(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Wn(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Un(t[r])&&r in e?n[r]=Wn(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Gn(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function Kn(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Hn(n.headers),Gn(n),Gn(n.headers);let r=Wn(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function qn(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var Jn=/\{[^{}}]+\}/g;function Yn(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Zn(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function Qn(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function q(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function $n(e,t,n){return t=e===`+`||e===`#`?Qn(t):q(t),n?q(n)+`=`+t:t}function er(e){return e!=null}function tr(e){return e===`;`||e===`&`||e===`?`}function nr(e,t,n,r){var i=e[n],a=[];if(er(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push($n(t,i,tr(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(er).forEach(function(e){a.push($n(t,e,tr(t)?n:``))}):Object.keys(i).forEach(function(e){er(i[e])&&a.push($n(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(er).forEach(function(n){e.push($n(t,n))}):Object.keys(i).forEach(function(n){er(i[n])&&(e.push(q(n)),e.push($n(t,i[n].toString())))}),tr(t)?a.push(q(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?er(i)&&a.push(q(n)):i===``&&(t===`&`||t===`?`)?a.push(q(n)+`=`):i===``&&a.push(``);return a}function rr(e){return{expand:ir.bind(null,e)}}function ir(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(nr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return Qn(i)}),e===`/`?e:e.replace(/\/$/,``)}function ar(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Zn(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Xn(n);n=rr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Zn(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=qn(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function or(e,t,n){return ar(Kn(e,t,n))}function sr(e,t){let n=Kn(e,t),r=or.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:sr.bind(null,n),merge:Kn.bind(null,n),parse:ar})}var cr=sr(null,Vn),lr=T(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))(),ur=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function hr(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=pr(e.body)||Array.isArray(e.body)?JSON.stringify(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new ur(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new ur(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await gr(o),new ur(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await gr(o),new ur(vr(u.data),s,{response:u,request:e});return u.data=r?await gr(o):o.body,u}async function gr(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(mr);let n=(0,lr.safeParse)(t);if(_r(n)){let t=``;try{return t=await e.text(),JSON.parse(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(mr);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function _r(e){return e.type===`application/json`||e.type===`application/scim+json`}function vr(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function yr(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return hr(n.parse(r));let i=(e,t)=>hr(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:yr.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:yr.bind(null,n)})}var br=yr(cr,fr),xr=`0.0.0-development`;function Sr(e){return`Request failed due to following response errors: `+e.errors.map(e=>` - ${e.message}`).join(` -`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${jn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${jn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Bn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new xn;const ii=An(),ai={baseUrl:ii,request:{agent:Dn(ii),fetch:kn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=En(e,n);return r&&(n.auth=r),n}const ci=new xn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(re(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=H.join(ki(),_e.randomUUID()),yield S(H.dirname(t)),M(`Downloading ${e}`),M(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(V.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(M(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw M(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=xe.promisify(Ae.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,V.createWriteStream(t)),M(`download complete`),l=!0,t}finally{if(!l){M(`download failed`);try{yield s(t)}catch(e){M(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),M(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),M(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`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(` `)];M(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);M(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=he.arch(),M(`Caching tool ${t} ${n} ${r}`),M(`source dir: ${e}`),!V.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of V.readdirSync(e))yield b(H.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=he.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=H.join(Oi(),e,t,n);M(`checking cache: ${i}`),V.existsSync(i)&&V.existsSync(`${i}.complete`)?(M(`Found tool in cache ${e} ${t} ${n}`),r=i):M(`not found`)}return r}function Si(e,t){let n=[];t||=he.arch();let r=H.join(Oi(),e);if(V.existsSync(r)){let e=V.readdirSync(r);for(let i of e)if(Ei(i)){let e=H.join(r,i,t||``);V.existsSync(e)&&V.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=H.join(ki(),_e.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=H.join(Oi(),e,Y.clean(t)||t,n||``);M(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${H.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;V.writeFileSync(r,``),M(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;M(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return M(`explicit? ${n}`),n}function Di(e,t){let n=``;M(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return M(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return be(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return be(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=R.join(t,`auth.json`);await U.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await U.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=B.platform,t=B.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(B.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=me.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=N(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Te.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=me.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>B.platform===`win32`?`${e}.exe`:e,n=me.join(e,t(`bun`));try{await Te.symlink(n,me.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};B.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`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 Qe(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 Gi(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`}=n;r.info(`Installing Oh My OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u});let d=``,f=[`oh-my-opencode@${e}`,`install`,`--no-tui`,`--claude=${a}`,`--copilot=${o}`,`--gemini=${s}`,`--openai=${c}`,`--opencode-zen=${l}`,`--zai-coding-plan=${u}`];try{let t=await i.exec(`bunx`,f,{listeners:{stdout:e=>{d+=e.toString()},stderr:e=>{d+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-opencode install returned exit code ${t}`;return r.error(e,{output:d.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${d.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(d),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=N(e),n=d.length>0?`${t}\nOutput: ${d.slice(0,500)}`:t;return r.error(`Failed to run oMo installer`,{error:t,output:d.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-opencode install failed: ${n}`}}}const Ki=`opencode`,qi=`1.2.9`;function Ji(){let e=Oe.platform(),t=Oe.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 Yi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Xi(e,t,n,r){if(B.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 Zi(e,t,n,r,i=qi){let a=Ji(),o=n.find(Ki,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 Qi(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:N(n)})}if(e!==i)try{let e=await Qi(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}): ${N(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Qi(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=Yi(e,t),o=await r.downloadTool(a);if(!await Xi(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,Ki,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function $i(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ea={restoreCache:async(e,t,n)=>ce(e,t,n),saveCache:async(e,t)=>D(e,t)};function ta(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ue}-${t}-oc-${n}-omo-${r}`}function na(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ue}-${t}-oc-${n}-omo-${r}-`]}async function ra(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=na({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:N(e)}),{hit:!1,restoredKey:null}}}async function ia(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:N(e)}),!1)}}const aa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function oa(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`;for(let e of t)if(aa.includes(e))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}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function sa(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ca(){return{exec:x,getExecOutput:c}}function la(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null}}async function ua(){let e=Date.now(),n=j({component:`setup`}),r=sa(),o=ca();try{let s=la(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${N(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await $i(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:N(e)}),u=qi}let d=m(`omo-version`).trim(),f=d.length>0?d:P,h=B.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=z(h,`opencode`),v=z(h,`bun`),y=z(ke(),`.config`,`opencode`),b=a(),x=await ra({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await Zi(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${N(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:N(e)})}if(E){let e=m(`omo-providers`).trim(),t=oa(e.length>0?e:oe),r=await Gi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}x.hit||await ia({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),L(`opencode-path`,C.path),L(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let te=li(c),D=await Hi(te,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(te,D.botLogin,n,o);let O=z(i(),`opencode`),k=await Mi(l,O,n);L(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=B.env.GITHUB_REPOSITORY??`unknown/unknown`,j=B.env.GITHUB_REF_NAME??`main`,M=a(),re=ee({agentIdentity:`github`,repo:A,ref:j,os:M}),ie=ae({agentIdentity:`github`,repo:A,ref:j,os:M}),F=`miss`;try{let e=await ce([O],re,[...ie]);e==null?n.info(`No cache found`):(F=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){F=`corrupted`,n.warning(`Cache restore failed`,{error:N(e)})}L(`cache-status`,F),L(`storage-path`,O);let se=Date.now()-e,I={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:D.authenticated,omoInstalled:w,omoError:T,cacheStatus:F,toolsCacheStatus:S,duration:se};return n.info(`Setup complete`,{duration:se}),I}catch(e){let t=N(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function da(e){return{success:!0,data:e}}function fa(e){return{success:!1,error:e}}const pa=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ma(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` +`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${An()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${An()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new zn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new bn;const ii=kn(),ai={baseUrl:ii,request:{agent:En(ii),fetch:On(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=Tn(e,n);return r&&(n.auth=r),n}const ci=new bn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(ie(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=U.join(ki(),ge.randomUUID()),yield S(U.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(H.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=be.promisify(ke.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,H.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=me.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!H.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of H.readdirSync(e))yield b(U.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=me.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=U.join(Oi(),e,t,n);j(`checking cache: ${i}`),H.existsSync(i)&&H.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=me.arch();let r=U.join(Oi(),e);if(H.existsSync(r)){let e=H.readdirSync(r);for(let i of e)if(Ei(i)){let e=U.join(r,i,t||``);H.existsSync(e)&&H.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=U.join(ki(),ge.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=U.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${U.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;H.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ye(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ye(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=z.join(t,`auth.json`);await W.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await W.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=V.platform,t=V.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(V.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=pe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await we.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=pe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>V.platform===`win32`?`${e}.exe`:e,n=pe.join(e,t(`bun`));try{await we.symlink(n,pe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};V.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`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 Ze(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 Gi(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`}=n;r.info(`Installing Oh My OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u});let d=``,f=[`oh-my-opencode@${e}`,`install`,`--no-tui`,`--claude=${a}`,`--copilot=${o}`,`--gemini=${s}`,`--openai=${c}`,`--opencode-zen=${l}`,`--zai-coding-plan=${u}`];try{let t=await i.exec(`bunx`,f,{listeners:{stdout:e=>{d+=e.toString()},stderr:e=>{d+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-opencode install returned exit code ${t}`;return r.error(e,{output:d.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${d.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(d),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=M(e),n=d.length>0?`${t}\nOutput: ${d.slice(0,500)}`:t;return r.error(`Failed to run oMo installer`,{error:t,output:d.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-opencode install failed: ${n}`}}}const Ki=`opencode`,qi=`1.2.9`;function Ji(){let e=De.platform(),t=De.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 Yi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Xi(e,t,n,r){if(V.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 Zi(e,t,n,r,i=qi){let a=Ji(),o=n.find(Ki,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 Qi(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(n)})}if(e!==i)try{let e=await Qi(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}): ${M(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Qi(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=Yi(e,t),o=await r.downloadTool(a);if(!await Xi(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,Ki,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function $i(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ea={restoreCache:async(e,t,n)=>ce(e,t,n),saveCache:async(e,t)=>D(e,t)};function ta(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${le}-${t}-oc-${n}-omo-${r}`}function na(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${le}-${t}-oc-${n}-omo-${r}-`]}async function ra(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=na({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function ia(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const aa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function oa(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`;for(let e of t)if(aa.includes(e))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}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function sa(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ca(){return{exec:x,getExecOutput:c}}function la(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null}}async function ua(){let e=Date.now(),n=A({component:`setup`}),r=sa(),o=ca();try{let s=la(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await $i(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=qi}let d=m(`omo-version`).trim(),f=d.length>0?d:N,h=V.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=B(h,`opencode`),v=B(h,`bun`),y=B(Oe(),`.config`,`opencode`),b=a(),x=await ra({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await Zi(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){let e=m(`omo-providers`).trim(),t=oa(e.length>0?e:se),r=await Gi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1,...s.opencodeConfig==null?{}:JSON.parse(s.opencodeConfig)};p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await ia({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),R(`opencode-path`,C.path),R(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=B(i(),`opencode`),k=await Mi(l,O,n);R(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=V.env.GITHUB_REPOSITORY??`unknown/unknown`,j=V.env.GITHUB_REF_NAME??`main`,ie=a(),ae=ee({agentIdentity:`github`,repo:A,ref:j,os:ie}),P=oe({agentIdentity:`github`,repo:A,ref:j,os:ie}),F=`miss`;try{let e=await ce([O],ae,[...P]);e==null?n.info(`No cache found`):(F=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){F=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}R(`cache-status`,F),R(`storage-path`,O);let I=Date.now()-e,L={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:F,toolsCacheStatus:S,duration:I};return n.info(`Setup complete`,{duration:I}),L}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function da(e){return{success:!0,data:e}}function fa(e){return{success:!1,error:e}}const pa=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ma(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` `),appendMode:!0};case`pull_request_review_comment`:return{directive:ha(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function ha(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` `)}function ga(e,t){let{directive:n,appendMode:r}=ma(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` `)}function _a(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a}=e,o=[];if(o.push(`# Agent Context @@ -167,7 +167,7 @@ Respond to the trigger comment above. Follow all instructions and requirements l \`\`\` ${n.commentBody} \`\`\` -`),a!=null&&o.push(ya(a)),n.diffContext!=null&&o.push(ba(n.diffContext)),n.hydratedContext!=null&&o.push(Re(n.hydratedContext)),o.push(`## Session Management (REQUIRED) +`),a!=null&&o.push(ya(a)),n.diffContext!=null&&o.push(ba(n.diffContext)),n.hydratedContext!=null&&o.push(Le(n.hydratedContext)),o.push(`## Session Management (REQUIRED) Before investigating any issue: 1. Use \`session_search\` to find relevant prior sessions for this repository @@ -254,9 +254,9 @@ Every response you post — regardless of channel (issue, PR, discussion, review `}function ya(e){let t=[`## Prior Session Context`];if(e.recentSessions.length>0){t.push(``),t.push(`### Recent Sessions`),t.push(`| ID | Title | Updated | Messages | Agents |`),t.push(`|----|-------|---------|----------|--------|`);for(let n of e.recentSessions.slice(0,5)){let e=new Date(n.updatedAt).toISOString().split(`T`)[0],r=n.agents.join(`, `)||`N/A`,i=n.title||`Untitled`;t.push(`| ${n.id} | ${i} | ${e} | ${n.messageCount} | ${r} |`)}t.push(``),t.push("Use `session_read` to review any of these sessions in detail.")}if(e.priorWorkContext.length>0){t.push(``),t.push(`### Relevant Prior Work`),t.push(``),t.push(`The following sessions contain content related to this issue:`),t.push(``);for(let n of e.priorWorkContext.slice(0,3)){t.push(`**Session ${n.sessionId}:**`),t.push("```markdown");for(let e of n.matches.slice(0,2))t.push(`- ${e.excerpt}`);t.push("```"),t.push(``)}t.push("Use `session_read` to review full context before starting new investigation.")}return t.push(``),t.join(` `)}function ba(e){let t=[`## Pull Request Diff Summary`];if(t.push(``),t.push(`- **Changed Files:** ${e.changedFiles}`),t.push(`- **Additions:** +${e.additions}`),t.push(`- **Deletions:** -${e.deletions}`),e.truncated&&t.push(`- **Note:** Diff was truncated due to size limits`),e.files.length>0){t.push(``),t.push(`### Changed Files`),t.push(`| File | Status | +/- |`),t.push(`|------|--------|-----|`);for(let n of e.files.slice(0,20))t.push(`| \`${n.filename}\` | ${n.status} | +${n.additions}/-${n.deletions} |`);e.files.length>20&&t.push(`| ... | | +${e.files.length-20} more files |`)}return t.push(``),t.join(` `)}function xa(e){let t=[`## Output Contract`,``];return t.push(`- Review action: approve/request-changes if confident; otherwise comment-only`),t.push(`- Requested reviewer: ${e.isRequestedReviewer?`yes`:`no`}`),e.authorAssociation!=null&&t.push(`- Author association: ${e.authorAssociation}`),t.push(``),t.join(` -`)}function Sa(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function Ca(e,t,n,r,i){let a=yn(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=bn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function wa(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(Sa(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(cn(a),a=``)}else if(e.type===`tool`){let t=e.state;if(t.status===`completed`){let n=e.tool,r=t.input,i=t.title;sn(n,i),n.toLowerCase()===`bash`&&Ca(String(r.command??r.cmd??``),String(t.output),l,u,()=>{d++})}}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error;r.error(`Session error`,{error:e});let t=typeof e==`string`?e:String(e);f=mn(e)?hn(t,s??void 0):gn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(cn(a),a=``))}return a.length>0&&cn(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}async function Ta(e,t,n,r,i,a=E,o){let s=Date.now(),c=0;for(;!r.aborted;){if(await nn(500),r.aborted)return{completed:!1,error:`Aborted`};if(o?.sessionError==null)c=0;else{if(c++,c>=3)return i.error(`Session error persisted through grace period`,{sessionId:t,error:o.sessionError,graceCycles:c}),{completed:!1,error:`Session error: ${o.sessionError}`};continue}if(o?.sessionIdle===!0)return i.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let l=Date.now()-s;if(a>0&&l>=a)return i.warning(`Poll timeout reached`,{elapsedMs:l,maxPollTimeMs:a}),{completed:!1,error:`Poll timeout after ${l}ms`};try{let r=((await e.session.status({query:{directory:n}})).data??{})[t];if(r==null)i.debug(`Session status not found in poll response`,{sessionId:t});else if(r.type===`idle`)return i.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else i.debug(`Session status`,{sessionId:t,type:r.type});if(o!=null&&!o.firstMeaningfulEventReceived){let e=Date.now()-s;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:N(e)})}}return{completed:!1,error:`Aborted`}}async function Ea(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}const Da=5e3;function Oa(e){return e==null?!1:Object.values(e.omoProviders).some(e=>e!==`no`)}function ka(e){if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!Oa(e))return{providerID:O.providerID,modelID:O.modelID}}async function Aa(e,t,n,r,i,a,o){let s=a?.agent??le,c=new AbortController,l={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},u=await e.event.subscribe(),d={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},f=wa(u.stream,t,c.signal,o,l).then(e=>{d=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&o.debug(`Event stream error`,{error:e.message})}),p=async()=>{c.abort(),await Ea(f)},m=[{type:`text`,text:n}];r!=null&&r.length>0&&(m.push(...r),o.info(`Including file attachments in prompt`,{count:r.length}));let h=ka(a),g={parts:m};h!=null&&(g.model=h),s!==le&&(g.agent=s),o.debug(`Sending prompt to OpenCode`,{sessionId:t});try{let n=await e.session.promptAsync({path:{id:t},body:g,query:{directory:i}});if(n.error!=null){o.error(`OpenCode prompt failed`,{error:String(n.error)}),await p();let e=mn(n.error)?hn(String(n.error),d.model??void 0):d.llmError;return{success:!1,error:String(n.error),llmError:e,shouldRetry:e!=null,eventStreamResult:d}}let r=a?.timeoutMs??E,s=await Ta(e,t,i,c.signal,o,r,l);if(await p(),!s.completed){let e=s.error??`Session did not reach idle state`;return o.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:d.llmError,shouldRetry:d.llmError!=null,eventStreamResult:d}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:d}}finally{c.abort(),await Ea(f)}}async function ja(e,t){try{let{client:n,server:r}=await tn({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),da({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),fa(Error(`Server bootstrap failed: ${n}`))}}async function Ma(e,t,n,r){let i=Date.now(),a=new AbortController,o=n?.timeoutMs??E,s=null,c=!1,l=r==null,u=null;o>0&&(s=setTimeout(()=>{c=!0,t.warning(`Execution timeout reached`,{timeoutMs:o}),a.abort()},o)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??le,hasModelOverride:n?.model!=null,timeoutMs:o});try{let s;if(r==null){let e=await tn({signal:a.signal});s=e.client,u=e.server,t.debug(`OpenCode server started`,{url:u.url})}else s=r.client,t.debug(`Reusing external OpenCode server`,{url:r.server.url});let l=await s.session.create();if(l.data==null||l.error!=null){let e=l.error==null?`No data returned`:String(l.error);throw Error(`Failed to create session: ${e}`)}let d=l.data.id;t.debug(`Session created`,{sessionId:d});let f=_a({...e,sessionId:d},t),p=v();if(h()){let e=de(),n=Ce.createHash(`sha256`).update(f).digest(`hex`),r=R.join(e,`prompt-${d}-${n.slice(0,8)}.txt`);try{await U.mkdir(e,{recursive:!0}),await U.writeFile(r,f,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let m=null,g=null,_=null,y=[],b=[],x=0,S=null,C=null;for(let r=1;r<=3;r++){if(c)return{success:!1,exitCode:130,duration:Date.now()-i,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C};let a=o-(Date.now()-i);if(o>0&&a<=Da&&r>1){t.warning(`Insufficient time remaining for retry`,{remainingMs:a,requiredMs:Da,attempt:r});break}let l=r===1?f:`The previous request was interrupted by a network error (fetch failed). +`)}function Sa(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function Ca(e,t,n,r,i){let a=vn(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=yn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function wa(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(Sa(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(sn(a),a=``)}else if(e.type===`tool`){let t=e.state;if(t.status===`completed`){let n=e.tool,r=t.input,i=t.title;on(n,i),n.toLowerCase()===`bash`&&Ca(String(r.command??r.cmd??``),String(t.output),l,u,()=>{d++})}}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error;r.error(`Session error`,{error:e});let t=typeof e==`string`?e:String(e);f=pn(e)?mn(t,s??void 0):hn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(sn(a),a=``))}return a.length>0&&sn(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}async function Ta(e,t,n,r,i,a=E,o){let s=Date.now(),c=0;for(;!r.aborted;){if(await tn(500),r.aborted)return{completed:!1,error:`Aborted`};if(o?.sessionError==null)c=0;else{if(c++,c>=3)return i.error(`Session error persisted through grace period`,{sessionId:t,error:o.sessionError,graceCycles:c}),{completed:!1,error:`Session error: ${o.sessionError}`};continue}if(o?.sessionIdle===!0)return i.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let l=Date.now()-s;if(a>0&&l>=a)return i.warning(`Poll timeout reached`,{elapsedMs:l,maxPollTimeMs:a}),{completed:!1,error:`Poll timeout after ${l}ms`};try{let r=((await e.session.status({query:{directory:n}})).data??{})[t];if(r==null)i.debug(`Session status not found in poll response`,{sessionId:t});else if(r.type===`idle`)return i.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else i.debug(`Session status`,{sessionId:t,type:r.type});if(o!=null&&!o.firstMeaningfulEventReceived){let e=Date.now()-s;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:M(e)})}}return{completed:!1,error:`Aborted`}}async function Ea(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}const Da=5e3;function Oa(e){return e==null?!1:Object.values(e.omoProviders).some(e=>e!==`no`)}function ka(e){if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!Oa(e))return{providerID:re.providerID,modelID:re.modelID}}async function Aa(e,t,n,r,i,a,o){let s=a?.agent??L,c=new AbortController,l={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},u=await e.event.subscribe(),d={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},f=wa(u.stream,t,c.signal,o,l).then(e=>{d=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&o.debug(`Event stream error`,{error:e.message})}),p=async()=>{c.abort(),await Ea(f)},m=[{type:`text`,text:n}];r!=null&&r.length>0&&(m.push(...r),o.info(`Including file attachments in prompt`,{count:r.length}));let h=ka(a),g={parts:m};h!=null&&(g.model=h),s!==L&&(g.agent=s),o.debug(`Sending prompt to OpenCode`,{sessionId:t});try{let n=await e.session.promptAsync({path:{id:t},body:g,query:{directory:i}});if(n.error!=null){o.error(`OpenCode prompt failed`,{error:String(n.error)}),await p();let e=pn(n.error)?mn(String(n.error),d.model??void 0):d.llmError;return{success:!1,error:String(n.error),llmError:e,shouldRetry:e!=null,eventStreamResult:d}}let r=a?.timeoutMs??E,s=await Ta(e,t,i,c.signal,o,r,l);if(await p(),!s.completed){let e=s.error??`Session did not reach idle state`;return o.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:d.llmError,shouldRetry:d.llmError!=null,eventStreamResult:d}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:d}}finally{c.abort(),await Ea(f)}}async function ja(e,t){try{let{client:n,server:r}=await en({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),da({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),fa(Error(`Server bootstrap failed: ${n}`))}}async function Ma(e,t,n,r){let i=Date.now(),a=new AbortController,o=n?.timeoutMs??E,s=null,c=!1,l=r==null,u=null;o>0&&(s=setTimeout(()=>{c=!0,t.warning(`Execution timeout reached`,{timeoutMs:o}),a.abort()},o)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??L,hasModelOverride:n?.model!=null,timeoutMs:o});try{let s;if(r==null){let e=await en({signal:a.signal});s=e.client,u=e.server,t.debug(`OpenCode server started`,{url:u.url})}else s=r.client,t.debug(`Reusing external OpenCode server`,{url:r.server.url});let l=await s.session.create();if(l.data==null||l.error!=null){let e=l.error==null?`No data returned`:String(l.error);throw Error(`Failed to create session: ${e}`)}let d=l.data.id;t.debug(`Session created`,{sessionId:d});let f=_a({...e,sessionId:d},t),p=v();if(h()){let e=ue(),n=Se.createHash(`sha256`).update(f).digest(`hex`),r=z.join(e,`prompt-${d}-${n.slice(0,8)}.txt`);try{await W.mkdir(e,{recursive:!0}),await W.writeFile(r,f,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let m=null,g=null,_=null,y=[],b=[],x=0,S=null,C=null;for(let r=1;r<=3;r++){if(c)return{success:!1,exitCode:130,duration:Date.now()-i,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C};let a=o-(Date.now()-i);if(o>0&&a<=Da&&r>1){t.warning(`Insufficient time remaining for retry`,{remainingMs:a,requiredMs:Da,attempt:r});break}let l=r===1?f:`The previous request was interrupted by a network error (fetch failed). Please continue where you left off. If you were in the middle of a task, resume it. -If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void 0;t.debug(`Sending prompt`,{attempt:r,isRetry:r>1});try{let e=await Aa(s,d,l,u,p,n,t);if(e.success){let{eventStreamResult:n}=e;m=n.tokens,g=n.model,_=n.cost,y=[...n.prsCreated],b=[...n.commitsCreated],x=n.commentsPosted;let a=Date.now()-i;return t.info(`OpenCode execution completed`,{sessionId:d,durationMs:a,attempts:r}),{success:!0,exitCode:0,duration:a,sessionId:d,error:null,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:null}}if(S=e.error,C=e.llmError,!e.shouldRetry||r>=3){e.shouldRetry&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:e.error});break}t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:e.error,delayMs:Da,sessionId:d}),await nn(Da)}catch(e){let n=N(e);t.error(`Prompt attempt failed with exception`,{attempt:r,error:n}),S=n;let i=mn(e)?hn(n):null;if(C=i,i==null||r>=3){i!=null&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:n});break}t.warning(`LLM fetch error detected (exception), retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:n,delayMs:Da,sessionId:d}),await nn(Da)}}return{success:!1,exitCode:1,duration:Date.now()-i,sessionId:d,error:S??`Unknown error`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C}}catch(e){let n=Date.now()-i,r=N(e);return t.error(`OpenCode execution failed`,{error:r,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:mn(e)?hn(r):null}}finally{s!=null&&clearTimeout(s),a.abort(),l&&u?.close()}}async function Na(e,t){let n=e??`opencode`;try{let e=``;await x(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function Pa(e){let{logger:n,opencodeVersion:r}=e,i=B.env.OPENCODE_PATH??null,a=await Na(i,n);if(a.available&&a.version!=null)return n.info(`OpenCode already available`,{version:a.version}),{path:i??`opencode`,version:a.version,didSetup:!1};n.info(`OpenCode not found, running auto-setup`,{requestedVersion:r});let o=await ua();if(o==null)throw Error(`Auto-setup failed: runSetup returned null`);return t(o.opencodePath),B.env.OPENCODE_PATH=o.opencodePath,n.info(`Auto-setup completed`,{version:o.opencodeVersion,path:o.opencodePath}),{path:o.opencodePath,version:o.opencodeVersion,didSetup:!0}}const Fa=`agent: working`;async function Ia(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await Ge(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function La(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await Je(e,t.repo,Fa,`fcf2e1`,`Agent is currently working on this`,n)&&await Ye(e,t.repo,t.issueNumber,[Fa],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function Ra(e,t,n){await Promise.all([Ia(e,t,n),La(e,t,n)])}async function za(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await Ke(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await qe(e,t.repo,t.commentId,r.id,n)}async function Ba(e,t,n,r){t.commentId!=null&&await Ge(e,t.repo,t.commentId,n,r)}async function Va(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:N(e)})}}async function Ha(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:N(e)})}}async function Ua(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Xe(e,t.repo,t.issueNumber,Fa,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function Wa(e,t,n,r){n?await Va(e,t,r):await Ha(e,t,r),await Ua(e,t,r)}const Ga={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 Ka(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function qa(e){let t=[],n=new Set;return Ka(Ga.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&vn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Ka(Ga.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&vn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Ka(Ga.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&vn(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),Ga.htmlImage.lastIndex=0,t}function Ja(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 Ya={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`]},Xa=[`github.com`,`githubusercontent.com`];async function Za(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(!Xa.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=Se.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=Ja(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await U.mkdtemp(R.join(De.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=R.join(p,m);return await U.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:N(t)}),null}}async function Qa(e,t,n=Ya,r){return Promise.all(e.map(async(e,i)=>Za(e,i,t,n,r)))}async function $a(e,t){for(let n of e)try{await U.unlink(n);let e=R.dirname(n);await U.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:N(e)})}}function eo(e){return e.map(e=>({type:`file`,mime:e.mime,url:we(e.tempPath).toString(),filename:e.filename}))}function to(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 no(e,t,n,r){return{processed:n,skipped:r,modifiedBody:to(e,t,n),fileParts:eo(n),tempFiles:n.map(e=>e.tempPath)}}function ro(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function io(e,t=Ya,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 (${ro(o.sizeBytes)} > ${ro(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 (${ro(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!ao(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 ao(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}const oo=``;function so(e,t){return t==null?!1:e===t||e===`${t}[bot]`}function co(e,t,n){return so(e,n)&&t.includes(oo)}async function lo(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:N(e)}),null}}async function uo(e,t,n,r){let i=[],a=1;for(;a<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:a});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;i.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:co(t,e.body??``,n)})}if(r.length<100)break;a++}catch(e){r.warning(`Failed to fetch comments page`,{target:t,page:a,error:N(e)});break}return i}async function fo(e,t,n,r){try{let i=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` +If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void 0;t.debug(`Sending prompt`,{attempt:r,isRetry:r>1});try{let e=await Aa(s,d,l,u,p,n,t);if(e.success){let{eventStreamResult:n}=e;m=n.tokens,g=n.model,_=n.cost,y=[...n.prsCreated],b=[...n.commitsCreated],x=n.commentsPosted;let a=Date.now()-i;return t.info(`OpenCode execution completed`,{sessionId:d,durationMs:a,attempts:r}),{success:!0,exitCode:0,duration:a,sessionId:d,error:null,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:null}}if(S=e.error,C=e.llmError,!e.shouldRetry||r>=3){e.shouldRetry&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:e.error});break}t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:e.error,delayMs:Da,sessionId:d}),await tn(Da)}catch(e){let n=M(e);t.error(`Prompt attempt failed with exception`,{attempt:r,error:n}),S=n;let i=pn(e)?mn(n):null;if(C=i,i==null||r>=3){i!=null&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:n});break}t.warning(`LLM fetch error detected (exception), retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:n,delayMs:Da,sessionId:d}),await tn(Da)}}return{success:!1,exitCode:1,duration:Date.now()-i,sessionId:d,error:S??`Unknown error`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C}}catch(e){let n=Date.now()-i,r=M(e);return t.error(`OpenCode execution failed`,{error:r,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:pn(e)?mn(r):null}}finally{s!=null&&clearTimeout(s),a.abort(),l&&u?.close()}}async function Na(e,t){let n=e??`opencode`;try{let e=``;await x(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function Pa(e){let{logger:n,opencodeVersion:r}=e,i=V.env.OPENCODE_PATH??null,a=await Na(i,n);if(a.available&&a.version!=null)return n.info(`OpenCode already available`,{version:a.version}),{path:i??`opencode`,version:a.version,didSetup:!1};n.info(`OpenCode not found, running auto-setup`,{requestedVersion:r});let o=await ua();if(o==null)throw Error(`Auto-setup failed: runSetup returned null`);return t(o.opencodePath),V.env.OPENCODE_PATH=o.opencodePath,n.info(`Auto-setup completed`,{version:o.opencodeVersion,path:o.opencodePath}),{path:o.opencodePath,version:o.opencodeVersion,didSetup:!0}}const Fa=`agent: working`;async function Ia(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await We(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function La(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await qe(e,t.repo,Fa,`fcf2e1`,`Agent is currently working on this`,n)&&await Je(e,t.repo,t.issueNumber,[Fa],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function Ra(e,t,n){await Promise.all([Ia(e,t,n),La(e,t,n)])}async function za(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await Ge(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Ke(e,t.repo,t.commentId,r.id,n)}async function Ba(e,t,n,r){t.commentId!=null&&await We(e,t.repo,t.commentId,n,r)}async function Va(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:M(e)})}}async function Ha(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:M(e)})}}async function Ua(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Ye(e,t.repo,t.issueNumber,Fa,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function Wa(e,t,n,r){n?await Va(e,t,r):await Ha(e,t,r),await Ua(e,t,r)}const Ga={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 Ka(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function qa(e){let t=[],n=new Set;return Ka(Ga.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&_n(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Ka(Ga.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&_n(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Ka(Ga.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&_n(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),Ga.htmlImage.lastIndex=0,t}function Ja(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 Ya={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`]},Xa=[`github.com`,`githubusercontent.com`];async function Za(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(!Xa.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=xe.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=Ja(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await W.mkdtemp(z.join(Ee.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=z.join(p,m);return await W.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:M(t)}),null}}async function Qa(e,t,n=Ya,r){return Promise.all(e.map(async(e,i)=>Za(e,i,t,n,r)))}async function $a(e,t){for(let n of e)try{await W.unlink(n);let e=z.dirname(n);await W.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:M(e)})}}function eo(e){return e.map(e=>({type:`file`,mime:e.mime,url:Ce(e.tempPath).toString(),filename:e.filename}))}function to(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 no(e,t,n,r){return{processed:n,skipped:r,modifiedBody:to(e,t,n),fileParts:eo(n),tempFiles:n.map(e=>e.tempPath)}}function ro(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function io(e,t=Ya,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 (${ro(o.sizeBytes)} > ${ro(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 (${ro(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!ao(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 ao(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}const oo=``;function so(e,t){return t==null?!1:e===t||e===`${t}[bot]`}function co(e,t,n){return so(e,n)&&t.includes(oo)}async function lo(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:M(e)}),null}}async function uo(e,t,n,r){let i=[],a=1;for(;a<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:a});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;i.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:co(t,e.body??``,n)})}if(r.length<100)break;a++}catch(e){r.warning(`Failed to fetch comments page`,{target:t,page:a,error:M(e)});break}return i}async function fo(e,t,n,r){try{let i=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` query GetDiscussion($owner: String!, $repo: String!, $number: Int!, $after: String) { repository(owner: $owner, name: $repo) { discussion(number: $number) { @@ -280,7 +280,7 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void } } } -`,{owner:t.owner,repo:t.repo,number:t.number,after:a})).repository.discussion;if(d==null)return r.debug(`Discussion not found`,{target:t}),null;u===0&&(o=d.id,s=d.title,c=d.body,l=d.author?.login??`unknown`);for(let e of d.comments.nodes){let t=e.author?.login??`unknown`;i.push({id:e.id,body:e.body,author:t,authorAssociation:`NONE`,createdAt:e.createdAt,updatedAt:e.updatedAt,isBot:co(t,e.body,n)})}if(!d.comments.pageInfo.hasNextPage)break;a=d.comments.pageInfo.endCursor,u++}return{type:`discussion`,number:t.number,title:s,body:c,author:l,comments:i,discussionId:o??void 0}}catch(e){return r.warning(`Failed to fetch discussion`,{target:t,error:N(e)}),null}}async function po(e,t,n,r){if(t.type===`discussion`)return fo(e,t,n,r);let i=await lo(e,t,r);if(i==null)return null;let a=await uo(e,t,n,r);return{type:t.type,number:t.number,title:i.title,body:i.body,author:i.author,comments:a}}function mo(e,t){let n=e.comments.filter(e=>so(e.author,t)&&e.body.includes(oo));return n.length===0?null:n.at(-1)??null}async function ho(e,t,n,r){try{let{data:i}=await e.rest.issues.createComment({owner:t.owner,repo:t.repo,issue_number:t.number,body:n});return r.debug(`Created issue comment`,{commentId:i.id,target:t}),{commentId:i.id,created:!0,updated:!1,url:i.html_url}}catch(e){return r.warning(`Failed to create issue comment`,{target:t,error:N(e)}),null}}async function go(e,t,n,r,i){try{let{data:a}=await e.rest.issues.updateComment({owner:t.owner,repo:t.repo,comment_id:n,body:r});return i.debug(`Updated issue comment`,{commentId:a.id,target:t}),{commentId:a.id,created:!1,updated:!0,url:a.html_url}}catch(e){return i.warning(`Failed to update issue comment`,{target:t,commentId:n,error:N(e)}),null}}async function _o(e,t,n,r){try{let i=(await e.graphql(` +`,{owner:t.owner,repo:t.repo,number:t.number,after:a})).repository.discussion;if(d==null)return r.debug(`Discussion not found`,{target:t}),null;u===0&&(o=d.id,s=d.title,c=d.body,l=d.author?.login??`unknown`);for(let e of d.comments.nodes){let t=e.author?.login??`unknown`;i.push({id:e.id,body:e.body,author:t,authorAssociation:`NONE`,createdAt:e.createdAt,updatedAt:e.updatedAt,isBot:co(t,e.body,n)})}if(!d.comments.pageInfo.hasNextPage)break;a=d.comments.pageInfo.endCursor,u++}return{type:`discussion`,number:t.number,title:s,body:c,author:l,comments:i,discussionId:o??void 0}}catch(e){return r.warning(`Failed to fetch discussion`,{target:t,error:M(e)}),null}}async function po(e,t,n,r){if(t.type===`discussion`)return fo(e,t,n,r);let i=await lo(e,t,r);if(i==null)return null;let a=await uo(e,t,n,r);return{type:t.type,number:t.number,title:i.title,body:i.body,author:i.author,comments:a}}function mo(e,t){let n=e.comments.filter(e=>so(e.author,t)&&e.body.includes(oo));return n.length===0?null:n.at(-1)??null}async function ho(e,t,n,r){try{let{data:i}=await e.rest.issues.createComment({owner:t.owner,repo:t.repo,issue_number:t.number,body:n});return r.debug(`Created issue comment`,{commentId:i.id,target:t}),{commentId:i.id,created:!0,updated:!1,url:i.html_url}}catch(e){return r.warning(`Failed to create issue comment`,{target:t,error:M(e)}),null}}async function go(e,t,n,r,i){try{let{data:a}=await e.rest.issues.updateComment({owner:t.owner,repo:t.repo,comment_id:n,body:r});return i.debug(`Updated issue comment`,{commentId:a.id,target:t}),{commentId:a.id,created:!1,updated:!0,url:a.html_url}}catch(e){return i.warning(`Failed to update issue comment`,{target:t,commentId:n,error:M(e)}),null}}async function _o(e,t,n,r){try{let i=(await e.graphql(` query GetDiscussionId($owner: String!, $repo: String!, $number: Int!) { repository(owner: $owner, name: $repo) { discussion(number: $number) { @@ -313,6 +313,6 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void comment { id url } } } -`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:N(e)}),null}}async function vo(e,t,n,r){if(t.type===`discussion`)return _o(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await po(e,t,n.botLogin,r);if(i!=null){let a=mo(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return go(e,t,a.id,n.body,r)}}return ho(e,t,n.body,r)}function yo(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function bo(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function xo(e){let t=ci,n=yo(t.eventName),r=bo(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function So(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function Co(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function wo(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 To(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Eo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function Do(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`;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}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function Oo(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return fa(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return fa(Error(`auth-json is required but was not provided`));So(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?Co(i,`session-retention`):k,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:le,p=m(`model`).trim(),h=p.length>0?wo(p):null,g=m(`timeout`).trim(),_=g.length>0?To(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:A,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:P,C=m(`omo-providers`).trim();return da({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:Do(C.length>0?C:oe)})}catch(e){return fa(e instanceof Error?e:Error(String(e)))}}function ko(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Ao(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function jo(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(F.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,ko(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Ao(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(F.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&F.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&F.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(F.addHeading(`Token Usage`,3),F.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&F.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&F.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(F.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&F.addList([...c.prsCreated]),c.commitsCreated.length>0&&F.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&F.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){F.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;F.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await F.write(),t.debug(`Wrote job summary`)}catch(e){let r=N(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Mo(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function No(e){L(`session-id`,e.sessionId??``),L(`cache-status`,e.cacheStatus),L(`duration`,e.duration)}function Po(e){let t=R.resolve(e);return t.endsWith(R.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function Fo(e){return typeof e==`boolean`?e:null}function Io(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function Lo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Io(e.diffs)}}function Ro(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function zo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Bo(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:zo(e.time),summary:Lo(e.summary),share:Ro(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Vo(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Io(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Ho(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:Fo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function Uo(e){return Z(e)?Q(e.role)===`assistant`?Ho(e):Vo(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Wo(e){let t=Uo(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(qo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function Go(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Ko(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function qo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=Go(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:Fo(e.synthetic)??void 0,ignored:Fo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Ko(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Jo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Bo):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function Yo(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Wo)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function Xo(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Bo);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function Zo(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function Qo(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function $o(e,t,n){let r=Po(t),i=await Qo(e,n);for(let e of i){if(Po(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Po(t)===r)return e}return null}async function es(e,t,n){return Jo(e,t,n)}async function ts(e,t,n){return Yo(e,t,n)}async function ns(e,t,n){return Zo(e,t,n)}async function rs(e,t,n,r){return Xo(e,t,n,r)}const is={maxSessions:50,maxAgeDays:30};async function as(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await $o(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await es(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await ns(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:N(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function os(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await es(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await ts(e,t.id,r),i=ss(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ss(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function cs(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ls(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await os(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ls(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ls(e,t,n,r,i){let a=await ts(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=us(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function us(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ds(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` -`)}async function fs(e,t,n,r){let i=ds(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:i}]}});if(t.error!=null){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}r.info(`Session summary written via SDK`,{sessionId:e})}catch(t){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:N(t)})}}const ps=/^[0-9a-f]{40}$/i;function ms(){return{exec:x,getExecOutput:c}}async function hs(e){let{workspacePath:t,logger:n,execAdapter:r=ms()}=e,i=R.join(t,`.git`),a=R.join(i,`opencode`);try{let e=(await U.readFile(a,`utf8`)).trim();if(e.length>0){if(ps.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:N(e)})}try{if((await U.stat(i)).isDirectory()===!1){let e=await U.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=R.resolve(t,n[1]),a=R.join(i,`opencode`)}}catch{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 U.writeFile(a,s,`utf8`),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){n.warning(`Failed to cache project ID (continuing)`,{error:N(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:N(e)}}}const gs={botLogin:null,requireMention:!0,allowedAssociations:pa,skipDraftPRs:!0,promptInput:null};function _s(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${vs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function vs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function ys(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${vs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function bs(e,t){return t.includes(e)}function xs(e){return e.endsWith(`[bot]`)}function Ss(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=_s(e,t);return{hasMention:n,command:n?ys(e,t):null}}function Cs(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},i=e.comment.body,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function ws(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:e.comment.body??e.discussion.body??null,locked:e.discussion.locked},i=e.comment.body??null,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Ts(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Es(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:xs(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=Ss(e.issue.body??``,t);return{author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,action:e.action}}const Ds=[`opened`,`edited`];function Os(e){return Ds.includes(e)}function ks(e,t,n){let r=e.action;return r==null||!Os(r)?(n.debug(`Skipping unsupported issues action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${r}' is not supported (only 'opened' and 'edited')`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):r===`edited`&&!e.hasMention?(n.debug(`Skipping issues.edited without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}):e.target?.locked===!0?(n.debug(`Skipping locked issue`),{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}):{shouldSkip:!1}}function As(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:xs(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft},{hasMention:i,command:a}=Ss(e.pullRequest.body??``,t);return{author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,action:e.action}}const js=[`opened`,`synchronize`,`reopened`];function Ms(e){return js.includes(e)}function Ns(e,t,n){let r=e.action;return r==null||!Ms(r)?(n.debug(`Skipping unsupported pull_request action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${r}' is not supported`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.skipDraftPRs&&e.target?.isDraft===!0?(n.debug(`Skipping draft PR`),{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}):e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):{shouldSkip:!1}}function Ps(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=Ss(e.comment.body,t);return{author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,action:e.action}}function Fs(e,t,n){let r=n?.trim()??``;return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Is(e,t){return(e.promptInput?.trim()??``)===``?(t.debug(`Skipping schedule event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}):{shouldSkip:!1}}function Ls(e,t){return(e.commentBody?.trim()??``)===``?(t.debug(`Skipping workflow_dispatch event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}):{shouldSkip:!1}}function Rs(e,t,n,r){let{targetLabel:i,actionLabel:a}=r;return e.action===`created`?e.target?.locked===!0?(n.debug(`Skipping locked ${i}`),{shouldSkip:!0,reason:`issue_locked`,message:`${i} is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping ${a} without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created ${a} action`,{action:e.action}),{shouldSkip:!0,reason:`action_not_created`,message:`${a} action is '${e.action}', not 'created'`})}function zs(e,t,n){return Rs(e,t,n,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function Bs(e,t,n){return Rs(e,t,n,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}function Vs(e,t,n){let r=e.action;return r===`created`?e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping review comment without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created review comment action`,{action:r}),{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${r}' is not supported (only 'created')`})}function Hs(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e.eventName}`};switch(e.eventType){case`issue_comment`:return zs(e,t,n);case`discussion_comment`:return Bs(e,t,n);case`issues`:return ks(e,t,n);case`pull_request`:return Ns(e,t,n);case`pull_request_review_comment`:return Vs(e,t,n);case`schedule`:return Is(t,n);case`workflow_dispatch`:return Ls(e,n);default:return{shouldSkip:!1}}}function Us(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:{let n=Cs(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`discussion_comment`:{let n=ws(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`workflow_dispatch`:{let t=Ts(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`issues`:{let n=Es(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request`:{let n=As(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request_review_comment`:{let n=Ps(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`schedule`:{let t=Fs(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null}}}function Ws(e,t,n={}){let r={...gs,...n},i=Us(e,r.botLogin,r.promptInput);t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Hs(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function Gs(){let e=Date.now(),t=j({phase:`bootstrap`}),n=null,i=!1,o=0,s=null,c=null,l=null,u=null,d=Mo();d.start(),f(I.SHOULD_SAVE_CACHE,`false`),f(I.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let p=Oo();if(!p.success)return _(`Invalid inputs: ${p.error.message}`),1;let m=p.data,h=j({phase:`main`});h.info(`Action inputs parsed`,{sessionRetention:m.sessionRetention,s3Backup:m.s3Backup,hasGithubToken:m.githubToken.length>0,hasPrompt:m.prompt!=null,agent:m.agent,hasModelOverride:m.model!=null,timeoutMs:m.timeoutMs});let g=await Pa({logger:h,opencodeVersion:m.opencodeVersion});g.didSetup?h.info(`OpenCode auto-setup completed`,{version:g.version}):h.info(`OpenCode already available`,{version:g.version}),f(I.OPENCODE_VERSION,g.version),l=g.version;let b=j({phase:`context`}),x=xo(b);s=Bi({token:m.githubToken,logger:b});let S=await Vi(s,b),C=j({phase:`trigger`}),w=Ws(x,C,{botLogin:S,requireMention:!0,promptInput:m.prompt});if(!w.shouldProcess)return C.info(`Skipping event`,{reason:w.skipReason,message:w.skipMessage}),No({sessionId:null,cacheStatus:`miss`,duration:Date.now()-e}),0;C.info(`Event routed for processing`,{eventType:w.context.eventType,hasMention:w.context.hasMention,command:w.context.command?.action??null}),f(I.SHOULD_SAVE_CACHE,`true`);let T=await nt({logger:b,octokit:s,triggerContext:w.context,botLogin:S});n={repo:T.repo,commentId:T.commentId,issueNumber:T.issueNumber,issueType:T.issueType,botLogin:S};let E=j({phase:`acknowledgment`});await Ra(s,n,E);let ee={agentIdentity:`github`,repo:te(),ref:pe(),os:a()},D=j({phase:`cache`}),ne=v(),O=R.join(ne,`.git`,`opencode`),k=await ie({components:ee,logger:D,storagePath:y(),authPath:r(),projectIdPath:O,opencodeVersion:g.version}),A=k.corrupted?`corrupted`:k.hit?`hit`:`miss`;d.setCacheStatus(A),h.info(`Cache restore completed`,{cacheStatus:A,key:k.key});let M=await hs({workspacePath:ne,logger:D});M.source===`error`?D.warning(`Failed to generate project ID (continuing)`,{error:M.error}):D.debug(`Project ID ready`,{projectId:M.projectId,source:M.source});let N=j({phase:`server-bootstrap`}),re=await ja(new AbortController().signal,N);if(!re.success)return _(`OpenCode server bootstrap failed: ${re.error.message}`),1;u=re.data,N.info(`SDK server bootstrapped successfully`);let P=j({phase:`session`}),ae=Po(ne),oe=await os(u.client,ae,{limit:10},P);P.debug(`Listed recent sessions`,{count:oe.length});let F=T.issueTitle??T.repo,se=await cs(F,u.client,ae,{limit:5},P);P.debug(`Searched prior sessions`,{query:F,resultCount:se.length});for(let e of se)d.addSessionUsed(e.sessionId);let ce=j({phase:`attachments`}),le=T.commentBody??``,ue=qa(le);if(ue.length>0){ce.info(`Processing attachments`,{count:ue.length});let{validated:e,skipped:t}=io(await Qa(ue,m.githubToken,void 0,ce),void 0,ce);(e.length>0||t.length>0)&&(c=no(le,ue,e,t),ce.info(`Attachments processed`,{processed:e.length,skipped:t.length}))}let de={context:T,customPrompt:m.prompt,cacheStatus:A,sessionContext:{recentSessions:oe,priorWorkContext:se},triggerContext:w.context,fileParts:c?.fileParts},fe=B.env.SKIP_AGENT_EXECUTION===`true`,L,me=Date.now();if(fe)h.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),L={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let e=await Ma(de,j({phase:`execution`}),{agent:m.agent,model:m.model,timeoutMs:m.timeoutMs,omoProviders:m.omoProviders},u??void 0),t=e.sessionId;if(t==null){let e=await rs(u.client,ae,me,P);e!=null&&(t=e.session.id,P.debug(`Identified session from execution`,{sessionId:t}))}L={...e,sessionId:t}}L.sessionId!=null&&f(I.SESSION_ID,L.sessionId),i=L.success,L.sessionId!=null&&d.addSessionCreated(L.sessionId),L.tokenUsage!=null&&d.setTokenUsage(L.tokenUsage,L.model,L.cost);for(let e of L.prsCreated)d.addPRCreated(e);for(let e of L.commitsCreated)d.addCommitCreated(e);for(let e=0;e0&&n.owner.length>0&&n.repo.length>0){let e=dn(L.llmError),t=j({phase:`error-comment`}),r=await vo(s,n,{body:e},t);r==null?t.warning(`Failed to post LLM error comment`):(t.info(`Posted LLM error comment`,{commentUrl:r.url}),d.incrementComments())}else h.warning(`Cannot post error comment: missing target context`);o=0}}catch(n){o=1;let r=Date.now()-e,i=n instanceof Error?n.name:`UnknownError`,a=n instanceof Error?n.message:String(n);d.recordError(i,a,!1),d.end(),No({sessionId:null,cacheStatus:`miss`,duration:r}),n instanceof Error?(t.error(`Agent failed`,{error:n.message}),_(n.message)):(t.error(`Agent failed with unknown error`),_(`An unknown error occurred`))}finally{try{if(c!=null){let e=j({phase:`attachment-cleanup`});await $a(c.tempFiles,e)}if(n!=null&&s!=null){let e=j({phase:`cleanup`});await Wa(s,n,i,e)}let e=j({phase:`prune`}),t=v();if(u!=null){let n=Po(t),r=await as(u.client,n,is,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let o={agentIdentity:`github`,repo:te(),ref:pe(),os:a()},d=j({phase:`cache-save`}),p=R.join(t,`.git`,`opencode`);await se({components:o,runId:fe(),logger:d,storagePath:y(),authPath:r(),projectIdPath:p,opencodeVersion:l})&&f(I.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(u!=null)try{u.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}return o}await Gs().then(e=>{B.exit(e)});export{}; \ No newline at end of file +`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:M(e)}),null}}async function vo(e,t,n,r){if(t.type===`discussion`)return _o(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await po(e,t,n.botLogin,r);if(i!=null){let a=mo(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return go(e,t,a.id,n.body,r)}}return ho(e,t,n.body,r)}function yo(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function bo(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function xo(e){let t=ci,n=yo(t.eventName),r=bo(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function So(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function Co(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function wo(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 To(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Eo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function Do(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`;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}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function Oo(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return fa(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return fa(Error(`auth-json is required but was not provided`));So(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?Co(i,`session-retention`):O,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:L,p=m(`model`).trim(),h=p.length>0?wo(p):null,g=m(`timeout`).trim(),_=g.length>0?To(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:k,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:N,C=m(`omo-providers`).trim();return da({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:Do(C.length>0?C:se)})}catch(e){return fa(e instanceof Error?e:Error(String(e)))}}function ko(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Ao(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function jo(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(P.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,ko(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Ao(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(P.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&P.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&P.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(P.addHeading(`Token Usage`,3),P.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&P.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&P.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(P.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&P.addList([...c.prsCreated]),c.commitsCreated.length>0&&P.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&P.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){P.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;P.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await P.write(),t.debug(`Wrote job summary`)}catch(e){let r=M(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Mo(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function No(e){R(`session-id`,e.sessionId??``),R(`cache-status`,e.cacheStatus),R(`duration`,e.duration)}function Po(e){let t=z.resolve(e);return t.endsWith(z.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function Fo(e){return typeof e==`boolean`?e:null}function Io(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function Lo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Io(e.diffs)}}function Ro(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function zo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Bo(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:zo(e.time),summary:Lo(e.summary),share:Ro(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Vo(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Io(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Ho(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:Fo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function Uo(e){return Z(e)?Q(e.role)===`assistant`?Ho(e):Vo(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Wo(e){let t=Uo(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(qo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function Go(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Ko(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function qo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=Go(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:Fo(e.synthetic)??void 0,ignored:Fo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Ko(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Jo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Bo):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function Yo(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Wo)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function Xo(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Bo);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function Zo(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function Qo(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function $o(e,t,n){let r=Po(t),i=await Qo(e,n);for(let e of i){if(Po(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Po(t)===r)return e}return null}async function es(e,t,n){return Jo(e,t,n)}async function ts(e,t,n){return Yo(e,t,n)}async function ns(e,t,n){return Zo(e,t,n)}async function rs(e,t,n,r){return Xo(e,t,n,r)}const is={maxSessions:50,maxAgeDays:30};async function as(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await $o(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await es(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await ns(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:M(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function os(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await es(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await ts(e,t.id,r),i=ss(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ss(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function cs(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ls(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await os(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ls(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ls(e,t,n,r,i){let a=await ts(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=us(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function us(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ds(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` +`)}async function fs(e,t,n,r){let i=ds(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:i}]}});if(t.error!=null){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}r.info(`Session summary written via SDK`,{sessionId:e})}catch(t){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:M(t)})}}const ps=/^[0-9a-f]{40}$/i;function ms(){return{exec:x,getExecOutput:c}}async function hs(e){let{workspacePath:t,logger:n,execAdapter:r=ms()}=e,i=z.join(t,`.git`),a=z.join(i,`opencode`);try{let e=(await W.readFile(a,`utf8`)).trim();if(e.length>0){if(ps.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:M(e)})}try{if((await W.stat(i)).isDirectory()===!1){let e=await W.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=z.resolve(t,n[1]),a=z.join(i,`opencode`)}}catch{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 W.writeFile(a,s,`utf8`),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){n.warning(`Failed to cache project ID (continuing)`,{error:M(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:M(e)}}}const gs={botLogin:null,requireMention:!0,allowedAssociations:pa,skipDraftPRs:!0,promptInput:null};function _s(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${vs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function vs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function ys(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${vs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function bs(e,t){return t.includes(e)}function xs(e){return e.endsWith(`[bot]`)}function Ss(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=_s(e,t);return{hasMention:n,command:n?ys(e,t):null}}function Cs(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},i=e.comment.body,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function ws(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:e.comment.body??e.discussion.body??null,locked:e.discussion.locked},i=e.comment.body??null,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Ts(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Es(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:xs(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=Ss(e.issue.body??``,t);return{author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,action:e.action}}const Ds=[`opened`,`edited`];function Os(e){return Ds.includes(e)}function ks(e,t,n){let r=e.action;return r==null||!Os(r)?(n.debug(`Skipping unsupported issues action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${r}' is not supported (only 'opened' and 'edited')`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):r===`edited`&&!e.hasMention?(n.debug(`Skipping issues.edited without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}):e.target?.locked===!0?(n.debug(`Skipping locked issue`),{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}):{shouldSkip:!1}}function As(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:xs(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft},{hasMention:i,command:a}=Ss(e.pullRequest.body??``,t);return{author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,action:e.action}}const js=[`opened`,`synchronize`,`reopened`];function Ms(e){return js.includes(e)}function Ns(e,t,n){let r=e.action;return r==null||!Ms(r)?(n.debug(`Skipping unsupported pull_request action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${r}' is not supported`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.skipDraftPRs&&e.target?.isDraft===!0?(n.debug(`Skipping draft PR`),{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}):e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):{shouldSkip:!1}}function Ps(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=Ss(e.comment.body,t);return{author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,action:e.action}}function Fs(e,t,n){let r=n?.trim()??``;return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Is(e,t){return(e.promptInput?.trim()??``)===``?(t.debug(`Skipping schedule event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}):{shouldSkip:!1}}function Ls(e,t){return(e.commentBody?.trim()??``)===``?(t.debug(`Skipping workflow_dispatch event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}):{shouldSkip:!1}}function Rs(e,t,n,r){let{targetLabel:i,actionLabel:a}=r;return e.action===`created`?e.target?.locked===!0?(n.debug(`Skipping locked ${i}`),{shouldSkip:!0,reason:`issue_locked`,message:`${i} is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping ${a} without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created ${a} action`,{action:e.action}),{shouldSkip:!0,reason:`action_not_created`,message:`${a} action is '${e.action}', not 'created'`})}function zs(e,t,n){return Rs(e,t,n,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function Bs(e,t,n){return Rs(e,t,n,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}function Vs(e,t,n){let r=e.action;return r===`created`?e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping review comment without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created review comment action`,{action:r}),{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${r}' is not supported (only 'created')`})}function Hs(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e.eventName}`};switch(e.eventType){case`issue_comment`:return zs(e,t,n);case`discussion_comment`:return Bs(e,t,n);case`issues`:return ks(e,t,n);case`pull_request`:return Ns(e,t,n);case`pull_request_review_comment`:return Vs(e,t,n);case`schedule`:return Is(t,n);case`workflow_dispatch`:return Ls(e,n);default:return{shouldSkip:!1}}}function Us(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:{let n=Cs(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`discussion_comment`:{let n=ws(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`workflow_dispatch`:{let t=Ts(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`issues`:{let n=Es(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request`:{let n=As(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request_review_comment`:{let n=Ps(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`schedule`:{let t=Fs(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null}}}function Ws(e,t,n={}){let r={...gs,...n},i=Us(e,r.botLogin,r.promptInput);t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Hs(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function Gs(){let e=Date.now(),t=A({phase:`bootstrap`}),n=null,i=!1,o=0,s=null,c=null,l=null,u=null,d=Mo();d.start(),f(I.SHOULD_SAVE_CACHE,`false`),f(I.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let p=Oo();if(!p.success)return _(`Invalid inputs: ${p.error.message}`),1;let m=p.data,h=A({phase:`main`});h.info(`Action inputs parsed`,{sessionRetention:m.sessionRetention,s3Backup:m.s3Backup,hasGithubToken:m.githubToken.length>0,hasPrompt:m.prompt!=null,agent:m.agent,hasModelOverride:m.model!=null,timeoutMs:m.timeoutMs});let g=await Pa({logger:h,opencodeVersion:m.opencodeVersion});g.didSetup?h.info(`OpenCode auto-setup completed`,{version:g.version}):h.info(`OpenCode already available`,{version:g.version}),f(I.OPENCODE_VERSION,g.version),l=g.version;let b=A({phase:`context`}),x=xo(b);s=Bi({token:m.githubToken,logger:b});let S=await Vi(s,b),C=A({phase:`trigger`}),w=Ws(x,C,{botLogin:S,requireMention:!0,promptInput:m.prompt});if(!w.shouldProcess)return C.info(`Skipping event`,{reason:w.skipReason,message:w.skipMessage}),No({sessionId:null,cacheStatus:`miss`,duration:Date.now()-e}),0;C.info(`Event routed for processing`,{eventType:w.context.eventType,hasMention:w.context.hasMention,command:w.context.command?.action??null}),f(I.SHOULD_SAVE_CACHE,`true`);let T=await tt({logger:b,octokit:s,triggerContext:w.context,botLogin:S});n={repo:T.repo,commentId:T.commentId,issueNumber:T.issueNumber,issueType:T.issueType,botLogin:S};let E=A({phase:`acknowledgment`});await Ra(s,n,E);let ee={agentIdentity:`github`,repo:te(),ref:fe(),os:a()},D=A({phase:`cache`}),ne=v(),re=z.join(ne,`.git`,`opencode`),O=await ae({components:ee,logger:D,storagePath:y(),authPath:r(),projectIdPath:re,opencodeVersion:g.version}),k=O.corrupted?`corrupted`:O.hit?`hit`:`miss`;d.setCacheStatus(k),h.info(`Cache restore completed`,{cacheStatus:k,key:O.key});let j=await hs({workspacePath:ne,logger:D});j.source===`error`?D.warning(`Failed to generate project ID (continuing)`,{error:j.error}):D.debug(`Project ID ready`,{projectId:j.projectId,source:j.source});let M=A({phase:`server-bootstrap`}),ie=await ja(new AbortController().signal,M);if(!ie.success)return _(`OpenCode server bootstrap failed: ${ie.error.message}`),1;u=ie.data,M.info(`SDK server bootstrapped successfully`);let N=A({phase:`session`}),oe=Po(ne),se=await os(u.client,oe,{limit:10},N);N.debug(`Listed recent sessions`,{count:se.length});let P=T.issueTitle??T.repo,F=await cs(P,u.client,oe,{limit:5},N);N.debug(`Searched prior sessions`,{query:P,resultCount:F.length});for(let e of F)d.addSessionUsed(e.sessionId);let ce=A({phase:`attachments`}),L=T.commentBody??``,le=qa(L);if(le.length>0){ce.info(`Processing attachments`,{count:le.length});let{validated:e,skipped:t}=io(await Qa(le,m.githubToken,void 0,ce),void 0,ce);(e.length>0||t.length>0)&&(c=no(L,le,e,t),ce.info(`Attachments processed`,{processed:e.length,skipped:t.length}))}let ue={context:T,customPrompt:m.prompt,cacheStatus:k,sessionContext:{recentSessions:se,priorWorkContext:F},triggerContext:w.context,fileParts:c?.fileParts},de=V.env.SKIP_AGENT_EXECUTION===`true`,R,pe=Date.now();if(de)h.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),R={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let e=await Ma(ue,A({phase:`execution`}),{agent:m.agent,model:m.model,timeoutMs:m.timeoutMs,omoProviders:m.omoProviders},u??void 0),t=e.sessionId;if(t==null){let e=await rs(u.client,oe,pe,N);e!=null&&(t=e.session.id,N.debug(`Identified session from execution`,{sessionId:t}))}R={...e,sessionId:t}}R.sessionId!=null&&f(I.SESSION_ID,R.sessionId),i=R.success,R.sessionId!=null&&d.addSessionCreated(R.sessionId),R.tokenUsage!=null&&d.setTokenUsage(R.tokenUsage,R.model,R.cost);for(let e of R.prsCreated)d.addPRCreated(e);for(let e of R.commitsCreated)d.addCommitCreated(e);for(let e=0;e0&&n.owner.length>0&&n.repo.length>0){let e=un(R.llmError),t=A({phase:`error-comment`}),r=await vo(s,n,{body:e},t);r==null?t.warning(`Failed to post LLM error comment`):(t.info(`Posted LLM error comment`,{commentUrl:r.url}),d.incrementComments())}else h.warning(`Cannot post error comment: missing target context`);o=0}}catch(n){o=1;let r=Date.now()-e,i=n instanceof Error?n.name:`UnknownError`,a=n instanceof Error?n.message:String(n);d.recordError(i,a,!1),d.end(),No({sessionId:null,cacheStatus:`miss`,duration:r}),n instanceof Error?(t.error(`Agent failed`,{error:n.message}),_(n.message)):(t.error(`Agent failed with unknown error`),_(`An unknown error occurred`))}finally{try{if(c!=null){let e=A({phase:`attachment-cleanup`});await $a(c.tempFiles,e)}if(n!=null&&s!=null){let e=A({phase:`cleanup`});await Wa(s,n,i,e)}let e=A({phase:`prune`}),t=v();if(u!=null){let n=Po(t),r=await as(u.client,n,is,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let o={agentIdentity:`github`,repo:te(),ref:fe(),os:a()},d=A({phase:`cache-save`}),p=z.join(t,`.git`,`opencode`);await F({components:o,runId:de(),logger:d,storagePath:y(),authPath:r(),projectIdPath:p,opencodeVersion:l})&&f(I.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(u!=null)try{u.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}return o}await Gs().then(e=>{V.exit(e)});export{}; \ No newline at end of file diff --git a/src/lib/setup/setup.test.ts b/src/lib/setup/setup.test.ts index 9447aae0..0795ab16 100644 --- a/src/lib/setup/setup.test.ts +++ b/src/lib/setup/setup.test.ts @@ -228,6 +228,50 @@ describe('setup', () => { expect(core.exportVariable).toHaveBeenCalledWith('GH_TOKEN', 'ghs_test_token') }) + it('exports OPENCODE_CONFIG_CONTENT with autoupdate:false baseline', async () => { + // #given - no opencode-config input + vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') + vi.mocked(exec.getExecOutput).mockResolvedValue({exitCode: 0, stdout: '', stderr: ''}) + vi.mocked(exec.exec).mockResolvedValue(0) + vi.mocked(fs.writeFile).mockResolvedValue() + vi.mocked(fs.mkdir).mockResolvedValue(undefined) + vi.mocked(fs.access).mockRejectedValue(new Error('not found')) + + // #when + await runSetup() + + // #then + expect(core.exportVariable).toHaveBeenCalledWith('OPENCODE_CONFIG_CONTENT', JSON.stringify({autoupdate: false})) + }) + + it('merges user opencode-config input on top of OPENCODE_CONFIG_CONTENT baseline', async () => { + // #given - user supplies opencode-config with custom settings + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{"anthropic": {"api_key": "sk-ant-test"}}', + 'opencode-version': 'latest', + 'opencode-config': '{"model": "claude-opus-4-5", "autoupdate": true}', + } + return inputs[name] ?? '' + }) + vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') + vi.mocked(exec.getExecOutput).mockResolvedValue({exitCode: 0, stdout: '', stderr: ''}) + vi.mocked(exec.exec).mockResolvedValue(0) + vi.mocked(fs.writeFile).mockResolvedValue() + vi.mocked(fs.mkdir).mockResolvedValue(undefined) + vi.mocked(fs.access).mockRejectedValue(new Error('not found')) + + // #when + await runSetup() + + // #then - user config wins on conflicting keys (autoupdate:true overrides false baseline) + expect(core.exportVariable).toHaveBeenCalledWith( + 'OPENCODE_CONFIG_CONTENT', + JSON.stringify({autoupdate: true, model: 'claude-opus-4-5'}), + ) + }) + it('sets outputs for opencode-path and auth-json-path', async () => { // #given vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') diff --git a/src/lib/setup/setup.ts b/src/lib/setup/setup.ts index 6dff893c..acca337d 100644 --- a/src/lib/setup/setup.ts +++ b/src/lib/setup/setup.ts @@ -234,6 +234,15 @@ export async function runSetup(): Promise { omoError = omoResult.error } + // Export CI-safe OpenCode config. OPENCODE_CONFIG_CONTENT has highest precedence over all + // other OpenCode config sources (project, global, etc.). User-supplied opencode-config input + // is merged on top of the baseline, so user values override the defaults. + const ciConfig: Record = { + autoupdate: false, + ...(inputs.opencodeConfig == null ? {} : (JSON.parse(inputs.opencodeConfig) as Record)), + } + core.exportVariable('OPENCODE_CONFIG_CONTENT', JSON.stringify(ciConfig)) + if (!toolsCacheResult.hit) { await saveToolsCache({ logger, From 22a2bf65b6d8366f8fa0e483dcc62844e4251e44 Mon Sep 17 00:00:00 2001 From: "Marcus R. Brown" Date: Sun, 1 Mar 2026 01:00:22 -0700 Subject: [PATCH 3/8] fix(setup): declare and validate opencode-config --- action.yaml | 5 ++ dist/main.js | 30 +++++------ src/lib/inputs.test.ts | 57 ++++++++++++++++++++ src/lib/inputs.ts | 9 ++++ src/lib/setup/setup.test.ts | 104 ++++++++++++++++++++++++++++++++++++ src/lib/setup/setup.ts | 14 +++-- src/lib/types.ts | 2 + 7 files changed, 203 insertions(+), 18 deletions(-) diff --git a/action.yaml b/action.yaml index 060a060a..23fc8374 100644 --- a/action.yaml +++ b/action.yaml @@ -56,6 +56,11 @@ inputs: copilot, gemini, openai, opencode-zen, zai-coding-plan. Default: empty (uses free OpenCode models) required: false + opencode-config: + description: >- + JSON object to merge into the OpenCode config (OPENCODE_CONFIG_CONTENT). + Values are merged on top of the autoupdate:false baseline; user values win on conflicts. + required: false outputs: session-id: diff --git a/dist/main.js b/dist/main.js index 19c7d7ab..fab9a994 100644 --- a/dist/main.js +++ b/dist/main.js @@ -1,7 +1,7 @@ -import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,Q as g,R as _,S as v,T as y,U as b,V as x,W as S,X as C,Y as w,Z as T,_ as E,a as ee,b as te,c as D,d as ne,f as re,g as O,h as k,i as A,j,k as M,l as ie,m as N,n as ae,o as oe,p as se,q as P,r as F,s as ce,t as I,u as L,v as le,w as ue,x as de,y as fe,z as R}from"./state-keys-CDII8qo6.js";import*as z from"node:path";import pe,{join as B}from"node:path";import V from"node:process";import*as me from"os";import{EOL as he}from"os";import*as ge from"crypto";import*as H from"fs";import{existsSync as _e,readFileSync as ve}from"fs";import*as U from"path";import{ok as ye}from"assert";import*as be from"util";import{Buffer as xe}from"node:buffer";import*as Se from"node:crypto";import{pathToFileURL as Ce}from"node:url";import*as W from"node:fs/promises";import we from"node:fs/promises";import{spawn as Te}from"node:child_process";import*as Ee from"node:os";import De,{homedir as Oe}from"node:os";import*as ke from"stream";const Ae={maxComments:50,maxCommits:100,maxFiles:100,maxReviews:100,maxBodyBytes:10*1024,maxTotalBytes:100*1024},je=`…[truncated]`;function Me(e,t){if(e.length===0)return{text:``,truncated:!1};let n=new TextEncoder,r=n.encode(e);if(r.length<=t)return{text:e,truncated:!1};let i=t-n.encode(je).length;if(i<=0)return{text:je,truncated:!0};let a=r.slice(0,i),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);for(;o.length>0&&o.charCodeAt(o.length-1)===65533;)a=a.slice(0,-1),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);return{text:o+je,truncated:!0}}function Ne(e){return e.length===0?``:`**Labels:** ${e.map(e=>`\`${e.name}\``).join(`, `)}\n`}function Pe(e){return e.length===0?``:`**Assignees:** ${e.map(e=>`@${e.login}`).join(`, `)}\n`}function Fe(e){let t=[];t.push(`## Issue #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`);let n=Ne(e.labels);n.length>0&&t.push(n.trimEnd());let r=Pe(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Body`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Body was truncated due to size limits.*`)),e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),e.commentsTruncated&&(t.push(``),t.push(`*Note: Comments were truncated due to limits.*`)),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` -`)}function Ie(e){let t=[];t.push(`## Pull Request #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`),t.push(`**Base:** ${e.baseBranch} ← **Head:** ${e.headBranch}`),e.isFork&&t.push(`**Fork:** Yes (external contributor)`);let n=Ne(e.labels);n.length>0&&t.push(n.trimEnd());let r=Pe(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Description`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Description was truncated due to size limits.*`)),e.files.length>0){t.push(``),t.push(`### Files Changed (${e.files.length}${e.filesTruncated?` of ${e.totalFiles}`:``})`),t.push(``),t.push(`| File | +/- |`),t.push(`|------|-----|`);for(let n of e.files)t.push(`| \`${n.path}\` | +${n.additions}/-${n.deletions} |`)}if(e.commits.length>0){t.push(``),t.push(`### Commits (${e.commits.length}${e.commitsTruncated?` of ${e.totalCommits}`:``})`),t.push(``);for(let n of e.commits){let e=n.oid.slice(0,7);t.push(`- \`${e}\` ${n.message.split(` +import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,Q as g,R as _,S as v,T as y,U as b,V as x,W as S,X as C,Y as w,Z as T,_ as E,a as ee,b as te,c as D,d as ne,f as re,g as O,h as k,i as A,j,k as M,l as ie,m as N,n as ae,o as oe,p as se,q as P,r as F,s as I,t as L,u as R,v as ce,w as le,x as ue,y as de,z}from"./state-keys-CDII8qo6.js";import*as B from"node:path";import fe,{join as V}from"node:path";import H from"node:process";import*as pe from"os";import{EOL as me}from"os";import*as he from"crypto";import*as U from"fs";import{existsSync as ge,readFileSync as _e}from"fs";import*as W from"path";import{ok as ve}from"assert";import*as ye from"util";import{Buffer as be}from"node:buffer";import*as xe from"node:crypto";import{pathToFileURL as Se}from"node:url";import*as G from"node:fs/promises";import Ce from"node:fs/promises";import{spawn as we}from"node:child_process";import*as Te from"node:os";import Ee,{homedir as De}from"node:os";import*as Oe from"stream";const ke={maxComments:50,maxCommits:100,maxFiles:100,maxReviews:100,maxBodyBytes:10*1024,maxTotalBytes:100*1024},Ae=`…[truncated]`;function je(e,t){if(e.length===0)return{text:``,truncated:!1};let n=new TextEncoder,r=n.encode(e);if(r.length<=t)return{text:e,truncated:!1};let i=t-n.encode(Ae).length;if(i<=0)return{text:Ae,truncated:!0};let a=r.slice(0,i),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);for(;o.length>0&&o.charCodeAt(o.length-1)===65533;)a=a.slice(0,-1),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);return{text:o+Ae,truncated:!0}}function Me(e){return e.length===0?``:`**Labels:** ${e.map(e=>`\`${e.name}\``).join(`, `)}\n`}function Ne(e){return e.length===0?``:`**Assignees:** ${e.map(e=>`@${e.login}`).join(`, `)}\n`}function Pe(e){let t=[];t.push(`## Issue #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`);let n=Me(e.labels);n.length>0&&t.push(n.trimEnd());let r=Ne(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Body`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Body was truncated due to size limits.*`)),e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),e.commentsTruncated&&(t.push(``),t.push(`*Note: Comments were truncated due to limits.*`)),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` +`)}function Fe(e){let t=[];t.push(`## Pull Request #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`),t.push(`**Base:** ${e.baseBranch} ← **Head:** ${e.headBranch}`),e.isFork&&t.push(`**Fork:** Yes (external contributor)`);let n=Me(e.labels);n.length>0&&t.push(n.trimEnd());let r=Ne(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Description`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Description was truncated due to size limits.*`)),e.files.length>0){t.push(``),t.push(`### Files Changed (${e.files.length}${e.filesTruncated?` of ${e.totalFiles}`:``})`),t.push(``),t.push(`| File | +/- |`),t.push(`|------|-----|`);for(let n of e.files)t.push(`| \`${n.path}\` | +${n.additions}/-${n.deletions} |`)}if(e.commits.length>0){t.push(``),t.push(`### Commits (${e.commits.length}${e.commitsTruncated?` of ${e.totalCommits}`:``})`),t.push(``);for(let n of e.commits){let e=n.oid.slice(0,7);t.push(`- \`${e}\` ${n.message.split(` `)[0]}`)}}if(e.reviews.length>0){t.push(``),t.push(`### Reviews (${e.reviews.length}${e.reviewsTruncated?` of ${e.totalReviews}`:``})`),t.push(``);for(let n of e.reviews)t.push(`**${n.author??`unknown`}** - ${n.state}`),n.body.length>0&&t.push(n.body),t.push(``)}if(e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` -`)}function Le(e){return e.type===`issue`?Fe(e):Ie(e)}async function Re(e,t,n,r,i,a){try{let[a,o]=await Promise.all([e.rest.issues.get({owner:t,repo:n,issue_number:r}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),s=a.data,c=Me(s.body??``,i.maxBodyBytes),l=o.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),u=(s.labels??[]).filter(e=>typeof e==`object`&&!!e&&`name`in e).map(e=>({name:e.name??``,color:e.color})),d=(s.assignees??[]).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.user?.login??null,createdAt:s.created_at,labels:u,assignees:d,comments:l,commentsTruncated:o.data.length>=i.maxComments,totalComments:o.data.length}}catch(e){return a.warning(`REST issue fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function ze(e,t,n,r,i,a){try{let[o,s,c,l,u]=await Promise.all([e.rest.pulls.get({owner:t,repo:n,pull_number:r}),e.rest.pulls.listCommits({owner:t,repo:n,pull_number:r,per_page:i.maxCommits}),e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:i.maxFiles}),e.rest.pulls.listReviews({owner:t,repo:n,pull_number:r,per_page:i.maxReviews}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),d=await e.rest.pulls.listRequestedReviewers({owner:t,repo:n,pull_number:r}).catch(e=>(a.warning(`Failed to fetch requested reviewers, defaulting to empty`,{owner:t,repo:n,number:r,error:M(e)}),{data:{users:[],teams:[]}})),f=o.data,p=Me(f.body??``,i.maxBodyBytes),m=f.base.repo?.owner.login,h=f.head.repo?.owner.login,g=h==null||m!==h,_=u.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),v=s.data.slice(0,i.maxCommits).map(e=>({oid:e.sha,message:e.commit.message,author:e.commit.author?.name??null})),y=c.data.slice(0,i.maxFiles).map(e=>({path:e.filename,additions:e.additions,deletions:e.deletions,status:e.status})),b=l.data.slice(0,i.maxReviews).map(e=>({author:e.user?.login??null,state:e.state,body:e.body??``,createdAt:e.submitted_at??``,comments:[]})),x=(f.labels??[]).map(e=>({name:e.name??``,color:e.color})),S=(f.assignees??[]).map(e=>({login:e?.login??``})),C=(d.data.users??[]).map(e=>e.login),w=(d.data.teams??[]).map(e=>e.name);return{type:`pull_request`,number:f.number,title:f.title,body:p.text,bodyTruncated:p.truncated,state:f.state,author:f.user?.login??null,createdAt:f.created_at,baseBranch:f.base.ref,headBranch:f.head.ref,isFork:g,labels:x,assignees:S,comments:_,commentsTruncated:u.data.length>=i.maxComments,totalComments:u.data.length,commits:v,commitsTruncated:s.data.length>=i.maxCommits,totalCommits:s.data.length,files:y,filesTruncated:c.data.length>=i.maxFiles,totalFiles:c.data.length,reviews:b,reviewsTruncated:l.data.length>=i.maxReviews,totalReviews:l.data.length,authorAssociation:f.author_association,requestedReviewers:C,requestedReviewerTeams:w}}catch(e){return a.warning(`REST pull request fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function Be(e,t,n,r,i,a){try{return await e.graphql(` +`)}function Ie(e){return e.type===`issue`?Pe(e):Fe(e)}async function Le(e,t,n,r,i,a){try{let[a,o]=await Promise.all([e.rest.issues.get({owner:t,repo:n,issue_number:r}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),s=a.data,c=je(s.body??``,i.maxBodyBytes),l=o.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),u=(s.labels??[]).filter(e=>typeof e==`object`&&!!e&&`name`in e).map(e=>({name:e.name??``,color:e.color})),d=(s.assignees??[]).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.user?.login??null,createdAt:s.created_at,labels:u,assignees:d,comments:l,commentsTruncated:o.data.length>=i.maxComments,totalComments:o.data.length}}catch(e){return a.warning(`REST issue fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function Re(e,t,n,r,i,a){try{let[o,s,c,l,u]=await Promise.all([e.rest.pulls.get({owner:t,repo:n,pull_number:r}),e.rest.pulls.listCommits({owner:t,repo:n,pull_number:r,per_page:i.maxCommits}),e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:i.maxFiles}),e.rest.pulls.listReviews({owner:t,repo:n,pull_number:r,per_page:i.maxReviews}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),d=await e.rest.pulls.listRequestedReviewers({owner:t,repo:n,pull_number:r}).catch(e=>(a.warning(`Failed to fetch requested reviewers, defaulting to empty`,{owner:t,repo:n,number:r,error:M(e)}),{data:{users:[],teams:[]}})),f=o.data,p=je(f.body??``,i.maxBodyBytes),m=f.base.repo?.owner.login,h=f.head.repo?.owner.login,g=h==null||m!==h,_=u.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),v=s.data.slice(0,i.maxCommits).map(e=>({oid:e.sha,message:e.commit.message,author:e.commit.author?.name??null})),y=c.data.slice(0,i.maxFiles).map(e=>({path:e.filename,additions:e.additions,deletions:e.deletions,status:e.status})),b=l.data.slice(0,i.maxReviews).map(e=>({author:e.user?.login??null,state:e.state,body:e.body??``,createdAt:e.submitted_at??``,comments:[]})),x=(f.labels??[]).map(e=>({name:e.name??``,color:e.color})),S=(f.assignees??[]).map(e=>({login:e?.login??``})),C=(d.data.users??[]).map(e=>e.login),w=(d.data.teams??[]).map(e=>e.name);return{type:`pull_request`,number:f.number,title:f.title,body:p.text,bodyTruncated:p.truncated,state:f.state,author:f.user?.login??null,createdAt:f.created_at,baseBranch:f.base.ref,headBranch:f.head.ref,isFork:g,labels:x,assignees:S,comments:_,commentsTruncated:u.data.length>=i.maxComments,totalComments:u.data.length,commits:v,commitsTruncated:s.data.length>=i.maxCommits,totalCommits:s.data.length,files:y,filesTruncated:c.data.length>=i.maxFiles,totalFiles:c.data.length,reviews:b,reviewsTruncated:l.data.length>=i.maxReviews,totalReviews:l.data.length,authorAssociation:f.author_association,requestedReviewers:C,requestedReviewerTeams:w}}catch(e){return a.warning(`REST pull request fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function ze(e,t,n,r,i,a){try{return await e.graphql(` query GetIssue($owner: String!, $repo: String!, $number: Int!, $maxComments: Int!) { repository(owner: $owner, name: $repo) { issue(number: $number) { @@ -31,7 +31,7 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a } } } -`,{owner:t,repo:n,number:r,maxComments:i})}catch(e){return a.warning(`GraphQL issue query failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function Ve(e,t,n,r,i,a,o,s,c){try{return await e.graphql(` +`,{owner:t,repo:n,number:r,maxComments:i})}catch(e){return a.warning(`GraphQL issue query failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function Be(e,t,n,r,i,a,o,s,c){try{return await e.graphql(` query GetPullRequest( $owner: String!, $repo: String!, @@ -119,15 +119,15 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a } } } -`,{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:M(e)}),null}}async function He(e,t,n,r,i,a){let o=await Be(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=Me(s.body??``,i.maxBodyBytes),l=s.comments.nodes.slice(0,i.maxComments),u=s.comments.totalCount>l.length,d=l.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),f=s.labels.nodes.map(e=>({name:e.name,color:e.color})),p=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:f,assignees:p,comments:d,commentsTruncated:u,totalComments:s.comments.totalCount}}async function Ue(e,t,n,r,i,a){let o=await Ve(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=Me(s.body??``,i.maxBodyBytes),l=s.baseRepository?.owner.login,u=s.headRepository?.owner.login,d=u==null||l!==u,f=s.comments.nodes.slice(0,i.maxComments),p=s.comments.totalCount>f.length,m=f.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),h=s.commits.nodes.slice(0,i.maxCommits),g=s.commits.totalCount>h.length,_=h.map(e=>({oid:e.commit.oid,message:e.commit.message,author:e.commit.author?.name??null})),v=s.files.nodes.slice(0,i.maxFiles),y=s.files.totalCount>v.length,b=v.map(e=>({path:e.path,additions:e.additions,deletions:e.deletions})),x=s.reviews.nodes.slice(0,i.maxReviews),S=s.reviews.totalCount>x.length,C=x.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}))})),w=s.labels.nodes.map(e=>({name:e.name,color:e.color})),T=s.assignees.nodes.map(e=>({login:e.login})),E=s.reviewRequests.nodes.map(e=>`login`in e.requestedReviewer?e.requestedReviewer.login:null).filter(e=>e!=null),ee=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:w,assignees:T,comments:m,commentsTruncated:p,totalComments:s.comments.totalCount,commits:_,commitsTruncated:g,totalCommits:s.commits.totalCount,files:b,filesTruncated:y,totalFiles:s.files.totalCount,reviews:C,reviewsTruncated:S,totalReviews:s.reviews.totalCount,authorAssociation:s.authorAssociation,requestedReviewers:E,requestedReviewerTeams:ee}}function G(e){let[t,n]=e.split(`/`);if(t==null||n==null||t.length===0||n.length===0)throw Error(`Invalid repository string: ${e}`);return{owner:t,repo:n}}async function We(e,t,n,r,i){try{let{owner:a,repo:o}=G(t),{data:s}=await e.rest.reactions.createForIssueComment({owner:a,repo:o,comment_id:n,content:r});return i.debug(`Created comment reaction`,{commentId:n,content:r,reactionId:s.id}),{id:s.id}}catch(e){return i.warning(`Failed to create comment reaction`,{commentId:n,content:r,error:M(e)}),null}}async function Ge(e,t,n,r){try{let{owner:r,repo:i}=G(t),{data:a}=await e.rest.reactions.listForIssueComment({owner:r,repo:i,comment_id:n,per_page:100});return a.map(e=>({id:e.id,content:e.content,userLogin:e.user?.login??null}))}catch(e){return r.warning(`Failed to list comment reactions`,{commentId:n,error:M(e)}),[]}}async function Ke(e,t,n,r,i){try{let{owner:a,repo:o}=G(t);return await e.rest.reactions.deleteForIssueComment({owner:a,repo:o,comment_id:n,reaction_id:r}),i.debug(`Deleted comment reaction`,{commentId:n,reactionId:r}),!0}catch(e){return i.warning(`Failed to delete comment reaction`,{commentId:n,reactionId:r,error:M(e)}),!1}}async function qe(e,t,n,r,i,a){let{owner:o,repo:s}=G(t);try{return await e.rest.issues.createLabel({owner:o,repo:s,name:n,color:r,description:i}),a.debug(`Created label`,{name:n,color:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===422?(a.debug(`Label already exists`,{name:n}),!0):(a.warning(`Failed to create label`,{name:n,error:M(e)}),!1)}}async function Je(e,t,n,r,i){try{let{owner:a,repo:o}=G(t);return await e.rest.issues.addLabels({owner:a,repo:o,issue_number:n,labels:[...r]}),i.debug(`Added labels to issue`,{issueNumber:n,labels:r}),!0}catch(e){return i.warning(`Failed to add labels to issue`,{issueNumber:n,labels:r,error:M(e)}),!1}}async function Ye(e,t,n,r,i){try{let{owner:a,repo:o}=G(t);return await e.rest.issues.removeLabel({owner:a,repo:o,issue_number:n,name:r}),i.debug(`Removed label from issue`,{issueNumber:n,label:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===404?(i.debug(`Label was not present on issue`,{issueNumber:n,label:r}),!0):(i.warning(`Failed to remove label from issue`,{issueNumber:n,label:r,error:M(e)}),!1)}}async function Xe(e,t,n){try{let{owner:n,repo:r}=G(t),{data:i}=await e.rest.repos.get({owner:n,repo:r});return i.default_branch}catch(e){return n.warning(`Failed to get default branch`,{repo:t,error:M(e)}),`main`}}async function Ze(e,t,n){try{let{data:n}=await e.rest.users.getByUsername({username:t});return{id:n.id,login:n.login}}catch(e){return n.debug(`Failed to get user by username`,{username:t,error:M(e)}),null}}const Qe={PER_PAGE:100,MAX_PAGES:50};async function $e(e,t,n,r,i){i.debug(`Fetching PR diff`,{prNumber:r});let a=[],o=1,s=!1;for(;o<=Qe.MAX_PAGES;){let{data:c}=await e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:Qe.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.lengthQe.MAX_PAGES&&(s=!0,i.warning(`PR diff pagination limit reached`,{filesLoaded:a.length,maxPages:Qe.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}}async function et(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 $e(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:M(e)}),null}}async function tt(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?.number??null,g=l?.title??null,_=u?.login??null,v=await et(r,n,p,t),y=await nt(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):!1;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 Xe(n,p,t),diffContext:v,hydratedContext:y,authorAssociation:x,isRequestedReviewer:S}}async function nt(e,t,n,r,i,a){if(r==null||i==null)return null;let o=Ae;return i===`issue`?await He(e,t,n,r,o,a)??Re(e,t,n,r,o,a):await Ue(e,t,n,r,o,a)??ze(e,t,n,r,o,a)}const rt=({onSseError:e,onSseEvent:t,responseTransformer:n,responseValidator:r,sseDefaultRetryDelay:i,sseMaxRetryAttempts:a,sseMaxRetryDelay:o,sseSleepFn:s,url:c,...l})=>{let u,d=s??(e=>new Promise(t=>setTimeout(t,e)));return{stream:async function*(){let s=i??3e3,f=0,p=l.signal??new AbortController().signal;for(;!p.aborted;){f++;let i=l.headers instanceof Headers?l.headers:new Headers(l.headers);u!==void 0&&i.set(`Last-Event-ID`,u);try{let e=await fetch(c,{...l,headers:i,signal:p});if(!e.ok)throw Error(`SSE failed: ${e.status} ${e.statusText}`);if(!e.body)throw Error(`No body in SSE response`);let a=e.body.pipeThrough(new TextDecoderStream).getReader(),o=``,d=()=>{try{a.cancel()}catch{}};p.addEventListener(`abort`,d);try{for(;;){let{done:e,value:i}=await a.read();if(e)break;o+=i;let c=o.split(` +`,{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:M(e)}),null}}async function Ve(e,t,n,r,i,a){let o=await ze(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=je(s.body??``,i.maxBodyBytes),l=s.comments.nodes.slice(0,i.maxComments),u=s.comments.totalCount>l.length,d=l.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),f=s.labels.nodes.map(e=>({name:e.name,color:e.color})),p=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:f,assignees:p,comments:d,commentsTruncated:u,totalComments:s.comments.totalCount}}async function He(e,t,n,r,i,a){let o=await Be(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=je(s.body??``,i.maxBodyBytes),l=s.baseRepository?.owner.login,u=s.headRepository?.owner.login,d=u==null||l!==u,f=s.comments.nodes.slice(0,i.maxComments),p=s.comments.totalCount>f.length,m=f.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),h=s.commits.nodes.slice(0,i.maxCommits),g=s.commits.totalCount>h.length,_=h.map(e=>({oid:e.commit.oid,message:e.commit.message,author:e.commit.author?.name??null})),v=s.files.nodes.slice(0,i.maxFiles),y=s.files.totalCount>v.length,b=v.map(e=>({path:e.path,additions:e.additions,deletions:e.deletions})),x=s.reviews.nodes.slice(0,i.maxReviews),S=s.reviews.totalCount>x.length,C=x.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}))})),w=s.labels.nodes.map(e=>({name:e.name,color:e.color})),T=s.assignees.nodes.map(e=>({login:e.login})),E=s.reviewRequests.nodes.map(e=>`login`in e.requestedReviewer?e.requestedReviewer.login:null).filter(e=>e!=null),ee=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:w,assignees:T,comments:m,commentsTruncated:p,totalComments:s.comments.totalCount,commits:_,commitsTruncated:g,totalCommits:s.commits.totalCount,files:b,filesTruncated:y,totalFiles:s.files.totalCount,reviews:C,reviewsTruncated:S,totalReviews:s.reviews.totalCount,authorAssociation:s.authorAssociation,requestedReviewers:E,requestedReviewerTeams:ee}}function K(e){let[t,n]=e.split(`/`);if(t==null||n==null||t.length===0||n.length===0)throw Error(`Invalid repository string: ${e}`);return{owner:t,repo:n}}async function Ue(e,t,n,r,i){try{let{owner:a,repo:o}=K(t),{data:s}=await e.rest.reactions.createForIssueComment({owner:a,repo:o,comment_id:n,content:r});return i.debug(`Created comment reaction`,{commentId:n,content:r,reactionId:s.id}),{id:s.id}}catch(e){return i.warning(`Failed to create comment reaction`,{commentId:n,content:r,error:M(e)}),null}}async function We(e,t,n,r){try{let{owner:r,repo:i}=K(t),{data:a}=await e.rest.reactions.listForIssueComment({owner:r,repo:i,comment_id:n,per_page:100});return a.map(e=>({id:e.id,content:e.content,userLogin:e.user?.login??null}))}catch(e){return r.warning(`Failed to list comment reactions`,{commentId:n,error:M(e)}),[]}}async function Ge(e,t,n,r,i){try{let{owner:a,repo:o}=K(t);return await e.rest.reactions.deleteForIssueComment({owner:a,repo:o,comment_id:n,reaction_id:r}),i.debug(`Deleted comment reaction`,{commentId:n,reactionId:r}),!0}catch(e){return i.warning(`Failed to delete comment reaction`,{commentId:n,reactionId:r,error:M(e)}),!1}}async function Ke(e,t,n,r,i,a){let{owner:o,repo:s}=K(t);try{return await e.rest.issues.createLabel({owner:o,repo:s,name:n,color:r,description:i}),a.debug(`Created label`,{name:n,color:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===422?(a.debug(`Label already exists`,{name:n}),!0):(a.warning(`Failed to create label`,{name:n,error:M(e)}),!1)}}async function qe(e,t,n,r,i){try{let{owner:a,repo:o}=K(t);return await e.rest.issues.addLabels({owner:a,repo:o,issue_number:n,labels:[...r]}),i.debug(`Added labels to issue`,{issueNumber:n,labels:r}),!0}catch(e){return i.warning(`Failed to add labels to issue`,{issueNumber:n,labels:r,error:M(e)}),!1}}async function Je(e,t,n,r,i){try{let{owner:a,repo:o}=K(t);return await e.rest.issues.removeLabel({owner:a,repo:o,issue_number:n,name:r}),i.debug(`Removed label from issue`,{issueNumber:n,label:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===404?(i.debug(`Label was not present on issue`,{issueNumber:n,label:r}),!0):(i.warning(`Failed to remove label from issue`,{issueNumber:n,label:r,error:M(e)}),!1)}}async function Ye(e,t,n){try{let{owner:n,repo:r}=K(t),{data:i}=await e.rest.repos.get({owner:n,repo:r});return i.default_branch}catch(e){return n.warning(`Failed to get default branch`,{repo:t,error:M(e)}),`main`}}async function Xe(e,t,n){try{let{data:n}=await e.rest.users.getByUsername({username:t});return{id:n.id,login:n.login}}catch(e){return n.debug(`Failed to get user by username`,{username:t,error:M(e)}),null}}const Ze={PER_PAGE:100,MAX_PAGES:50};async function Qe(e,t,n,r,i){i.debug(`Fetching PR diff`,{prNumber:r});let a=[],o=1,s=!1;for(;o<=Ze.MAX_PAGES;){let{data:c}=await e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:Ze.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.lengthZe.MAX_PAGES&&(s=!0,i.warning(`PR diff pagination limit reached`,{filesLoaded:a.length,maxPages:Ze.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}}async function $e(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 Qe(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:M(e)}),null}}async function et(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?.number??null,g=l?.title??null,_=u?.login??null,v=await $e(r,n,p,t),y=await tt(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):!1;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 Ye(n,p,t),diffContext:v,hydratedContext:y,authorAssociation:x,isRequestedReviewer:S}}async function tt(e,t,n,r,i,a){if(r==null||i==null)return null;let o=ke;return i===`issue`?await Ve(e,t,n,r,o,a)??Le(e,t,n,r,o,a):await He(e,t,n,r,o,a)??Re(e,t,n,r,o,a)}const nt=({onSseError:e,onSseEvent:t,responseTransformer:n,responseValidator:r,sseDefaultRetryDelay:i,sseMaxRetryAttempts:a,sseMaxRetryDelay:o,sseSleepFn:s,url:c,...l})=>{let u,d=s??(e=>new Promise(t=>setTimeout(t,e)));return{stream:async function*(){let s=i??3e3,f=0,p=l.signal??new AbortController().signal;for(;!p.aborted;){f++;let i=l.headers instanceof Headers?l.headers:new Headers(l.headers);u!==void 0&&i.set(`Last-Event-ID`,u);try{let e=await fetch(c,{...l,headers:i,signal:p});if(!e.ok)throw Error(`SSE failed: ${e.status} ${e.statusText}`);if(!e.body)throw Error(`No body in SSE response`);let a=e.body.pipeThrough(new TextDecoderStream).getReader(),o=``,d=()=>{try{a.cancel()}catch{}};p.addEventListener(`abort`,d);try{for(;;){let{done:e,value:i}=await a.read();if(e)break;o+=i;let c=o.split(` `);o=c.pop()??``;for(let e of c){let i=e.split(` `),a=[],o;for(let e of i)if(e.startsWith(`data:`))a.push(e.replace(/^data:\s*/,``));else if(e.startsWith(`event:`))o=e.replace(/^event:\s*/,``);else if(e.startsWith(`id:`))u=e.replace(/^id:\s*/,``);else if(e.startsWith(`retry:`)){let t=Number.parseInt(e.replace(/^retry:\s*/,``),10);Number.isNaN(t)||(s=t)}let c,l=!1;if(a.length){let e=a.join(` -`);try{c=JSON.parse(e),l=!0}catch{c=e}}l&&(r&&await r(c),n&&(c=await n(c))),t?.({data:c,event:o,id:u,retry:s}),a.length&&(yield c)}}}finally{p.removeEventListener(`abort`,d),a.releaseLock()}break}catch(t){if(e?.(t),a!==void 0&&f>=a)break;await d(Math.min(s*2**(f-1),o??3e4))}}}()}},it=async(e,t)=>{let n=typeof t==`function`?await t(e):t;if(n)return e.scheme===`bearer`?`Bearer ${n}`:e.scheme===`basic`?`Basic ${btoa(n)}`:n},at={bodySerializer:e=>JSON.stringify(e,(e,t)=>typeof t==`bigint`?t.toString():t)},ot=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},st=e=>{switch(e){case`form`:return`,`;case`pipeDelimited`:return`|`;case`spaceDelimited`:return`%20`;default:return`,`}},ct=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},lt=({allowReserved:e,explode:t,name:n,style:r,value:i})=>{if(!t){let t=(e?i:i.map(e=>encodeURIComponent(e))).join(st(r));switch(r){case`label`:return`.${t}`;case`matrix`:return`;${n}=${t}`;case`simple`:return t;default:return`${n}=${t}`}}let a=ot(r),o=i.map(t=>r===`label`||r===`simple`?e?t:encodeURIComponent(t):ut({allowReserved:e,name:n,value:t})).join(a);return r===`label`||r===`matrix`?a+o:o},ut=({allowReserved:e,name:t,value:n})=>{if(n==null)return``;if(typeof n==`object`)throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${t}=${e?n:encodeURIComponent(n)}`},dt=({allowReserved:e,explode:t,name:n,style:r,value:i,valueOnly:a})=>{if(i instanceof Date)return a?i.toISOString():`${n}=${i.toISOString()}`;if(r!==`deepObject`&&!t){let t=[];Object.entries(i).forEach(([n,r])=>{t=[...t,n,e?r:encodeURIComponent(r)]});let a=t.join(`,`);switch(r){case`form`:return`${n}=${a}`;case`label`:return`.${a}`;case`matrix`:return`;${n}=${a}`;default:return a}}let o=ct(r),s=Object.entries(i).map(([t,i])=>ut({allowReserved:e,name:r===`deepObject`?`${n}[${t}]`:t,value:i})).join(o);return r===`label`||r===`matrix`?o+s:s},ft=/\{[^{}]+\}/g,pt=({path:e,url:t})=>{let n=t,r=t.match(ft);if(r)for(let t of r){let r=!1,i=t.substring(1,t.length-1),a=`simple`;i.endsWith(`*`)&&(r=!0,i=i.substring(0,i.length-1)),i.startsWith(`.`)?(i=i.substring(1),a=`label`):i.startsWith(`;`)&&(i=i.substring(1),a=`matrix`);let o=e[i];if(o==null)continue;if(Array.isArray(o)){n=n.replace(t,lt({explode:r,name:i,style:a,value:o}));continue}if(typeof o==`object`){n=n.replace(t,dt({explode:r,name:i,style:a,value:o,valueOnly:!0}));continue}if(a===`matrix`){n=n.replace(t,`;${ut({name:i,value:o})}`);continue}let s=encodeURIComponent(a===`label`?`.${o}`:o);n=n.replace(t,s)}return n},mt=({baseUrl:e,path:t,query:n,querySerializer:r,url:i})=>{let a=i.startsWith(`/`)?i:`/${i}`,o=(e??``)+a;t&&(o=pt({path:t,url:o}));let s=n?r(n):``;return s.startsWith(`?`)&&(s=s.substring(1)),s&&(o+=`?${s}`),o},ht=({allowReserved:e,array:t,object:n}={})=>r=>{let i=[];if(r&&typeof r==`object`)for(let a in r){let o=r[a];if(o!=null)if(Array.isArray(o)){let n=lt({allowReserved:e,explode:!0,name:a,style:`form`,value:o,...t});n&&i.push(n)}else if(typeof o==`object`){let t=dt({allowReserved:e,explode:!0,name:a,style:`deepObject`,value:o,...n});t&&i.push(t)}else{let t=ut({allowReserved:e,name:a,value:o});t&&i.push(t)}}return i.join(`&`)},gt=e=>{if(!e)return`stream`;let t=e.split(`;`)[0]?.trim();if(t){if(t.startsWith(`application/json`)||t.endsWith(`+json`))return`json`;if(t===`multipart/form-data`)return`formData`;if([`application/`,`audio/`,`image/`,`video/`].some(e=>t.startsWith(e)))return`blob`;if(t.startsWith(`text/`))return`text`}},_t=(e,t)=>t?!!(e.headers.has(t)||e.query?.[t]||e.headers.get(`Cookie`)?.includes(`${t}=`)):!1,vt=async({security:e,...t})=>{for(let n of e){if(_t(t,n.name))continue;let e=await it(n,t.auth);if(!e)continue;let r=n.name??`Authorization`;switch(n.in){case`query`:t.query||={},t.query[r]=e;break;case`cookie`:t.headers.append(`Cookie`,`${r}=${e}`);break;default:t.headers.set(r,e);break}}},yt=e=>mt({baseUrl:e.baseUrl,path:e.path,query:e.query,querySerializer:typeof e.querySerializer==`function`?e.querySerializer:ht(e.querySerializer),url:e.url}),bt=(e,t)=>{let n={...e,...t};return n.baseUrl?.endsWith(`/`)&&(n.baseUrl=n.baseUrl.substring(0,n.baseUrl.length-1)),n.headers=xt(e.headers,t.headers),n},xt=(...e)=>{let t=new Headers;for(let n of e){if(!n||typeof n!=`object`)continue;let e=n instanceof Headers?n.entries():Object.entries(n);for(let[n,r]of e)if(r===null)t.delete(n);else if(Array.isArray(r))for(let e of r)t.append(n,e);else r!==void 0&&t.set(n,typeof r==`object`?JSON.stringify(r):r)}return t};var St=class{_fns;constructor(){this._fns=[]}clear(){this._fns=[]}getInterceptorIndex(e){return typeof e==`number`?this._fns[e]?e:-1:this._fns.indexOf(e)}exists(e){let t=this.getInterceptorIndex(e);return!!this._fns[t]}eject(e){let t=this.getInterceptorIndex(e);this._fns[t]&&(this._fns[t]=null)}update(e,t){let n=this.getInterceptorIndex(e);return this._fns[n]?(this._fns[n]=t,e):!1}use(e){return this._fns=[...this._fns,e],this._fns.length-1}};const Ct=()=>({error:new St,request:new St,response:new St}),wt=ht({allowReserved:!1,array:{explode:!0,style:`form`},object:{explode:!0,style:`deepObject`}}),Tt={"Content-Type":`application/json`},Et=(e={})=>({...at,headers:Tt,parseAs:`auto`,querySerializer:wt,...e}),Dt=(e={})=>{let t=bt(Et(),e),n=()=>({...t}),r=e=>(t=bt(t,e),n()),i=Ct(),a=async e=>{let n={...t,...e,fetch:e.fetch??t.fetch??globalThis.fetch,headers:xt(t.headers,e.headers),serializedBody:void 0};return n.security&&await vt({...n,security:n.security}),n.requestValidator&&await n.requestValidator(n),n.body&&n.bodySerializer&&(n.serializedBody=n.bodySerializer(n.body)),(n.serializedBody===void 0||n.serializedBody===``)&&n.headers.delete(`Content-Type`),{opts:n,url:yt(n)}},o=async e=>{let{opts:t,url:n}=await a(e),r={redirect:`follow`,...t,body:t.serializedBody},o=new Request(n,r);for(let e of i.request._fns)e&&(o=await e(o,t));let s=t.fetch,c=await s(o);for(let e of i.response._fns)e&&(c=await e(c,o,t));let l={request:o,response:c};if(c.ok){if(c.status===204||c.headers.get(`Content-Length`)===`0`)return t.responseStyle===`data`?{}:{data:{},...l};let e=(t.parseAs===`auto`?gt(c.headers.get(`Content-Type`)):t.parseAs)??`json`,n;switch(e){case`arrayBuffer`:case`blob`:case`formData`:case`json`:case`text`:n=await c[e]();break;case`stream`:return t.responseStyle===`data`?c.body:{data:c.body,...l}}return e===`json`&&(t.responseValidator&&await t.responseValidator(n),t.responseTransformer&&(n=await t.responseTransformer(n))),t.responseStyle===`data`?n:{data:n,...l}}let u=await c.text(),d;try{d=JSON.parse(u)}catch{}let f=d??u,p=f;for(let e of i.error._fns)e&&(p=await e(f,c,o,t));if(p||={},t.throwOnError)throw p;return t.responseStyle===`data`?void 0:{error:p,...l}},s=e=>{let t=t=>o({...t,method:e});return t.sse=async t=>{let{opts:n,url:r}=await a(t);return rt({...n,body:n.body,headers:n.headers,method:e,url:r})},t};return{buildUrl:yt,connect:s(`CONNECT`),delete:s(`DELETE`),get:s(`GET`),getConfig:n,head:s(`HEAD`),interceptors:i,options:s(`OPTIONS`),patch:s(`PATCH`),post:s(`POST`),put:s(`PUT`),request:o,setConfig:r,trace:s(`TRACE`)}};Object.entries({$body_:`body`,$headers_:`headers`,$path_:`path`,$query_:`query`});const Ot=Dt(Et({baseUrl:`http://localhost:4096`}));var K=class{_client=Ot;constructor(e){e?.client&&(this._client=e.client)}},kt=class extends K{event(e){return(e?.client??this._client).get.sse({url:`/global/event`,...e})}},At=class extends K{list(e){return(e?.client??this._client).get({url:`/project`,...e})}current(e){return(e?.client??this._client).get({url:`/project/current`,...e})}},jt=class extends K{list(e){return(e?.client??this._client).get({url:`/pty`,...e})}create(e){return(e?.client??this._client).post({url:`/pty`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}remove(e){return(e.client??this._client).delete({url:`/pty/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/pty/{id}`,...e})}update(e){return(e.client??this._client).put({url:`/pty/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}connect(e){return(e.client??this._client).get({url:`/pty/{id}/connect`,...e})}},Mt=class extends K{get(e){return(e?.client??this._client).get({url:`/config`,...e})}update(e){return(e?.client??this._client).patch({url:`/config`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}providers(e){return(e?.client??this._client).get({url:`/config/providers`,...e})}},Nt=class extends K{ids(e){return(e?.client??this._client).get({url:`/experimental/tool/ids`,...e})}list(e){return(e.client??this._client).get({url:`/experimental/tool`,...e})}},Pt=class extends K{dispose(e){return(e?.client??this._client).post({url:`/instance/dispose`,...e})}},Ft=class extends K{get(e){return(e?.client??this._client).get({url:`/path`,...e})}},It=class extends K{get(e){return(e?.client??this._client).get({url:`/vcs`,...e})}},Lt=class extends K{list(e){return(e?.client??this._client).get({url:`/session`,...e})}create(e){return(e?.client??this._client).post({url:`/session`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}status(e){return(e?.client??this._client).get({url:`/session/status`,...e})}delete(e){return(e.client??this._client).delete({url:`/session/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/session/{id}`,...e})}update(e){return(e.client??this._client).patch({url:`/session/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}children(e){return(e.client??this._client).get({url:`/session/{id}/children`,...e})}todo(e){return(e.client??this._client).get({url:`/session/{id}/todo`,...e})}init(e){return(e.client??this._client).post({url:`/session/{id}/init`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}fork(e){return(e.client??this._client).post({url:`/session/{id}/fork`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}abort(e){return(e.client??this._client).post({url:`/session/{id}/abort`,...e})}unshare(e){return(e.client??this._client).delete({url:`/session/{id}/share`,...e})}share(e){return(e.client??this._client).post({url:`/session/{id}/share`,...e})}diff(e){return(e.client??this._client).get({url:`/session/{id}/diff`,...e})}summarize(e){return(e.client??this._client).post({url:`/session/{id}/summarize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}messages(e){return(e.client??this._client).get({url:`/session/{id}/message`,...e})}prompt(e){return(e.client??this._client).post({url:`/session/{id}/message`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}message(e){return(e.client??this._client).get({url:`/session/{id}/message/{messageID}`,...e})}promptAsync(e){return(e.client??this._client).post({url:`/session/{id}/prompt_async`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}command(e){return(e.client??this._client).post({url:`/session/{id}/command`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}shell(e){return(e.client??this._client).post({url:`/session/{id}/shell`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}revert(e){return(e.client??this._client).post({url:`/session/{id}/revert`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}unrevert(e){return(e.client??this._client).post({url:`/session/{id}/unrevert`,...e})}},Rt=class extends K{list(e){return(e?.client??this._client).get({url:`/command`,...e})}},zt=class extends K{authorize(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/authorize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}callback(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Bt=class extends K{list(e){return(e?.client??this._client).get({url:`/provider`,...e})}auth(e){return(e?.client??this._client).get({url:`/provider/auth`,...e})}oauth=new zt({client:this._client})},Vt=class extends K{text(e){return(e.client??this._client).get({url:`/find`,...e})}files(e){return(e.client??this._client).get({url:`/find/file`,...e})}symbols(e){return(e.client??this._client).get({url:`/find/symbol`,...e})}},Ht=class extends K{list(e){return(e.client??this._client).get({url:`/file`,...e})}read(e){return(e.client??this._client).get({url:`/file/content`,...e})}status(e){return(e?.client??this._client).get({url:`/file/status`,...e})}},Ut=class extends K{log(e){return(e?.client??this._client).post({url:`/log`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}agents(e){return(e?.client??this._client).get({url:`/agent`,...e})}},Wt=class extends K{remove(e){return(e.client??this._client).delete({url:`/mcp/{name}/auth`,...e})}start(e){return(e.client??this._client).post({url:`/mcp/{name}/auth`,...e})}callback(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}authenticate(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/authenticate`,...e})}set(e){return(e.client??this._client).put({url:`/auth/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Gt=class extends K{status(e){return(e?.client??this._client).get({url:`/mcp`,...e})}add(e){return(e?.client??this._client).post({url:`/mcp`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}connect(e){return(e.client??this._client).post({url:`/mcp/{name}/connect`,...e})}disconnect(e){return(e.client??this._client).post({url:`/mcp/{name}/disconnect`,...e})}auth=new Wt({client:this._client})},Kt=class extends K{status(e){return(e?.client??this._client).get({url:`/lsp`,...e})}},qt=class extends K{status(e){return(e?.client??this._client).get({url:`/formatter`,...e})}},Jt=class extends K{next(e){return(e?.client??this._client).get({url:`/tui/control/next`,...e})}response(e){return(e?.client??this._client).post({url:`/tui/control/response`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}},Yt=class extends K{appendPrompt(e){return(e?.client??this._client).post({url:`/tui/append-prompt`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}openHelp(e){return(e?.client??this._client).post({url:`/tui/open-help`,...e})}openSessions(e){return(e?.client??this._client).post({url:`/tui/open-sessions`,...e})}openThemes(e){return(e?.client??this._client).post({url:`/tui/open-themes`,...e})}openModels(e){return(e?.client??this._client).post({url:`/tui/open-models`,...e})}submitPrompt(e){return(e?.client??this._client).post({url:`/tui/submit-prompt`,...e})}clearPrompt(e){return(e?.client??this._client).post({url:`/tui/clear-prompt`,...e})}executeCommand(e){return(e?.client??this._client).post({url:`/tui/execute-command`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}showToast(e){return(e?.client??this._client).post({url:`/tui/show-toast`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}publish(e){return(e?.client??this._client).post({url:`/tui/publish`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}control=new Jt({client:this._client})},Xt=class extends K{subscribe(e){return(e?.client??this._client).get.sse({url:`/event`,...e})}},Zt=class extends K{postSessionIdPermissionsPermissionId(e){return(e.client??this._client).post({url:`/session/{id}/permissions/{permissionID}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}global=new kt({client:this._client});project=new At({client:this._client});pty=new jt({client:this._client});config=new Mt({client:this._client});tool=new Nt({client:this._client});instance=new Pt({client:this._client});path=new Ft({client:this._client});vcs=new It({client:this._client});session=new Lt({client:this._client});command=new Rt({client:this._client});provider=new Bt({client:this._client});find=new Vt({client:this._client});file=new Ht({client:this._client});app=new Ut({client:this._client});mcp=new Gt({client:this._client});lsp=new Kt({client:this._client});formatter=new qt({client:this._client});tui=new Yt({client:this._client});auth=new Wt({client:this._client});event=new Xt({client:this._client})};function Qt(e){if(!e?.fetch){let t=e=>(e.timeout=!1,fetch(e));e={...e,fetch:t}}return e?.directory&&(e.headers={...e.headers,"x-opencode-directory":encodeURIComponent(e.directory)}),new Zt({client:Dt(e)})}async function $t(e){e=Object.assign({hostname:`127.0.0.1`,port:4096,timeout:5e3},e??{});let t=[`serve`,`--hostname=${e.hostname}`,`--port=${e.port}`];e.config?.logLevel&&t.push(`--log-level=${e.config.logLevel}`);let n=Te(`opencode`,t,{signal:e.signal,env:{...process.env,OPENCODE_CONFIG_CONTENT:JSON.stringify(e.config??{})}});return{url:await new Promise((t,r)=>{let i=setTimeout(()=>{r(Error(`Timeout waiting for server to start after ${e.timeout}ms`))},e.timeout),a=``;n.stdout?.on(`data`,e=>{a+=e.toString();let n=a.split(` -`);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function en(e){let t=await $t({...e});return{client:Qt({baseUrl:t.url}),server:t}}async function tn(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const nn={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},rn=`\x1B[0m`;function an(){return V.env.NO_COLOR==null}function on(e,t){let[n,r]=nn[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);an()?V.stdout.write(`\n${r}|${rn} ${i} ${rn}${t}\n`):V.stdout.write(`\n| ${i} ${t}\n`)}function sn(e){V.stdout.write(`\n${e}\n`)}const cn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function ln(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function un(e){let t=ln(e),n=cn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` -`)}function dn(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const fn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function pn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return fn.some(e=>e.test(t))}function mn(e,t){return dn(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function hn(e,t){return dn(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}function gn(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function _n(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 vn(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(gn)}function yn(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)]}var bn=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(_e(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(ve(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${he}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},xn=T((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),Sn=e(T((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[d.Accept]=this._getExistingOrDefaultHeader(t,d.Accept,f.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===u.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&m.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!h.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},x(this.requestOptions.headers),x(e||{})):x(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[d.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[d.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new l.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===u.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let x=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),Cn=w(),wn=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function Tn(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function En(e){return new Sn.HttpClient().getAgent(e)}function Dn(e){return new Sn.HttpClient().getAgentDispatcher(e)}function On(e){let t=Dn(e);return(e,n)=>wn(this,void 0,void 0,function*(){return(0,Cn.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function kn(){return process.env.GITHUB_API_URL||`https://api.github.com`}function An(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function jn(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>jn.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function Mn(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function Nn(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const Pn=Function.bind,Fn=Pn.bind(Pn);function In(e,t,n){let r=Fn(Nn,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=Fn(Mn,null).apply(null,i)})}function Ln(){let e=Symbol(`Singular`),t={registry:{}},n=jn.bind(null,t,e);return In(n,t,e),n}function Rn(){let e={registry:{}},t=jn.bind(null,e);return In(t,e),t}var zn={Singular:Ln,Collection:Rn},Bn=`octokit-endpoint.js/0.0.0-development ${An()}`,Vn={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":Bn},mediaType:{format:``}};function Hn(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Un(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Wn(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Un(t[r])&&r in e?n[r]=Wn(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Gn(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function Kn(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Hn(n.headers),Gn(n),Gn(n.headers);let r=Wn(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function qn(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var Jn=/\{[^{}}]+\}/g;function Yn(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Zn(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function Qn(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function q(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function $n(e,t,n){return t=e===`+`||e===`#`?Qn(t):q(t),n?q(n)+`=`+t:t}function er(e){return e!=null}function tr(e){return e===`;`||e===`&`||e===`?`}function nr(e,t,n,r){var i=e[n],a=[];if(er(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push($n(t,i,tr(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(er).forEach(function(e){a.push($n(t,e,tr(t)?n:``))}):Object.keys(i).forEach(function(e){er(i[e])&&a.push($n(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(er).forEach(function(n){e.push($n(t,n))}):Object.keys(i).forEach(function(n){er(i[n])&&(e.push(q(n)),e.push($n(t,i[n].toString())))}),tr(t)?a.push(q(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?er(i)&&a.push(q(n)):i===``&&(t===`&`||t===`?`)?a.push(q(n)+`=`):i===``&&a.push(``);return a}function rr(e){return{expand:ir.bind(null,e)}}function ir(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(nr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return Qn(i)}),e===`/`?e:e.replace(/\/$/,``)}function ar(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Zn(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Xn(n);n=rr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Zn(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=qn(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function or(e,t,n){return ar(Kn(e,t,n))}function sr(e,t){let n=Kn(e,t),r=or.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:sr.bind(null,n),merge:Kn.bind(null,n),parse:ar})}var cr=sr(null,Vn),lr=T(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))(),ur=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function hr(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=pr(e.body)||Array.isArray(e.body)?JSON.stringify(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new ur(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new ur(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await gr(o),new ur(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await gr(o),new ur(vr(u.data),s,{response:u,request:e});return u.data=r?await gr(o):o.body,u}async function gr(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(mr);let n=(0,lr.safeParse)(t);if(_r(n)){let t=``;try{return t=await e.text(),JSON.parse(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(mr);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function _r(e){return e.type===`application/json`||e.type===`application/scim+json`}function vr(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function yr(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return hr(n.parse(r));let i=(e,t)=>hr(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:yr.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:yr.bind(null,n)})}var br=yr(cr,fr),xr=`0.0.0-development`;function Sr(e){return`Request failed due to following response errors: +`);try{c=JSON.parse(e),l=!0}catch{c=e}}l&&(r&&await r(c),n&&(c=await n(c))),t?.({data:c,event:o,id:u,retry:s}),a.length&&(yield c)}}}finally{p.removeEventListener(`abort`,d),a.releaseLock()}break}catch(t){if(e?.(t),a!==void 0&&f>=a)break;await d(Math.min(s*2**(f-1),o??3e4))}}}()}},rt=async(e,t)=>{let n=typeof t==`function`?await t(e):t;if(n)return e.scheme===`bearer`?`Bearer ${n}`:e.scheme===`basic`?`Basic ${btoa(n)}`:n},it={bodySerializer:e=>JSON.stringify(e,(e,t)=>typeof t==`bigint`?t.toString():t)},at=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},ot=e=>{switch(e){case`form`:return`,`;case`pipeDelimited`:return`|`;case`spaceDelimited`:return`%20`;default:return`,`}},st=e=>{switch(e){case`label`:return`.`;case`matrix`:return`;`;case`simple`:return`,`;default:return`&`}},ct=({allowReserved:e,explode:t,name:n,style:r,value:i})=>{if(!t){let t=(e?i:i.map(e=>encodeURIComponent(e))).join(ot(r));switch(r){case`label`:return`.${t}`;case`matrix`:return`;${n}=${t}`;case`simple`:return t;default:return`${n}=${t}`}}let a=at(r),o=i.map(t=>r===`label`||r===`simple`?e?t:encodeURIComponent(t):lt({allowReserved:e,name:n,value:t})).join(a);return r===`label`||r===`matrix`?a+o:o},lt=({allowReserved:e,name:t,value:n})=>{if(n==null)return``;if(typeof n==`object`)throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${t}=${e?n:encodeURIComponent(n)}`},ut=({allowReserved:e,explode:t,name:n,style:r,value:i,valueOnly:a})=>{if(i instanceof Date)return a?i.toISOString():`${n}=${i.toISOString()}`;if(r!==`deepObject`&&!t){let t=[];Object.entries(i).forEach(([n,r])=>{t=[...t,n,e?r:encodeURIComponent(r)]});let a=t.join(`,`);switch(r){case`form`:return`${n}=${a}`;case`label`:return`.${a}`;case`matrix`:return`;${n}=${a}`;default:return a}}let o=st(r),s=Object.entries(i).map(([t,i])=>lt({allowReserved:e,name:r===`deepObject`?`${n}[${t}]`:t,value:i})).join(o);return r===`label`||r===`matrix`?o+s:s},dt=/\{[^{}]+\}/g,ft=({path:e,url:t})=>{let n=t,r=t.match(dt);if(r)for(let t of r){let r=!1,i=t.substring(1,t.length-1),a=`simple`;i.endsWith(`*`)&&(r=!0,i=i.substring(0,i.length-1)),i.startsWith(`.`)?(i=i.substring(1),a=`label`):i.startsWith(`;`)&&(i=i.substring(1),a=`matrix`);let o=e[i];if(o==null)continue;if(Array.isArray(o)){n=n.replace(t,ct({explode:r,name:i,style:a,value:o}));continue}if(typeof o==`object`){n=n.replace(t,ut({explode:r,name:i,style:a,value:o,valueOnly:!0}));continue}if(a===`matrix`){n=n.replace(t,`;${lt({name:i,value:o})}`);continue}let s=encodeURIComponent(a===`label`?`.${o}`:o);n=n.replace(t,s)}return n},pt=({baseUrl:e,path:t,query:n,querySerializer:r,url:i})=>{let a=i.startsWith(`/`)?i:`/${i}`,o=(e??``)+a;t&&(o=ft({path:t,url:o}));let s=n?r(n):``;return s.startsWith(`?`)&&(s=s.substring(1)),s&&(o+=`?${s}`),o},mt=({allowReserved:e,array:t,object:n}={})=>r=>{let i=[];if(r&&typeof r==`object`)for(let a in r){let o=r[a];if(o!=null)if(Array.isArray(o)){let n=ct({allowReserved:e,explode:!0,name:a,style:`form`,value:o,...t});n&&i.push(n)}else if(typeof o==`object`){let t=ut({allowReserved:e,explode:!0,name:a,style:`deepObject`,value:o,...n});t&&i.push(t)}else{let t=lt({allowReserved:e,name:a,value:o});t&&i.push(t)}}return i.join(`&`)},ht=e=>{if(!e)return`stream`;let t=e.split(`;`)[0]?.trim();if(t){if(t.startsWith(`application/json`)||t.endsWith(`+json`))return`json`;if(t===`multipart/form-data`)return`formData`;if([`application/`,`audio/`,`image/`,`video/`].some(e=>t.startsWith(e)))return`blob`;if(t.startsWith(`text/`))return`text`}},gt=(e,t)=>t?!!(e.headers.has(t)||e.query?.[t]||e.headers.get(`Cookie`)?.includes(`${t}=`)):!1,_t=async({security:e,...t})=>{for(let n of e){if(gt(t,n.name))continue;let e=await rt(n,t.auth);if(!e)continue;let r=n.name??`Authorization`;switch(n.in){case`query`:t.query||={},t.query[r]=e;break;case`cookie`:t.headers.append(`Cookie`,`${r}=${e}`);break;default:t.headers.set(r,e);break}}},vt=e=>pt({baseUrl:e.baseUrl,path:e.path,query:e.query,querySerializer:typeof e.querySerializer==`function`?e.querySerializer:mt(e.querySerializer),url:e.url}),yt=(e,t)=>{let n={...e,...t};return n.baseUrl?.endsWith(`/`)&&(n.baseUrl=n.baseUrl.substring(0,n.baseUrl.length-1)),n.headers=bt(e.headers,t.headers),n},bt=(...e)=>{let t=new Headers;for(let n of e){if(!n||typeof n!=`object`)continue;let e=n instanceof Headers?n.entries():Object.entries(n);for(let[n,r]of e)if(r===null)t.delete(n);else if(Array.isArray(r))for(let e of r)t.append(n,e);else r!==void 0&&t.set(n,typeof r==`object`?JSON.stringify(r):r)}return t};var xt=class{_fns;constructor(){this._fns=[]}clear(){this._fns=[]}getInterceptorIndex(e){return typeof e==`number`?this._fns[e]?e:-1:this._fns.indexOf(e)}exists(e){let t=this.getInterceptorIndex(e);return!!this._fns[t]}eject(e){let t=this.getInterceptorIndex(e);this._fns[t]&&(this._fns[t]=null)}update(e,t){let n=this.getInterceptorIndex(e);return this._fns[n]?(this._fns[n]=t,e):!1}use(e){return this._fns=[...this._fns,e],this._fns.length-1}};const St=()=>({error:new xt,request:new xt,response:new xt}),Ct=mt({allowReserved:!1,array:{explode:!0,style:`form`},object:{explode:!0,style:`deepObject`}}),wt={"Content-Type":`application/json`},Tt=(e={})=>({...it,headers:wt,parseAs:`auto`,querySerializer:Ct,...e}),Et=(e={})=>{let t=yt(Tt(),e),n=()=>({...t}),r=e=>(t=yt(t,e),n()),i=St(),a=async e=>{let n={...t,...e,fetch:e.fetch??t.fetch??globalThis.fetch,headers:bt(t.headers,e.headers),serializedBody:void 0};return n.security&&await _t({...n,security:n.security}),n.requestValidator&&await n.requestValidator(n),n.body&&n.bodySerializer&&(n.serializedBody=n.bodySerializer(n.body)),(n.serializedBody===void 0||n.serializedBody===``)&&n.headers.delete(`Content-Type`),{opts:n,url:vt(n)}},o=async e=>{let{opts:t,url:n}=await a(e),r={redirect:`follow`,...t,body:t.serializedBody},o=new Request(n,r);for(let e of i.request._fns)e&&(o=await e(o,t));let s=t.fetch,c=await s(o);for(let e of i.response._fns)e&&(c=await e(c,o,t));let l={request:o,response:c};if(c.ok){if(c.status===204||c.headers.get(`Content-Length`)===`0`)return t.responseStyle===`data`?{}:{data:{},...l};let e=(t.parseAs===`auto`?ht(c.headers.get(`Content-Type`)):t.parseAs)??`json`,n;switch(e){case`arrayBuffer`:case`blob`:case`formData`:case`json`:case`text`:n=await c[e]();break;case`stream`:return t.responseStyle===`data`?c.body:{data:c.body,...l}}return e===`json`&&(t.responseValidator&&await t.responseValidator(n),t.responseTransformer&&(n=await t.responseTransformer(n))),t.responseStyle===`data`?n:{data:n,...l}}let u=await c.text(),d;try{d=JSON.parse(u)}catch{}let f=d??u,p=f;for(let e of i.error._fns)e&&(p=await e(f,c,o,t));if(p||={},t.throwOnError)throw p;return t.responseStyle===`data`?void 0:{error:p,...l}},s=e=>{let t=t=>o({...t,method:e});return t.sse=async t=>{let{opts:n,url:r}=await a(t);return nt({...n,body:n.body,headers:n.headers,method:e,url:r})},t};return{buildUrl:vt,connect:s(`CONNECT`),delete:s(`DELETE`),get:s(`GET`),getConfig:n,head:s(`HEAD`),interceptors:i,options:s(`OPTIONS`),patch:s(`PATCH`),post:s(`POST`),put:s(`PUT`),request:o,setConfig:r,trace:s(`TRACE`)}};Object.entries({$body_:`body`,$headers_:`headers`,$path_:`path`,$query_:`query`});const Dt=Et(Tt({baseUrl:`http://localhost:4096`}));var q=class{_client=Dt;constructor(e){e?.client&&(this._client=e.client)}},Ot=class extends q{event(e){return(e?.client??this._client).get.sse({url:`/global/event`,...e})}},kt=class extends q{list(e){return(e?.client??this._client).get({url:`/project`,...e})}current(e){return(e?.client??this._client).get({url:`/project/current`,...e})}},At=class extends q{list(e){return(e?.client??this._client).get({url:`/pty`,...e})}create(e){return(e?.client??this._client).post({url:`/pty`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}remove(e){return(e.client??this._client).delete({url:`/pty/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/pty/{id}`,...e})}update(e){return(e.client??this._client).put({url:`/pty/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}connect(e){return(e.client??this._client).get({url:`/pty/{id}/connect`,...e})}},jt=class extends q{get(e){return(e?.client??this._client).get({url:`/config`,...e})}update(e){return(e?.client??this._client).patch({url:`/config`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}providers(e){return(e?.client??this._client).get({url:`/config/providers`,...e})}},Mt=class extends q{ids(e){return(e?.client??this._client).get({url:`/experimental/tool/ids`,...e})}list(e){return(e.client??this._client).get({url:`/experimental/tool`,...e})}},Nt=class extends q{dispose(e){return(e?.client??this._client).post({url:`/instance/dispose`,...e})}},Pt=class extends q{get(e){return(e?.client??this._client).get({url:`/path`,...e})}},Ft=class extends q{get(e){return(e?.client??this._client).get({url:`/vcs`,...e})}},It=class extends q{list(e){return(e?.client??this._client).get({url:`/session`,...e})}create(e){return(e?.client??this._client).post({url:`/session`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}status(e){return(e?.client??this._client).get({url:`/session/status`,...e})}delete(e){return(e.client??this._client).delete({url:`/session/{id}`,...e})}get(e){return(e.client??this._client).get({url:`/session/{id}`,...e})}update(e){return(e.client??this._client).patch({url:`/session/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}children(e){return(e.client??this._client).get({url:`/session/{id}/children`,...e})}todo(e){return(e.client??this._client).get({url:`/session/{id}/todo`,...e})}init(e){return(e.client??this._client).post({url:`/session/{id}/init`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}fork(e){return(e.client??this._client).post({url:`/session/{id}/fork`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}abort(e){return(e.client??this._client).post({url:`/session/{id}/abort`,...e})}unshare(e){return(e.client??this._client).delete({url:`/session/{id}/share`,...e})}share(e){return(e.client??this._client).post({url:`/session/{id}/share`,...e})}diff(e){return(e.client??this._client).get({url:`/session/{id}/diff`,...e})}summarize(e){return(e.client??this._client).post({url:`/session/{id}/summarize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}messages(e){return(e.client??this._client).get({url:`/session/{id}/message`,...e})}prompt(e){return(e.client??this._client).post({url:`/session/{id}/message`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}message(e){return(e.client??this._client).get({url:`/session/{id}/message/{messageID}`,...e})}promptAsync(e){return(e.client??this._client).post({url:`/session/{id}/prompt_async`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}command(e){return(e.client??this._client).post({url:`/session/{id}/command`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}shell(e){return(e.client??this._client).post({url:`/session/{id}/shell`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}revert(e){return(e.client??this._client).post({url:`/session/{id}/revert`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}unrevert(e){return(e.client??this._client).post({url:`/session/{id}/unrevert`,...e})}},Lt=class extends q{list(e){return(e?.client??this._client).get({url:`/command`,...e})}},Rt=class extends q{authorize(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/authorize`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}callback(e){return(e.client??this._client).post({url:`/provider/{id}/oauth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},zt=class extends q{list(e){return(e?.client??this._client).get({url:`/provider`,...e})}auth(e){return(e?.client??this._client).get({url:`/provider/auth`,...e})}oauth=new Rt({client:this._client})},Bt=class extends q{text(e){return(e.client??this._client).get({url:`/find`,...e})}files(e){return(e.client??this._client).get({url:`/find/file`,...e})}symbols(e){return(e.client??this._client).get({url:`/find/symbol`,...e})}},Vt=class extends q{list(e){return(e.client??this._client).get({url:`/file`,...e})}read(e){return(e.client??this._client).get({url:`/file/content`,...e})}status(e){return(e?.client??this._client).get({url:`/file/status`,...e})}},Ht=class extends q{log(e){return(e?.client??this._client).post({url:`/log`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}agents(e){return(e?.client??this._client).get({url:`/agent`,...e})}},Ut=class extends q{remove(e){return(e.client??this._client).delete({url:`/mcp/{name}/auth`,...e})}start(e){return(e.client??this._client).post({url:`/mcp/{name}/auth`,...e})}callback(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/callback`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}authenticate(e){return(e.client??this._client).post({url:`/mcp/{name}/auth/authenticate`,...e})}set(e){return(e.client??this._client).put({url:`/auth/{id}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}},Wt=class extends q{status(e){return(e?.client??this._client).get({url:`/mcp`,...e})}add(e){return(e?.client??this._client).post({url:`/mcp`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}connect(e){return(e.client??this._client).post({url:`/mcp/{name}/connect`,...e})}disconnect(e){return(e.client??this._client).post({url:`/mcp/{name}/disconnect`,...e})}auth=new Ut({client:this._client})},Gt=class extends q{status(e){return(e?.client??this._client).get({url:`/lsp`,...e})}},Kt=class extends q{status(e){return(e?.client??this._client).get({url:`/formatter`,...e})}},qt=class extends q{next(e){return(e?.client??this._client).get({url:`/tui/control/next`,...e})}response(e){return(e?.client??this._client).post({url:`/tui/control/response`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}},Jt=class extends q{appendPrompt(e){return(e?.client??this._client).post({url:`/tui/append-prompt`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}openHelp(e){return(e?.client??this._client).post({url:`/tui/open-help`,...e})}openSessions(e){return(e?.client??this._client).post({url:`/tui/open-sessions`,...e})}openThemes(e){return(e?.client??this._client).post({url:`/tui/open-themes`,...e})}openModels(e){return(e?.client??this._client).post({url:`/tui/open-models`,...e})}submitPrompt(e){return(e?.client??this._client).post({url:`/tui/submit-prompt`,...e})}clearPrompt(e){return(e?.client??this._client).post({url:`/tui/clear-prompt`,...e})}executeCommand(e){return(e?.client??this._client).post({url:`/tui/execute-command`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}showToast(e){return(e?.client??this._client).post({url:`/tui/show-toast`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}publish(e){return(e?.client??this._client).post({url:`/tui/publish`,...e,headers:{"Content-Type":`application/json`,...e?.headers}})}control=new qt({client:this._client})},Yt=class extends q{subscribe(e){return(e?.client??this._client).get.sse({url:`/event`,...e})}},Xt=class extends q{postSessionIdPermissionsPermissionId(e){return(e.client??this._client).post({url:`/session/{id}/permissions/{permissionID}`,...e,headers:{"Content-Type":`application/json`,...e.headers}})}global=new Ot({client:this._client});project=new kt({client:this._client});pty=new At({client:this._client});config=new jt({client:this._client});tool=new Mt({client:this._client});instance=new Nt({client:this._client});path=new Pt({client:this._client});vcs=new Ft({client:this._client});session=new It({client:this._client});command=new Lt({client:this._client});provider=new zt({client:this._client});find=new Bt({client:this._client});file=new Vt({client:this._client});app=new Ht({client:this._client});mcp=new Wt({client:this._client});lsp=new Gt({client:this._client});formatter=new Kt({client:this._client});tui=new Jt({client:this._client});auth=new Ut({client:this._client});event=new Yt({client:this._client})};function Zt(e){if(!e?.fetch){let t=e=>(e.timeout=!1,fetch(e));e={...e,fetch:t}}return e?.directory&&(e.headers={...e.headers,"x-opencode-directory":encodeURIComponent(e.directory)}),new Xt({client:Et(e)})}async function Qt(e){e=Object.assign({hostname:`127.0.0.1`,port:4096,timeout:5e3},e??{});let t=[`serve`,`--hostname=${e.hostname}`,`--port=${e.port}`];e.config?.logLevel&&t.push(`--log-level=${e.config.logLevel}`);let n=we(`opencode`,t,{signal:e.signal,env:{...process.env,OPENCODE_CONFIG_CONTENT:JSON.stringify(e.config??{})}});return{url:await new Promise((t,r)=>{let i=setTimeout(()=>{r(Error(`Timeout waiting for server to start after ${e.timeout}ms`))},e.timeout),a=``;n.stdout?.on(`data`,e=>{a+=e.toString();let n=a.split(` +`);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function $t(e){let t=await Qt({...e});return{client:Zt({baseUrl:t.url}),server:t}}async function en(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const tn={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},nn=`\x1B[0m`;function rn(){return H.env.NO_COLOR==null}function an(e,t){let[n,r]=tn[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);rn()?H.stdout.write(`\n${r}|${nn} ${i} ${nn}${t}\n`):H.stdout.write(`\n| ${i} ${t}\n`)}function on(e){H.stdout.write(`\n${e}\n`)}const sn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function cn(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function ln(e){let t=cn(e),n=sn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` +`)}function un(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const dn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function fn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return dn.some(e=>e.test(t))}function pn(e,t){return un(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function mn(e,t){return un(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}function hn(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function gn(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 _n(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(hn)}function vn(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)]}var yn=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(ge(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(_e(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${me}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},bn=T((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),xn=e(T((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[d.Accept]=this._getExistingOrDefaultHeader(t,d.Accept,f.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===u.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&m.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!h.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},x(this.requestOptions.headers),x(e||{})):x(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[d.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[d.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new l.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===u.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let x=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),Sn=w(),Cn=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function wn(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function Tn(e){return new xn.HttpClient().getAgent(e)}function En(e){return new xn.HttpClient().getAgentDispatcher(e)}function Dn(e){let t=En(e);return(e,n)=>Cn(this,void 0,void 0,function*(){return(0,Sn.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function On(){return process.env.GITHUB_API_URL||`https://api.github.com`}function kn(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function An(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>An.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function jn(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function Mn(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const Nn=Function.bind,Pn=Nn.bind(Nn);function Fn(e,t,n){let r=Pn(Mn,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=Pn(jn,null).apply(null,i)})}function In(){let e=Symbol(`Singular`),t={registry:{}},n=An.bind(null,t,e);return Fn(n,t,e),n}function Ln(){let e={registry:{}},t=An.bind(null,e);return Fn(t,e),t}var Rn={Singular:In,Collection:Ln},zn=`octokit-endpoint.js/0.0.0-development ${kn()}`,Bn={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":zn},mediaType:{format:``}};function Vn(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Hn(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Un(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Hn(t[r])&&r in e?n[r]=Un(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Wn(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function Gn(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Vn(n.headers),Wn(n),Wn(n.headers);let r=Un(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function Kn(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var qn=/\{[^{}}]+\}/g;function Jn(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Xn(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function Zn(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function Qn(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function $n(e,t,n){return t=e===`+`||e===`#`?Zn(t):Qn(t),n?Qn(n)+`=`+t:t}function er(e){return e!=null}function tr(e){return e===`;`||e===`&`||e===`?`}function nr(e,t,n,r){var i=e[n],a=[];if(er(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push($n(t,i,tr(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(er).forEach(function(e){a.push($n(t,e,tr(t)?n:``))}):Object.keys(i).forEach(function(e){er(i[e])&&a.push($n(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(er).forEach(function(n){e.push($n(t,n))}):Object.keys(i).forEach(function(n){er(i[n])&&(e.push(Qn(n)),e.push($n(t,i[n].toString())))}),tr(t)?a.push(Qn(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?er(i)&&a.push(Qn(n)):i===``&&(t===`&`||t===`?`)?a.push(Qn(n)+`=`):i===``&&a.push(``);return a}function rr(e){return{expand:ir.bind(null,e)}}function ir(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(nr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return Zn(i)}),e===`/`?e:e.replace(/\/$/,``)}function ar(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Xn(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Yn(n);n=rr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Xn(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=Kn(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function or(e,t,n){return ar(Gn(e,t,n))}function sr(e,t){let n=Gn(e,t),r=or.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:sr.bind(null,n),merge:Gn.bind(null,n),parse:ar})}var cr=sr(null,Bn),lr=T(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))(),ur=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function hr(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=pr(e.body)||Array.isArray(e.body)?JSON.stringify(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new ur(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new ur(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await gr(o),new ur(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await gr(o),new ur(vr(u.data),s,{response:u,request:e});return u.data=r?await gr(o):o.body,u}async function gr(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(mr);let n=(0,lr.safeParse)(t);if(_r(n)){let t=``;try{return t=await e.text(),JSON.parse(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(mr);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function _r(e){return e.type===`application/json`||e.type===`application/scim+json`}function vr(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function yr(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return hr(n.parse(r));let i=(e,t)=>hr(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:yr.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:yr.bind(null,n)})}var br=yr(cr,fr),xr=`0.0.0-development`;function Sr(e){return`Request failed due to following response errors: `+e.errors.map(e=>` - ${e.message}`).join(` -`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${An()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${An()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new zn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new bn;const ii=kn(),ai={baseUrl:ii,request:{agent:En(ii),fetch:On(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=Tn(e,n);return r&&(n.auth=r),n}const ci=new bn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(ie(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=U.join(ki(),ge.randomUUID()),yield S(U.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(H.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=be.promisify(ke.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,H.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=me.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!H.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of H.readdirSync(e))yield b(U.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=me.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=U.join(Oi(),e,t,n);j(`checking cache: ${i}`),H.existsSync(i)&&H.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=me.arch();let r=U.join(Oi(),e);if(H.existsSync(r)){let e=H.readdirSync(r);for(let i of e)if(Ei(i)){let e=U.join(r,i,t||``);H.existsSync(e)&&H.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=U.join(ki(),ge.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=U.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${U.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;H.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ye(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ye(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=z.join(t,`auth.json`);await W.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await W.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=V.platform,t=V.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(V.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=pe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await we.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=pe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>V.platform===`win32`?`${e}.exe`:e,n=pe.join(e,t(`bun`));try{await we.symlink(n,pe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};V.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`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 Ze(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 Gi(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`}=n;r.info(`Installing Oh My OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u});let d=``,f=[`oh-my-opencode@${e}`,`install`,`--no-tui`,`--claude=${a}`,`--copilot=${o}`,`--gemini=${s}`,`--openai=${c}`,`--opencode-zen=${l}`,`--zai-coding-plan=${u}`];try{let t=await i.exec(`bunx`,f,{listeners:{stdout:e=>{d+=e.toString()},stderr:e=>{d+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-opencode install returned exit code ${t}`;return r.error(e,{output:d.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${d.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(d),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=M(e),n=d.length>0?`${t}\nOutput: ${d.slice(0,500)}`:t;return r.error(`Failed to run oMo installer`,{error:t,output:d.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-opencode install failed: ${n}`}}}const Ki=`opencode`,qi=`1.2.9`;function Ji(){let e=De.platform(),t=De.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 Yi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Xi(e,t,n,r){if(V.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 Zi(e,t,n,r,i=qi){let a=Ji(),o=n.find(Ki,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 Qi(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(n)})}if(e!==i)try{let e=await Qi(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}): ${M(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Qi(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=Yi(e,t),o=await r.downloadTool(a);if(!await Xi(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,Ki,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function $i(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ea={restoreCache:async(e,t,n)=>ce(e,t,n),saveCache:async(e,t)=>D(e,t)};function ta(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${le}-${t}-oc-${n}-omo-${r}`}function na(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${le}-${t}-oc-${n}-omo-${r}-`]}async function ra(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=na({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function ia(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const aa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function oa(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`;for(let e of t)if(aa.includes(e))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}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function sa(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ca(){return{exec:x,getExecOutput:c}}function la(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null}}async function ua(){let e=Date.now(),n=A({component:`setup`}),r=sa(),o=ca();try{let s=la(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await $i(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=qi}let d=m(`omo-version`).trim(),f=d.length>0?d:N,h=V.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=B(h,`opencode`),v=B(h,`bun`),y=B(Oe(),`.config`,`opencode`),b=a(),x=await ra({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await Zi(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){let e=m(`omo-providers`).trim(),t=oa(e.length>0?e:se),r=await Gi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1,...s.opencodeConfig==null?{}:JSON.parse(s.opencodeConfig)};p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await ia({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),R(`opencode-path`,C.path),R(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=B(i(),`opencode`),k=await Mi(l,O,n);R(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=V.env.GITHUB_REPOSITORY??`unknown/unknown`,j=V.env.GITHUB_REF_NAME??`main`,ie=a(),ae=ee({agentIdentity:`github`,repo:A,ref:j,os:ie}),P=oe({agentIdentity:`github`,repo:A,ref:j,os:ie}),F=`miss`;try{let e=await ce([O],ae,[...P]);e==null?n.info(`No cache found`):(F=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){F=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}R(`cache-status`,F),R(`storage-path`,O);let I=Date.now()-e,L={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:F,toolsCacheStatus:S,duration:I};return n.info(`Setup complete`,{duration:I}),L}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function da(e){return{success:!0,data:e}}function fa(e){return{success:!1,error:e}}const pa=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ma(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` +`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${kn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${kn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Rn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new yn;const ii=On(),ai={baseUrl:ii,request:{agent:Tn(ii),fetch:Dn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=wn(e,n);return r&&(n.auth=r),n}const ci=new yn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(ie(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=W.join(ki(),he.randomUUID()),yield S(W.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(U.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=ye.promisify(Oe.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,U.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=pe.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!U.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of U.readdirSync(e))yield b(W.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=pe.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=W.join(Oi(),e,t,n);j(`checking cache: ${i}`),U.existsSync(i)&&U.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=pe.arch();let r=W.join(Oi(),e);if(U.existsSync(r)){let e=U.readdirSync(r);for(let i of e)if(Ei(i)){let e=W.join(r,i,t||``);U.existsSync(e)&&U.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=W.join(ki(),he.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=W.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${W.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;U.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ve(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ve(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=B.join(t,`auth.json`);await G.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await G.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=H.platform,t=H.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(H.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=fe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Ce.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=fe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>H.platform===`win32`?`${e}.exe`:e,n=fe.join(e,t(`bun`));try{await Ce.symlink(n,fe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};H.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}async function Gi(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`}=n;r.info(`Installing Oh My OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u});let d=``,f=[`oh-my-opencode@${e}`,`install`,`--no-tui`,`--claude=${a}`,`--copilot=${o}`,`--gemini=${s}`,`--openai=${c}`,`--opencode-zen=${l}`,`--zai-coding-plan=${u}`];try{let t=await i.exec(`bunx`,f,{listeners:{stdout:e=>{d+=e.toString()},stderr:e=>{d+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-opencode install returned exit code ${t}`;return r.error(e,{output:d.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${d.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(d),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=M(e),n=d.length>0?`${t}\nOutput: ${d.slice(0,500)}`:t;return r.error(`Failed to run oMo installer`,{error:t,output:d.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-opencode install failed: ${n}`}}}const Ki=`opencode`,qi=`1.2.9`;function Ji(){let e=Ee.platform(),t=Ee.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 Yi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Xi(e,t,n,r){if(H.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 Zi(e,t,n,r,i=qi){let a=Ji(),o=n.find(Ki,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 Qi(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(n)})}if(e!==i)try{let e=await Qi(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}): ${M(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Qi(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=Yi(e,t),o=await r.downloadTool(a);if(!await Xi(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,Ki,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function $i(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ea={restoreCache:async(e,t,n)=>I(e,t,n),saveCache:async(e,t)=>D(e,t)};function ta(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ce}-${t}-oc-${n}-omo-${r}`}function na(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ce}-${t}-oc-${n}-omo-${r}-`]}async function ra(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=na({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function ia(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const aa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function oa(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`;for(let e of t)if(aa.includes(e))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}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function sa(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ca(){return{exec:x,getExecOutput:c}}function la(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null}}async function ua(){let e=Date.now(),n=A({component:`setup`}),r=sa(),o=ca();try{let s=la(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await $i(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=qi}let d=m(`omo-version`).trim(),f=d.length>0?d:N,h=H.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=V(h,`opencode`),v=V(h,`bun`),y=V(De(),`.config`,`opencode`),b=a(),x=await ra({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await Zi(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){let e=m(`omo-providers`).trim(),t=oa(e.length>0?e:se),r=await Gi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1};if(s.opencodeConfig!=null){let e=JSON.parse(s.opencodeConfig);if(typeof e!=`object`||!e||Array.isArray(e))return _(`opencode-config must be a JSON object`),null;Object.assign(te,e)}p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await ia({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),z(`opencode-path`,C.path),z(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=V(i(),`opencode`),k=await Mi(l,O,n);z(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=H.env.GITHUB_REPOSITORY??`unknown/unknown`,j=H.env.GITHUB_REF_NAME??`main`,ie=a(),ae=ee({agentIdentity:`github`,repo:A,ref:j,os:ie}),P=oe({agentIdentity:`github`,repo:A,ref:j,os:ie}),F=`miss`;try{let e=await I([O],ae,[...P]);e==null?n.info(`No cache found`):(F=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){F=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}z(`cache-status`,F),z(`storage-path`,O);let L=Date.now()-e,R={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:F,toolsCacheStatus:S,duration:L};return n.info(`Setup complete`,{duration:L}),R}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function da(e){return{success:!0,data:e}}function fa(e){return{success:!1,error:e}}const pa=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ma(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` `),appendMode:!0};case`pull_request_review_comment`:return{directive:ha(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function ha(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` `)}function ga(e,t){let{directive:n,appendMode:r}=ma(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` `)}function _a(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a}=e,o=[];if(o.push(`# Agent Context @@ -167,7 +167,7 @@ Respond to the trigger comment above. Follow all instructions and requirements l \`\`\` ${n.commentBody} \`\`\` -`),a!=null&&o.push(ya(a)),n.diffContext!=null&&o.push(ba(n.diffContext)),n.hydratedContext!=null&&o.push(Le(n.hydratedContext)),o.push(`## Session Management (REQUIRED) +`),a!=null&&o.push(ya(a)),n.diffContext!=null&&o.push(ba(n.diffContext)),n.hydratedContext!=null&&o.push(Ie(n.hydratedContext)),o.push(`## Session Management (REQUIRED) Before investigating any issue: 1. Use \`session_search\` to find relevant prior sessions for this repository @@ -254,9 +254,9 @@ Every response you post — regardless of channel (issue, PR, discussion, review `}function ya(e){let t=[`## Prior Session Context`];if(e.recentSessions.length>0){t.push(``),t.push(`### Recent Sessions`),t.push(`| ID | Title | Updated | Messages | Agents |`),t.push(`|----|-------|---------|----------|--------|`);for(let n of e.recentSessions.slice(0,5)){let e=new Date(n.updatedAt).toISOString().split(`T`)[0],r=n.agents.join(`, `)||`N/A`,i=n.title||`Untitled`;t.push(`| ${n.id} | ${i} | ${e} | ${n.messageCount} | ${r} |`)}t.push(``),t.push("Use `session_read` to review any of these sessions in detail.")}if(e.priorWorkContext.length>0){t.push(``),t.push(`### Relevant Prior Work`),t.push(``),t.push(`The following sessions contain content related to this issue:`),t.push(``);for(let n of e.priorWorkContext.slice(0,3)){t.push(`**Session ${n.sessionId}:**`),t.push("```markdown");for(let e of n.matches.slice(0,2))t.push(`- ${e.excerpt}`);t.push("```"),t.push(``)}t.push("Use `session_read` to review full context before starting new investigation.")}return t.push(``),t.join(` `)}function ba(e){let t=[`## Pull Request Diff Summary`];if(t.push(``),t.push(`- **Changed Files:** ${e.changedFiles}`),t.push(`- **Additions:** +${e.additions}`),t.push(`- **Deletions:** -${e.deletions}`),e.truncated&&t.push(`- **Note:** Diff was truncated due to size limits`),e.files.length>0){t.push(``),t.push(`### Changed Files`),t.push(`| File | Status | +/- |`),t.push(`|------|--------|-----|`);for(let n of e.files.slice(0,20))t.push(`| \`${n.filename}\` | ${n.status} | +${n.additions}/-${n.deletions} |`);e.files.length>20&&t.push(`| ... | | +${e.files.length-20} more files |`)}return t.push(``),t.join(` `)}function xa(e){let t=[`## Output Contract`,``];return t.push(`- Review action: approve/request-changes if confident; otherwise comment-only`),t.push(`- Requested reviewer: ${e.isRequestedReviewer?`yes`:`no`}`),e.authorAssociation!=null&&t.push(`- Author association: ${e.authorAssociation}`),t.push(``),t.join(` -`)}function Sa(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function Ca(e,t,n,r,i){let a=vn(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=yn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function wa(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(Sa(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(sn(a),a=``)}else if(e.type===`tool`){let t=e.state;if(t.status===`completed`){let n=e.tool,r=t.input,i=t.title;on(n,i),n.toLowerCase()===`bash`&&Ca(String(r.command??r.cmd??``),String(t.output),l,u,()=>{d++})}}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error;r.error(`Session error`,{error:e});let t=typeof e==`string`?e:String(e);f=pn(e)?mn(t,s??void 0):hn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(sn(a),a=``))}return a.length>0&&sn(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}async function Ta(e,t,n,r,i,a=E,o){let s=Date.now(),c=0;for(;!r.aborted;){if(await tn(500),r.aborted)return{completed:!1,error:`Aborted`};if(o?.sessionError==null)c=0;else{if(c++,c>=3)return i.error(`Session error persisted through grace period`,{sessionId:t,error:o.sessionError,graceCycles:c}),{completed:!1,error:`Session error: ${o.sessionError}`};continue}if(o?.sessionIdle===!0)return i.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let l=Date.now()-s;if(a>0&&l>=a)return i.warning(`Poll timeout reached`,{elapsedMs:l,maxPollTimeMs:a}),{completed:!1,error:`Poll timeout after ${l}ms`};try{let r=((await e.session.status({query:{directory:n}})).data??{})[t];if(r==null)i.debug(`Session status not found in poll response`,{sessionId:t});else if(r.type===`idle`)return i.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else i.debug(`Session status`,{sessionId:t,type:r.type});if(o!=null&&!o.firstMeaningfulEventReceived){let e=Date.now()-s;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:M(e)})}}return{completed:!1,error:`Aborted`}}async function Ea(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}const Da=5e3;function Oa(e){return e==null?!1:Object.values(e.omoProviders).some(e=>e!==`no`)}function ka(e){if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!Oa(e))return{providerID:re.providerID,modelID:re.modelID}}async function Aa(e,t,n,r,i,a,o){let s=a?.agent??L,c=new AbortController,l={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},u=await e.event.subscribe(),d={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},f=wa(u.stream,t,c.signal,o,l).then(e=>{d=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&o.debug(`Event stream error`,{error:e.message})}),p=async()=>{c.abort(),await Ea(f)},m=[{type:`text`,text:n}];r!=null&&r.length>0&&(m.push(...r),o.info(`Including file attachments in prompt`,{count:r.length}));let h=ka(a),g={parts:m};h!=null&&(g.model=h),s!==L&&(g.agent=s),o.debug(`Sending prompt to OpenCode`,{sessionId:t});try{let n=await e.session.promptAsync({path:{id:t},body:g,query:{directory:i}});if(n.error!=null){o.error(`OpenCode prompt failed`,{error:String(n.error)}),await p();let e=pn(n.error)?mn(String(n.error),d.model??void 0):d.llmError;return{success:!1,error:String(n.error),llmError:e,shouldRetry:e!=null,eventStreamResult:d}}let r=a?.timeoutMs??E,s=await Ta(e,t,i,c.signal,o,r,l);if(await p(),!s.completed){let e=s.error??`Session did not reach idle state`;return o.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:d.llmError,shouldRetry:d.llmError!=null,eventStreamResult:d}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:d}}finally{c.abort(),await Ea(f)}}async function ja(e,t){try{let{client:n,server:r}=await en({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),da({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),fa(Error(`Server bootstrap failed: ${n}`))}}async function Ma(e,t,n,r){let i=Date.now(),a=new AbortController,o=n?.timeoutMs??E,s=null,c=!1,l=r==null,u=null;o>0&&(s=setTimeout(()=>{c=!0,t.warning(`Execution timeout reached`,{timeoutMs:o}),a.abort()},o)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??L,hasModelOverride:n?.model!=null,timeoutMs:o});try{let s;if(r==null){let e=await en({signal:a.signal});s=e.client,u=e.server,t.debug(`OpenCode server started`,{url:u.url})}else s=r.client,t.debug(`Reusing external OpenCode server`,{url:r.server.url});let l=await s.session.create();if(l.data==null||l.error!=null){let e=l.error==null?`No data returned`:String(l.error);throw Error(`Failed to create session: ${e}`)}let d=l.data.id;t.debug(`Session created`,{sessionId:d});let f=_a({...e,sessionId:d},t),p=v();if(h()){let e=ue(),n=Se.createHash(`sha256`).update(f).digest(`hex`),r=z.join(e,`prompt-${d}-${n.slice(0,8)}.txt`);try{await W.mkdir(e,{recursive:!0}),await W.writeFile(r,f,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let m=null,g=null,_=null,y=[],b=[],x=0,S=null,C=null;for(let r=1;r<=3;r++){if(c)return{success:!1,exitCode:130,duration:Date.now()-i,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C};let a=o-(Date.now()-i);if(o>0&&a<=Da&&r>1){t.warning(`Insufficient time remaining for retry`,{remainingMs:a,requiredMs:Da,attempt:r});break}let l=r===1?f:`The previous request was interrupted by a network error (fetch failed). +`)}function Sa(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function Ca(e,t,n,r,i){let a=_n(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=vn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function wa(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(Sa(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(on(a),a=``)}else if(e.type===`tool`){let t=e.state;if(t.status===`completed`){let n=e.tool,r=t.input,i=t.title;an(n,i),n.toLowerCase()===`bash`&&Ca(String(r.command??r.cmd??``),String(t.output),l,u,()=>{d++})}}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error;r.error(`Session error`,{error:e});let t=typeof e==`string`?e:String(e);f=fn(e)?pn(t,s??void 0):mn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(on(a),a=``))}return a.length>0&&on(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}async function Ta(e,t,n,r,i,a=E,o){let s=Date.now(),c=0;for(;!r.aborted;){if(await en(500),r.aborted)return{completed:!1,error:`Aborted`};if(o?.sessionError==null)c=0;else{if(c++,c>=3)return i.error(`Session error persisted through grace period`,{sessionId:t,error:o.sessionError,graceCycles:c}),{completed:!1,error:`Session error: ${o.sessionError}`};continue}if(o?.sessionIdle===!0)return i.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let l=Date.now()-s;if(a>0&&l>=a)return i.warning(`Poll timeout reached`,{elapsedMs:l,maxPollTimeMs:a}),{completed:!1,error:`Poll timeout after ${l}ms`};try{let r=((await e.session.status({query:{directory:n}})).data??{})[t];if(r==null)i.debug(`Session status not found in poll response`,{sessionId:t});else if(r.type===`idle`)return i.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else i.debug(`Session status`,{sessionId:t,type:r.type});if(o!=null&&!o.firstMeaningfulEventReceived){let e=Date.now()-s;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:M(e)})}}return{completed:!1,error:`Aborted`}}async function Ea(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}const Da=5e3;function Oa(e){return e==null?!1:Object.values(e.omoProviders).some(e=>e!==`no`)}function ka(e){if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!Oa(e))return{providerID:re.providerID,modelID:re.modelID}}async function Aa(e,t,n,r,i,a,o){let s=a?.agent??R,c=new AbortController,l={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},u=await e.event.subscribe(),d={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},f=wa(u.stream,t,c.signal,o,l).then(e=>{d=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&o.debug(`Event stream error`,{error:e.message})}),p=async()=>{c.abort(),await Ea(f)},m=[{type:`text`,text:n}];r!=null&&r.length>0&&(m.push(...r),o.info(`Including file attachments in prompt`,{count:r.length}));let h=ka(a),g={parts:m};h!=null&&(g.model=h),s!==R&&(g.agent=s),o.debug(`Sending prompt to OpenCode`,{sessionId:t});try{let n=await e.session.promptAsync({path:{id:t},body:g,query:{directory:i}});if(n.error!=null){o.error(`OpenCode prompt failed`,{error:String(n.error)}),await p();let e=fn(n.error)?pn(String(n.error),d.model??void 0):d.llmError;return{success:!1,error:String(n.error),llmError:e,shouldRetry:e!=null,eventStreamResult:d}}let r=a?.timeoutMs??E,s=await Ta(e,t,i,c.signal,o,r,l);if(await p(),!s.completed){let e=s.error??`Session did not reach idle state`;return o.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:d.llmError,shouldRetry:d.llmError!=null,eventStreamResult:d}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:d}}finally{c.abort(),await Ea(f)}}async function ja(e,t){try{let{client:n,server:r}=await $t({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),da({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),fa(Error(`Server bootstrap failed: ${n}`))}}async function Ma(e,t,n,r){let i=Date.now(),a=new AbortController,o=n?.timeoutMs??E,s=null,c=!1,l=r==null,u=null;o>0&&(s=setTimeout(()=>{c=!0,t.warning(`Execution timeout reached`,{timeoutMs:o}),a.abort()},o)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??R,hasModelOverride:n?.model!=null,timeoutMs:o});try{let s;if(r==null){let e=await $t({signal:a.signal});s=e.client,u=e.server,t.debug(`OpenCode server started`,{url:u.url})}else s=r.client,t.debug(`Reusing external OpenCode server`,{url:r.server.url});let l=await s.session.create();if(l.data==null||l.error!=null){let e=l.error==null?`No data returned`:String(l.error);throw Error(`Failed to create session: ${e}`)}let d=l.data.id;t.debug(`Session created`,{sessionId:d});let f=_a({...e,sessionId:d},t),p=v();if(h()){let e=le(),n=xe.createHash(`sha256`).update(f).digest(`hex`),r=B.join(e,`prompt-${d}-${n.slice(0,8)}.txt`);try{await G.mkdir(e,{recursive:!0}),await G.writeFile(r,f,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let m=null,g=null,_=null,y=[],b=[],x=0,S=null,C=null;for(let r=1;r<=3;r++){if(c)return{success:!1,exitCode:130,duration:Date.now()-i,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C};let a=o-(Date.now()-i);if(o>0&&a<=Da&&r>1){t.warning(`Insufficient time remaining for retry`,{remainingMs:a,requiredMs:Da,attempt:r});break}let l=r===1?f:`The previous request was interrupted by a network error (fetch failed). Please continue where you left off. If you were in the middle of a task, resume it. -If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void 0;t.debug(`Sending prompt`,{attempt:r,isRetry:r>1});try{let e=await Aa(s,d,l,u,p,n,t);if(e.success){let{eventStreamResult:n}=e;m=n.tokens,g=n.model,_=n.cost,y=[...n.prsCreated],b=[...n.commitsCreated],x=n.commentsPosted;let a=Date.now()-i;return t.info(`OpenCode execution completed`,{sessionId:d,durationMs:a,attempts:r}),{success:!0,exitCode:0,duration:a,sessionId:d,error:null,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:null}}if(S=e.error,C=e.llmError,!e.shouldRetry||r>=3){e.shouldRetry&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:e.error});break}t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:e.error,delayMs:Da,sessionId:d}),await tn(Da)}catch(e){let n=M(e);t.error(`Prompt attempt failed with exception`,{attempt:r,error:n}),S=n;let i=pn(e)?mn(n):null;if(C=i,i==null||r>=3){i!=null&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:n});break}t.warning(`LLM fetch error detected (exception), retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:n,delayMs:Da,sessionId:d}),await tn(Da)}}return{success:!1,exitCode:1,duration:Date.now()-i,sessionId:d,error:S??`Unknown error`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C}}catch(e){let n=Date.now()-i,r=M(e);return t.error(`OpenCode execution failed`,{error:r,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:pn(e)?mn(r):null}}finally{s!=null&&clearTimeout(s),a.abort(),l&&u?.close()}}async function Na(e,t){let n=e??`opencode`;try{let e=``;await x(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function Pa(e){let{logger:n,opencodeVersion:r}=e,i=V.env.OPENCODE_PATH??null,a=await Na(i,n);if(a.available&&a.version!=null)return n.info(`OpenCode already available`,{version:a.version}),{path:i??`opencode`,version:a.version,didSetup:!1};n.info(`OpenCode not found, running auto-setup`,{requestedVersion:r});let o=await ua();if(o==null)throw Error(`Auto-setup failed: runSetup returned null`);return t(o.opencodePath),V.env.OPENCODE_PATH=o.opencodePath,n.info(`Auto-setup completed`,{version:o.opencodeVersion,path:o.opencodePath}),{path:o.opencodePath,version:o.opencodeVersion,didSetup:!0}}const Fa=`agent: working`;async function Ia(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await We(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function La(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await qe(e,t.repo,Fa,`fcf2e1`,`Agent is currently working on this`,n)&&await Je(e,t.repo,t.issueNumber,[Fa],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function Ra(e,t,n){await Promise.all([Ia(e,t,n),La(e,t,n)])}async function za(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await Ge(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Ke(e,t.repo,t.commentId,r.id,n)}async function Ba(e,t,n,r){t.commentId!=null&&await We(e,t.repo,t.commentId,n,r)}async function Va(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:M(e)})}}async function Ha(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:M(e)})}}async function Ua(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Ye(e,t.repo,t.issueNumber,Fa,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function Wa(e,t,n,r){n?await Va(e,t,r):await Ha(e,t,r),await Ua(e,t,r)}const Ga={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 Ka(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function qa(e){let t=[],n=new Set;return Ka(Ga.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&_n(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Ka(Ga.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&_n(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Ka(Ga.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&_n(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),Ga.htmlImage.lastIndex=0,t}function Ja(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 Ya={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`]},Xa=[`github.com`,`githubusercontent.com`];async function Za(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(!Xa.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=xe.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=Ja(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await W.mkdtemp(z.join(Ee.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=z.join(p,m);return await W.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:M(t)}),null}}async function Qa(e,t,n=Ya,r){return Promise.all(e.map(async(e,i)=>Za(e,i,t,n,r)))}async function $a(e,t){for(let n of e)try{await W.unlink(n);let e=z.dirname(n);await W.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:M(e)})}}function eo(e){return e.map(e=>({type:`file`,mime:e.mime,url:Ce(e.tempPath).toString(),filename:e.filename}))}function to(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 no(e,t,n,r){return{processed:n,skipped:r,modifiedBody:to(e,t,n),fileParts:eo(n),tempFiles:n.map(e=>e.tempPath)}}function ro(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function io(e,t=Ya,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 (${ro(o.sizeBytes)} > ${ro(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 (${ro(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!ao(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 ao(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}const oo=``;function so(e,t){return t==null?!1:e===t||e===`${t}[bot]`}function co(e,t,n){return so(e,n)&&t.includes(oo)}async function lo(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:M(e)}),null}}async function uo(e,t,n,r){let i=[],a=1;for(;a<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:a});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;i.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:co(t,e.body??``,n)})}if(r.length<100)break;a++}catch(e){r.warning(`Failed to fetch comments page`,{target:t,page:a,error:M(e)});break}return i}async function fo(e,t,n,r){try{let i=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` +If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void 0;t.debug(`Sending prompt`,{attempt:r,isRetry:r>1});try{let e=await Aa(s,d,l,u,p,n,t);if(e.success){let{eventStreamResult:n}=e;m=n.tokens,g=n.model,_=n.cost,y=[...n.prsCreated],b=[...n.commitsCreated],x=n.commentsPosted;let a=Date.now()-i;return t.info(`OpenCode execution completed`,{sessionId:d,durationMs:a,attempts:r}),{success:!0,exitCode:0,duration:a,sessionId:d,error:null,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:null}}if(S=e.error,C=e.llmError,!e.shouldRetry||r>=3){e.shouldRetry&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:e.error});break}t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:e.error,delayMs:Da,sessionId:d}),await en(Da)}catch(e){let n=M(e);t.error(`Prompt attempt failed with exception`,{attempt:r,error:n}),S=n;let i=fn(e)?pn(n):null;if(C=i,i==null||r>=3){i!=null&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:n});break}t.warning(`LLM fetch error detected (exception), retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:n,delayMs:Da,sessionId:d}),await en(Da)}}return{success:!1,exitCode:1,duration:Date.now()-i,sessionId:d,error:S??`Unknown error`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C}}catch(e){let n=Date.now()-i,r=M(e);return t.error(`OpenCode execution failed`,{error:r,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:fn(e)?pn(r):null}}finally{s!=null&&clearTimeout(s),a.abort(),l&&u?.close()}}async function Na(e,t){let n=e??`opencode`;try{let e=``;await x(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function Pa(e){let{logger:n,opencodeVersion:r}=e,i=H.env.OPENCODE_PATH??null,a=await Na(i,n);if(a.available&&a.version!=null)return n.info(`OpenCode already available`,{version:a.version}),{path:i??`opencode`,version:a.version,didSetup:!1};n.info(`OpenCode not found, running auto-setup`,{requestedVersion:r});let o=await ua();if(o==null)throw Error(`Auto-setup failed: runSetup returned null`);return t(o.opencodePath),H.env.OPENCODE_PATH=o.opencodePath,n.info(`Auto-setup completed`,{version:o.opencodeVersion,path:o.opencodePath}),{path:o.opencodePath,version:o.opencodeVersion,didSetup:!0}}const Fa=`agent: working`;async function Ia(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await Ue(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function La(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await Ke(e,t.repo,Fa,`fcf2e1`,`Agent is currently working on this`,n)&&await qe(e,t.repo,t.issueNumber,[Fa],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function Ra(e,t,n){await Promise.all([Ia(e,t,n),La(e,t,n)])}async function za(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await We(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Ge(e,t.repo,t.commentId,r.id,n)}async function Ba(e,t,n,r){t.commentId!=null&&await Ue(e,t.repo,t.commentId,n,r)}async function Va(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:M(e)})}}async function Ha(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:M(e)})}}async function Ua(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Je(e,t.repo,t.issueNumber,Fa,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function Wa(e,t,n,r){n?await Va(e,t,r):await Ha(e,t,r),await Ua(e,t,r)}const Ga={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 Ka(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function qa(e){let t=[],n=new Set;return Ka(Ga.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Ka(Ga.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Ka(Ga.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&gn(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),Ga.htmlImage.lastIndex=0,t}function Ja(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 Ya={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`]},Xa=[`github.com`,`githubusercontent.com`];async function Za(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(!Xa.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=be.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=Ja(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await G.mkdtemp(B.join(Te.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=B.join(p,m);return await G.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:M(t)}),null}}async function Qa(e,t,n=Ya,r){return Promise.all(e.map(async(e,i)=>Za(e,i,t,n,r)))}async function $a(e,t){for(let n of e)try{await G.unlink(n);let e=B.dirname(n);await G.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:M(e)})}}function eo(e){return e.map(e=>({type:`file`,mime:e.mime,url:Se(e.tempPath).toString(),filename:e.filename}))}function to(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 no(e,t,n,r){return{processed:n,skipped:r,modifiedBody:to(e,t,n),fileParts:eo(n),tempFiles:n.map(e=>e.tempPath)}}function ro(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function io(e,t=Ya,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 (${ro(o.sizeBytes)} > ${ro(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 (${ro(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!ao(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 ao(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}const oo=``;function so(e,t){return t==null?!1:e===t||e===`${t}[bot]`}function co(e,t,n){return so(e,n)&&t.includes(oo)}async function lo(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:M(e)}),null}}async function uo(e,t,n,r){let i=[],a=1;for(;a<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:a});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;i.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:co(t,e.body??``,n)})}if(r.length<100)break;a++}catch(e){r.warning(`Failed to fetch comments page`,{target:t,page:a,error:M(e)});break}return i}async function fo(e,t,n,r){try{let i=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` query GetDiscussion($owner: String!, $repo: String!, $number: Int!, $after: String) { repository(owner: $owner, name: $repo) { discussion(number: $number) { @@ -313,6 +313,6 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void comment { id url } } } -`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:M(e)}),null}}async function vo(e,t,n,r){if(t.type===`discussion`)return _o(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await po(e,t,n.botLogin,r);if(i!=null){let a=mo(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return go(e,t,a.id,n.body,r)}}return ho(e,t,n.body,r)}function yo(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function bo(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function xo(e){let t=ci,n=yo(t.eventName),r=bo(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function So(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function Co(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function wo(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 To(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Eo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function Do(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`;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}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function Oo(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return fa(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return fa(Error(`auth-json is required but was not provided`));So(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?Co(i,`session-retention`):O,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:L,p=m(`model`).trim(),h=p.length>0?wo(p):null,g=m(`timeout`).trim(),_=g.length>0?To(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:k,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:N,C=m(`omo-providers`).trim();return da({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:Do(C.length>0?C:se)})}catch(e){return fa(e instanceof Error?e:Error(String(e)))}}function ko(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Ao(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function jo(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(P.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,ko(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Ao(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(P.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&P.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&P.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(P.addHeading(`Token Usage`,3),P.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&P.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&P.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(P.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&P.addList([...c.prsCreated]),c.commitsCreated.length>0&&P.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&P.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){P.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;P.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await P.write(),t.debug(`Wrote job summary`)}catch(e){let r=M(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Mo(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function No(e){R(`session-id`,e.sessionId??``),R(`cache-status`,e.cacheStatus),R(`duration`,e.duration)}function Po(e){let t=z.resolve(e);return t.endsWith(z.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function Fo(e){return typeof e==`boolean`?e:null}function Io(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function Lo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Io(e.diffs)}}function Ro(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function zo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Bo(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:zo(e.time),summary:Lo(e.summary),share:Ro(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Vo(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Io(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Ho(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:Fo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function Uo(e){return Z(e)?Q(e.role)===`assistant`?Ho(e):Vo(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Wo(e){let t=Uo(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(qo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function Go(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Ko(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function qo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=Go(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:Fo(e.synthetic)??void 0,ignored:Fo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Ko(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Jo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Bo):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function Yo(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Wo)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function Xo(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Bo);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function Zo(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function Qo(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function $o(e,t,n){let r=Po(t),i=await Qo(e,n);for(let e of i){if(Po(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Po(t)===r)return e}return null}async function es(e,t,n){return Jo(e,t,n)}async function ts(e,t,n){return Yo(e,t,n)}async function ns(e,t,n){return Zo(e,t,n)}async function rs(e,t,n,r){return Xo(e,t,n,r)}const is={maxSessions:50,maxAgeDays:30};async function as(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await $o(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await es(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await ns(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:M(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function os(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await es(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await ts(e,t.id,r),i=ss(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ss(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function cs(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ls(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await os(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ls(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ls(e,t,n,r,i){let a=await ts(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=us(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function us(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ds(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` -`)}async function fs(e,t,n,r){let i=ds(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:i}]}});if(t.error!=null){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}r.info(`Session summary written via SDK`,{sessionId:e})}catch(t){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:M(t)})}}const ps=/^[0-9a-f]{40}$/i;function ms(){return{exec:x,getExecOutput:c}}async function hs(e){let{workspacePath:t,logger:n,execAdapter:r=ms()}=e,i=z.join(t,`.git`),a=z.join(i,`opencode`);try{let e=(await W.readFile(a,`utf8`)).trim();if(e.length>0){if(ps.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:M(e)})}try{if((await W.stat(i)).isDirectory()===!1){let e=await W.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=z.resolve(t,n[1]),a=z.join(i,`opencode`)}}catch{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 W.writeFile(a,s,`utf8`),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){n.warning(`Failed to cache project ID (continuing)`,{error:M(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:M(e)}}}const gs={botLogin:null,requireMention:!0,allowedAssociations:pa,skipDraftPRs:!0,promptInput:null};function _s(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${vs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function vs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function ys(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${vs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function bs(e,t){return t.includes(e)}function xs(e){return e.endsWith(`[bot]`)}function Ss(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=_s(e,t);return{hasMention:n,command:n?ys(e,t):null}}function Cs(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},i=e.comment.body,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function ws(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:e.comment.body??e.discussion.body??null,locked:e.discussion.locked},i=e.comment.body??null,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Ts(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Es(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:xs(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=Ss(e.issue.body??``,t);return{author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,action:e.action}}const Ds=[`opened`,`edited`];function Os(e){return Ds.includes(e)}function ks(e,t,n){let r=e.action;return r==null||!Os(r)?(n.debug(`Skipping unsupported issues action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${r}' is not supported (only 'opened' and 'edited')`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):r===`edited`&&!e.hasMention?(n.debug(`Skipping issues.edited without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}):e.target?.locked===!0?(n.debug(`Skipping locked issue`),{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}):{shouldSkip:!1}}function As(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:xs(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft},{hasMention:i,command:a}=Ss(e.pullRequest.body??``,t);return{author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,action:e.action}}const js=[`opened`,`synchronize`,`reopened`];function Ms(e){return js.includes(e)}function Ns(e,t,n){let r=e.action;return r==null||!Ms(r)?(n.debug(`Skipping unsupported pull_request action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${r}' is not supported`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.skipDraftPRs&&e.target?.isDraft===!0?(n.debug(`Skipping draft PR`),{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}):e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):{shouldSkip:!1}}function Ps(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=Ss(e.comment.body,t);return{author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,action:e.action}}function Fs(e,t,n){let r=n?.trim()??``;return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Is(e,t){return(e.promptInput?.trim()??``)===``?(t.debug(`Skipping schedule event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}):{shouldSkip:!1}}function Ls(e,t){return(e.commentBody?.trim()??``)===``?(t.debug(`Skipping workflow_dispatch event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}):{shouldSkip:!1}}function Rs(e,t,n,r){let{targetLabel:i,actionLabel:a}=r;return e.action===`created`?e.target?.locked===!0?(n.debug(`Skipping locked ${i}`),{shouldSkip:!0,reason:`issue_locked`,message:`${i} is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping ${a} without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created ${a} action`,{action:e.action}),{shouldSkip:!0,reason:`action_not_created`,message:`${a} action is '${e.action}', not 'created'`})}function zs(e,t,n){return Rs(e,t,n,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function Bs(e,t,n){return Rs(e,t,n,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}function Vs(e,t,n){let r=e.action;return r===`created`?e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping review comment without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created review comment action`,{action:r}),{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${r}' is not supported (only 'created')`})}function Hs(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e.eventName}`};switch(e.eventType){case`issue_comment`:return zs(e,t,n);case`discussion_comment`:return Bs(e,t,n);case`issues`:return ks(e,t,n);case`pull_request`:return Ns(e,t,n);case`pull_request_review_comment`:return Vs(e,t,n);case`schedule`:return Is(t,n);case`workflow_dispatch`:return Ls(e,n);default:return{shouldSkip:!1}}}function Us(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:{let n=Cs(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`discussion_comment`:{let n=ws(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`workflow_dispatch`:{let t=Ts(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`issues`:{let n=Es(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request`:{let n=As(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request_review_comment`:{let n=Ps(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`schedule`:{let t=Fs(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null}}}function Ws(e,t,n={}){let r={...gs,...n},i=Us(e,r.botLogin,r.promptInput);t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Hs(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function Gs(){let e=Date.now(),t=A({phase:`bootstrap`}),n=null,i=!1,o=0,s=null,c=null,l=null,u=null,d=Mo();d.start(),f(I.SHOULD_SAVE_CACHE,`false`),f(I.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let p=Oo();if(!p.success)return _(`Invalid inputs: ${p.error.message}`),1;let m=p.data,h=A({phase:`main`});h.info(`Action inputs parsed`,{sessionRetention:m.sessionRetention,s3Backup:m.s3Backup,hasGithubToken:m.githubToken.length>0,hasPrompt:m.prompt!=null,agent:m.agent,hasModelOverride:m.model!=null,timeoutMs:m.timeoutMs});let g=await Pa({logger:h,opencodeVersion:m.opencodeVersion});g.didSetup?h.info(`OpenCode auto-setup completed`,{version:g.version}):h.info(`OpenCode already available`,{version:g.version}),f(I.OPENCODE_VERSION,g.version),l=g.version;let b=A({phase:`context`}),x=xo(b);s=Bi({token:m.githubToken,logger:b});let S=await Vi(s,b),C=A({phase:`trigger`}),w=Ws(x,C,{botLogin:S,requireMention:!0,promptInput:m.prompt});if(!w.shouldProcess)return C.info(`Skipping event`,{reason:w.skipReason,message:w.skipMessage}),No({sessionId:null,cacheStatus:`miss`,duration:Date.now()-e}),0;C.info(`Event routed for processing`,{eventType:w.context.eventType,hasMention:w.context.hasMention,command:w.context.command?.action??null}),f(I.SHOULD_SAVE_CACHE,`true`);let T=await tt({logger:b,octokit:s,triggerContext:w.context,botLogin:S});n={repo:T.repo,commentId:T.commentId,issueNumber:T.issueNumber,issueType:T.issueType,botLogin:S};let E=A({phase:`acknowledgment`});await Ra(s,n,E);let ee={agentIdentity:`github`,repo:te(),ref:fe(),os:a()},D=A({phase:`cache`}),ne=v(),re=z.join(ne,`.git`,`opencode`),O=await ae({components:ee,logger:D,storagePath:y(),authPath:r(),projectIdPath:re,opencodeVersion:g.version}),k=O.corrupted?`corrupted`:O.hit?`hit`:`miss`;d.setCacheStatus(k),h.info(`Cache restore completed`,{cacheStatus:k,key:O.key});let j=await hs({workspacePath:ne,logger:D});j.source===`error`?D.warning(`Failed to generate project ID (continuing)`,{error:j.error}):D.debug(`Project ID ready`,{projectId:j.projectId,source:j.source});let M=A({phase:`server-bootstrap`}),ie=await ja(new AbortController().signal,M);if(!ie.success)return _(`OpenCode server bootstrap failed: ${ie.error.message}`),1;u=ie.data,M.info(`SDK server bootstrapped successfully`);let N=A({phase:`session`}),oe=Po(ne),se=await os(u.client,oe,{limit:10},N);N.debug(`Listed recent sessions`,{count:se.length});let P=T.issueTitle??T.repo,F=await cs(P,u.client,oe,{limit:5},N);N.debug(`Searched prior sessions`,{query:P,resultCount:F.length});for(let e of F)d.addSessionUsed(e.sessionId);let ce=A({phase:`attachments`}),L=T.commentBody??``,le=qa(L);if(le.length>0){ce.info(`Processing attachments`,{count:le.length});let{validated:e,skipped:t}=io(await Qa(le,m.githubToken,void 0,ce),void 0,ce);(e.length>0||t.length>0)&&(c=no(L,le,e,t),ce.info(`Attachments processed`,{processed:e.length,skipped:t.length}))}let ue={context:T,customPrompt:m.prompt,cacheStatus:k,sessionContext:{recentSessions:se,priorWorkContext:F},triggerContext:w.context,fileParts:c?.fileParts},de=V.env.SKIP_AGENT_EXECUTION===`true`,R,pe=Date.now();if(de)h.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),R={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let e=await Ma(ue,A({phase:`execution`}),{agent:m.agent,model:m.model,timeoutMs:m.timeoutMs,omoProviders:m.omoProviders},u??void 0),t=e.sessionId;if(t==null){let e=await rs(u.client,oe,pe,N);e!=null&&(t=e.session.id,N.debug(`Identified session from execution`,{sessionId:t}))}R={...e,sessionId:t}}R.sessionId!=null&&f(I.SESSION_ID,R.sessionId),i=R.success,R.sessionId!=null&&d.addSessionCreated(R.sessionId),R.tokenUsage!=null&&d.setTokenUsage(R.tokenUsage,R.model,R.cost);for(let e of R.prsCreated)d.addPRCreated(e);for(let e of R.commitsCreated)d.addCommitCreated(e);for(let e=0;e0&&n.owner.length>0&&n.repo.length>0){let e=un(R.llmError),t=A({phase:`error-comment`}),r=await vo(s,n,{body:e},t);r==null?t.warning(`Failed to post LLM error comment`):(t.info(`Posted LLM error comment`,{commentUrl:r.url}),d.incrementComments())}else h.warning(`Cannot post error comment: missing target context`);o=0}}catch(n){o=1;let r=Date.now()-e,i=n instanceof Error?n.name:`UnknownError`,a=n instanceof Error?n.message:String(n);d.recordError(i,a,!1),d.end(),No({sessionId:null,cacheStatus:`miss`,duration:r}),n instanceof Error?(t.error(`Agent failed`,{error:n.message}),_(n.message)):(t.error(`Agent failed with unknown error`),_(`An unknown error occurred`))}finally{try{if(c!=null){let e=A({phase:`attachment-cleanup`});await $a(c.tempFiles,e)}if(n!=null&&s!=null){let e=A({phase:`cleanup`});await Wa(s,n,i,e)}let e=A({phase:`prune`}),t=v();if(u!=null){let n=Po(t),r=await as(u.client,n,is,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let o={agentIdentity:`github`,repo:te(),ref:fe(),os:a()},d=A({phase:`cache-save`}),p=z.join(t,`.git`,`opencode`);await F({components:o,runId:de(),logger:d,storagePath:y(),authPath:r(),projectIdPath:p,opencodeVersion:l})&&f(I.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(u!=null)try{u.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}return o}await Gs().then(e=>{V.exit(e)});export{}; \ No newline at end of file +`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:M(e)}),null}}async function vo(e,t,n,r){if(t.type===`discussion`)return _o(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await po(e,t,n.botLogin,r);if(i!=null){let a=mo(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return go(e,t,a.id,n.body,r)}}return ho(e,t,n.body,r)}function yo(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function bo(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function xo(e){let t=ci,n=yo(t.eventName),r=bo(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function So(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function Co(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function wo(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 To(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Eo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function Do(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`;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}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function Oo(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return fa(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return fa(Error(`auth-json is required but was not provided`));So(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?Co(i,`session-retention`):O,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:R,p=m(`model`).trim(),h=p.length>0?wo(p):null,g=m(`timeout`).trim(),_=g.length>0?To(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:k,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:N,C=m(`omo-providers`).trim(),w=Do(C.length>0?C:se),T=m(`opencode-config`).trim(),ee=T.length>0?T:null;return ee!=null&&So(ee,`opencode-config`),da({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:w,opencodeConfig:ee})}catch(e){return fa(e instanceof Error?e:Error(String(e)))}}function ko(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Ao(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function jo(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(P.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,ko(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Ao(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(P.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&P.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&P.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(P.addHeading(`Token Usage`,3),P.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&P.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&P.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(P.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&P.addList([...c.prsCreated]),c.commitsCreated.length>0&&P.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&P.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){P.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;P.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await P.write(),t.debug(`Wrote job summary`)}catch(e){let r=M(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Mo(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function No(e){z(`session-id`,e.sessionId??``),z(`cache-status`,e.cacheStatus),z(`duration`,e.duration)}function Po(e){let t=B.resolve(e);return t.endsWith(B.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function Fo(e){return typeof e==`boolean`?e:null}function Io(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function Lo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Io(e.diffs)}}function Ro(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function zo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Bo(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:zo(e.time),summary:Lo(e.summary),share:Ro(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Vo(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Io(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Ho(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:Fo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function Uo(e){return Z(e)?Q(e.role)===`assistant`?Ho(e):Vo(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Wo(e){let t=Uo(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(qo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function Go(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Ko(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function qo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=Go(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:Fo(e.synthetic)??void 0,ignored:Fo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Ko(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Jo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Bo):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function Yo(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Wo)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function Xo(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Bo);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function Zo(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function Qo(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function $o(e,t,n){let r=Po(t),i=await Qo(e,n);for(let e of i){if(Po(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Po(t)===r)return e}return null}async function es(e,t,n){return Jo(e,t,n)}async function ts(e,t,n){return Yo(e,t,n)}async function ns(e,t,n){return Zo(e,t,n)}async function rs(e,t,n,r){return Xo(e,t,n,r)}const is={maxSessions:50,maxAgeDays:30};async function as(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await $o(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await es(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await ns(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:M(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function os(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await es(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await ts(e,t.id,r),i=ss(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ss(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function cs(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ls(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await os(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ls(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ls(e,t,n,r,i){let a=await ts(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=us(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function us(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ds(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` +`)}async function fs(e,t,n,r){let i=ds(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:i}]}});if(t.error!=null){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}r.info(`Session summary written via SDK`,{sessionId:e})}catch(t){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:M(t)})}}const ps=/^[0-9a-f]{40}$/i;function ms(){return{exec:x,getExecOutput:c}}async function hs(e){let{workspacePath:t,logger:n,execAdapter:r=ms()}=e,i=B.join(t,`.git`),a=B.join(i,`opencode`);try{let e=(await G.readFile(a,`utf8`)).trim();if(e.length>0){if(ps.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:M(e)})}try{if((await G.stat(i)).isDirectory()===!1){let e=await G.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=B.resolve(t,n[1]),a=B.join(i,`opencode`)}}catch{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 G.writeFile(a,s,`utf8`),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){n.warning(`Failed to cache project ID (continuing)`,{error:M(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:M(e)}}}const gs={botLogin:null,requireMention:!0,allowedAssociations:pa,skipDraftPRs:!0,promptInput:null};function _s(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${vs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function vs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function ys(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${vs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function bs(e,t){return t.includes(e)}function xs(e){return e.endsWith(`[bot]`)}function Ss(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=_s(e,t);return{hasMention:n,command:n?ys(e,t):null}}function Cs(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},i=e.comment.body,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function ws(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:e.comment.body??e.discussion.body??null,locked:e.discussion.locked},i=e.comment.body??null,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Ts(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Es(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:xs(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=Ss(e.issue.body??``,t);return{author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,action:e.action}}const Ds=[`opened`,`edited`];function Os(e){return Ds.includes(e)}function ks(e,t,n){let r=e.action;return r==null||!Os(r)?(n.debug(`Skipping unsupported issues action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${r}' is not supported (only 'opened' and 'edited')`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):r===`edited`&&!e.hasMention?(n.debug(`Skipping issues.edited without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}):e.target?.locked===!0?(n.debug(`Skipping locked issue`),{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}):{shouldSkip:!1}}function As(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:xs(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft},{hasMention:i,command:a}=Ss(e.pullRequest.body??``,t);return{author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,action:e.action}}const js=[`opened`,`synchronize`,`reopened`];function Ms(e){return js.includes(e)}function Ns(e,t,n){let r=e.action;return r==null||!Ms(r)?(n.debug(`Skipping unsupported pull_request action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${r}' is not supported`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.skipDraftPRs&&e.target?.isDraft===!0?(n.debug(`Skipping draft PR`),{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}):e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):{shouldSkip:!1}}function Ps(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=Ss(e.comment.body,t);return{author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,action:e.action}}function Fs(e,t,n){let r=n?.trim()??``;return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Is(e,t){return(e.promptInput?.trim()??``)===``?(t.debug(`Skipping schedule event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}):{shouldSkip:!1}}function Ls(e,t){return(e.commentBody?.trim()??``)===``?(t.debug(`Skipping workflow_dispatch event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}):{shouldSkip:!1}}function Rs(e,t,n,r){let{targetLabel:i,actionLabel:a}=r;return e.action===`created`?e.target?.locked===!0?(n.debug(`Skipping locked ${i}`),{shouldSkip:!0,reason:`issue_locked`,message:`${i} is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping ${a} without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created ${a} action`,{action:e.action}),{shouldSkip:!0,reason:`action_not_created`,message:`${a} action is '${e.action}', not 'created'`})}function zs(e,t,n){return Rs(e,t,n,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function Bs(e,t,n){return Rs(e,t,n,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}function Vs(e,t,n){let r=e.action;return r===`created`?e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping review comment without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created review comment action`,{action:r}),{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${r}' is not supported (only 'created')`})}function Hs(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e.eventName}`};switch(e.eventType){case`issue_comment`:return zs(e,t,n);case`discussion_comment`:return Bs(e,t,n);case`issues`:return ks(e,t,n);case`pull_request`:return Ns(e,t,n);case`pull_request_review_comment`:return Vs(e,t,n);case`schedule`:return Is(t,n);case`workflow_dispatch`:return Ls(e,n);default:return{shouldSkip:!1}}}function Us(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:{let n=Cs(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`discussion_comment`:{let n=ws(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`workflow_dispatch`:{let t=Ts(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`issues`:{let n=Es(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request`:{let n=As(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request_review_comment`:{let n=Ps(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`schedule`:{let t=Fs(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null}}}function Ws(e,t,n={}){let r={...gs,...n},i=Us(e,r.botLogin,r.promptInput);t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Hs(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function Gs(){let e=Date.now(),t=A({phase:`bootstrap`}),n=null,i=!1,o=0,s=null,c=null,l=null,u=null,d=Mo();d.start(),f(L.SHOULD_SAVE_CACHE,`false`),f(L.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let p=Oo();if(!p.success)return _(`Invalid inputs: ${p.error.message}`),1;let m=p.data,h=A({phase:`main`});h.info(`Action inputs parsed`,{sessionRetention:m.sessionRetention,s3Backup:m.s3Backup,hasGithubToken:m.githubToken.length>0,hasPrompt:m.prompt!=null,agent:m.agent,hasModelOverride:m.model!=null,timeoutMs:m.timeoutMs});let g=await Pa({logger:h,opencodeVersion:m.opencodeVersion});g.didSetup?h.info(`OpenCode auto-setup completed`,{version:g.version}):h.info(`OpenCode already available`,{version:g.version}),f(L.OPENCODE_VERSION,g.version),l=g.version;let b=A({phase:`context`}),x=xo(b);s=Bi({token:m.githubToken,logger:b});let S=await Vi(s,b),C=A({phase:`trigger`}),w=Ws(x,C,{botLogin:S,requireMention:!0,promptInput:m.prompt});if(!w.shouldProcess)return C.info(`Skipping event`,{reason:w.skipReason,message:w.skipMessage}),No({sessionId:null,cacheStatus:`miss`,duration:Date.now()-e}),0;C.info(`Event routed for processing`,{eventType:w.context.eventType,hasMention:w.context.hasMention,command:w.context.command?.action??null}),f(L.SHOULD_SAVE_CACHE,`true`);let T=await et({logger:b,octokit:s,triggerContext:w.context,botLogin:S});n={repo:T.repo,commentId:T.commentId,issueNumber:T.issueNumber,issueType:T.issueType,botLogin:S};let E=A({phase:`acknowledgment`});await Ra(s,n,E);let ee={agentIdentity:`github`,repo:te(),ref:de(),os:a()},D=A({phase:`cache`}),ne=v(),re=B.join(ne,`.git`,`opencode`),O=await ae({components:ee,logger:D,storagePath:y(),authPath:r(),projectIdPath:re,opencodeVersion:g.version}),k=O.corrupted?`corrupted`:O.hit?`hit`:`miss`;d.setCacheStatus(k),h.info(`Cache restore completed`,{cacheStatus:k,key:O.key});let j=await hs({workspacePath:ne,logger:D});j.source===`error`?D.warning(`Failed to generate project ID (continuing)`,{error:j.error}):D.debug(`Project ID ready`,{projectId:j.projectId,source:j.source});let M=A({phase:`server-bootstrap`}),ie=await ja(new AbortController().signal,M);if(!ie.success)return _(`OpenCode server bootstrap failed: ${ie.error.message}`),1;u=ie.data,M.info(`SDK server bootstrapped successfully`);let N=A({phase:`session`}),oe=Po(ne),se=await os(u.client,oe,{limit:10},N);N.debug(`Listed recent sessions`,{count:se.length});let P=T.issueTitle??T.repo,F=await cs(P,u.client,oe,{limit:5},N);N.debug(`Searched prior sessions`,{query:P,resultCount:F.length});for(let e of F)d.addSessionUsed(e.sessionId);let I=A({phase:`attachments`}),R=T.commentBody??``,ce=qa(R);if(ce.length>0){I.info(`Processing attachments`,{count:ce.length});let{validated:e,skipped:t}=io(await Qa(ce,m.githubToken,void 0,I),void 0,I);(e.length>0||t.length>0)&&(c=no(R,ce,e,t),I.info(`Attachments processed`,{processed:e.length,skipped:t.length}))}let le={context:T,customPrompt:m.prompt,cacheStatus:k,sessionContext:{recentSessions:se,priorWorkContext:F},triggerContext:w.context,fileParts:c?.fileParts},ue=H.env.SKIP_AGENT_EXECUTION===`true`,z,fe=Date.now();if(ue)h.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),z={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let e=await Ma(le,A({phase:`execution`}),{agent:m.agent,model:m.model,timeoutMs:m.timeoutMs,omoProviders:m.omoProviders},u??void 0),t=e.sessionId;if(t==null){let e=await rs(u.client,oe,fe,N);e!=null&&(t=e.session.id,N.debug(`Identified session from execution`,{sessionId:t}))}z={...e,sessionId:t}}z.sessionId!=null&&f(L.SESSION_ID,z.sessionId),i=z.success,z.sessionId!=null&&d.addSessionCreated(z.sessionId),z.tokenUsage!=null&&d.setTokenUsage(z.tokenUsage,z.model,z.cost);for(let e of z.prsCreated)d.addPRCreated(e);for(let e of z.commitsCreated)d.addCommitCreated(e);for(let e=0;e0&&n.owner.length>0&&n.repo.length>0){let e=ln(z.llmError),t=A({phase:`error-comment`}),r=await vo(s,n,{body:e},t);r==null?t.warning(`Failed to post LLM error comment`):(t.info(`Posted LLM error comment`,{commentUrl:r.url}),d.incrementComments())}else h.warning(`Cannot post error comment: missing target context`);o=0}}catch(n){o=1;let r=Date.now()-e,i=n instanceof Error?n.name:`UnknownError`,a=n instanceof Error?n.message:String(n);d.recordError(i,a,!1),d.end(),No({sessionId:null,cacheStatus:`miss`,duration:r}),n instanceof Error?(t.error(`Agent failed`,{error:n.message}),_(n.message)):(t.error(`Agent failed with unknown error`),_(`An unknown error occurred`))}finally{try{if(c!=null){let e=A({phase:`attachment-cleanup`});await $a(c.tempFiles,e)}if(n!=null&&s!=null){let e=A({phase:`cleanup`});await Wa(s,n,i,e)}let e=A({phase:`prune`}),t=v();if(u!=null){let n=Po(t),r=await as(u.client,n,is,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let o={agentIdentity:`github`,repo:te(),ref:de(),os:a()},d=A({phase:`cache-save`}),p=B.join(t,`.git`,`opencode`);await F({components:o,runId:ue(),logger:d,storagePath:y(),authPath:r(),projectIdPath:p,opencodeVersion:l})&&f(L.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(u!=null)try{u.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}return o}await Gs().then(e=>{H.exit(e)});export{}; \ No newline at end of file diff --git a/src/lib/inputs.test.ts b/src/lib/inputs.test.ts index 28bbf985..fdf178ef 100644 --- a/src/lib/inputs.test.ts +++ b/src/lib/inputs.test.ts @@ -356,6 +356,63 @@ describe('parseActionInputs', () => { expect(result.success).toBe(false) expect(!result.success && result.error.message).toContain('Invalid model format') }) + + it('returns error for invalid opencode-config (not valid JSON)', () => { + const mockGetInput = core.getInput as ReturnType + + mockGetInput.mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghp_test123', + 'auth-json': '{"anthropic":{"type":"api","key":"sk-ant-test"}}', + 'opencode-config': 'not-valid-json', + } + return inputs[name] ?? '' + }) + + const result = parseActionInputs() + + expect(result.success).toBe(false) + expect(!result.success && result.error.message).toContain('opencode-config') + expect(!result.success && result.error.message).toContain('valid JSON') + }) + }) + + describe('with valid opencode-config', () => { + it('parses valid JSON object in opencode-config', () => { + const mockGetInput = core.getInput as ReturnType + + mockGetInput.mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghp_test123', + 'auth-json': '{"anthropic":{"type":"api","key":"sk-ant-test"}}', + 'opencode-config': '{"model": "claude-opus-4", "temperature": 0.7}', + } + return inputs[name] ?? '' + }) + + const result = parseActionInputs() + + expect(result.success).toBe(true) + expect(result.success && result.data.opencodeConfig).toBe('{"model": "claude-opus-4", "temperature": 0.7}') + }) + + it('sets opencodeConfig to null when empty string', () => { + const mockGetInput = core.getInput as ReturnType + + mockGetInput.mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghp_test123', + 'auth-json': '{"anthropic":{"type":"api","key":"sk-ant-test"}}', + 'opencode-config': '', + } + return inputs[name] ?? '' + }) + + const result = parseActionInputs() + + expect(result.success).toBe(true) + expect(result.success && result.data.opencodeConfig).toBe(null) + }) }) }) diff --git a/src/lib/inputs.ts b/src/lib/inputs.ts index 77da4d51..3bad9988 100644 --- a/src/lib/inputs.ts +++ b/src/lib/inputs.ts @@ -179,6 +179,14 @@ export function parseActionInputs(): Result { const omoProvidersRaw = core.getInput('omo-providers').trim() const omoProviders = parseOmoProviders(omoProvidersRaw.length > 0 ? omoProvidersRaw : DEFAULT_OMO_PROVIDERS) + const opencodeConfigRaw = core.getInput('opencode-config').trim() + const opencodeConfig = opencodeConfigRaw.length > 0 ? opencodeConfigRaw : null + + // Validate opencode-config is valid JSON if provided + if (opencodeConfig != null) { + validateJsonString(opencodeConfig, 'opencode-config') + } + return ok({ githubToken, authJson, @@ -194,6 +202,7 @@ export function parseActionInputs(): Result { skipCache, omoVersion, omoProviders, + opencodeConfig, }) } catch (error) { return err(error instanceof Error ? error : new Error(String(error))) diff --git a/src/lib/setup/setup.test.ts b/src/lib/setup/setup.test.ts index 0795ab16..97edd739 100644 --- a/src/lib/setup/setup.test.ts +++ b/src/lib/setup/setup.test.ts @@ -272,6 +272,110 @@ describe('setup', () => { ) }) + it('fails when opencode-config is null', async () => { + // #given - user supplies null as opencode-config + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{\"anthropic\": {\"api_key\": \"sk-ant-test\"}}', + 'opencode-version': 'latest', + 'opencode-config': 'null', + } + return inputs[name] ?? '' + }) + vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') + vi.mocked(exec.getExecOutput).mockResolvedValue({exitCode: 0, stdout: '', stderr: ''}) + vi.mocked(exec.exec).mockResolvedValue(0) + vi.mocked(fs.writeFile).mockResolvedValue() + vi.mocked(fs.mkdir).mockResolvedValue(undefined) + vi.mocked(fs.access).mockRejectedValue(new Error('not found')) + + // #when + const result = await runSetup() + + // #then + expect(result).toBe(null) + expect(core.setFailed).toHaveBeenCalledWith('opencode-config must be a JSON object') + }) + + it('fails when opencode-config is an array', async () => { + // #given - user supplies array as opencode-config + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{\"anthropic\": {\"api_key\": \"sk-ant-test\"}}', + 'opencode-version': 'latest', + 'opencode-config': '[\"model\", \"claude-opus-4\"]', + } + return inputs[name] ?? '' + }) + vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') + vi.mocked(exec.getExecOutput).mockResolvedValue({exitCode: 0, stdout: '', stderr: ''}) + vi.mocked(exec.exec).mockResolvedValue(0) + vi.mocked(fs.writeFile).mockResolvedValue() + vi.mocked(fs.mkdir).mockResolvedValue(undefined) + vi.mocked(fs.access).mockRejectedValue(new Error('not found')) + + // #when + const result = await runSetup() + + // #then + expect(result).toBe(null) + expect(core.setFailed).toHaveBeenCalledWith('opencode-config must be a JSON object') + }) + + it('fails when opencode-config is a number', async () => { + // #given - user supplies number as opencode-config + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{\"anthropic\": {\"api_key\": \"sk-ant-test\"}}', + 'opencode-version': 'latest', + 'opencode-config': '42', + } + return inputs[name] ?? '' + }) + vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') + vi.mocked(exec.getExecOutput).mockResolvedValue({exitCode: 0, stdout: '', stderr: ''}) + vi.mocked(exec.exec).mockResolvedValue(0) + vi.mocked(fs.writeFile).mockResolvedValue() + vi.mocked(fs.mkdir).mockResolvedValue(undefined) + vi.mocked(fs.access).mockRejectedValue(new Error('not found')) + + // #when + const result = await runSetup() + + // #then + expect(result).toBe(null) + expect(core.setFailed).toHaveBeenCalledWith('opencode-config must be a JSON object') + }) + + it('fails when opencode-config is a string', async () => { + // #given - user supplies string as opencode-config + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{\"anthropic\": {\"api_key\": \"sk-ant-test\"}}', + 'opencode-version': 'latest', + 'opencode-config': '\"just-a-string\"', + } + return inputs[name] ?? '' + }) + vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') + vi.mocked(exec.getExecOutput).mockResolvedValue({exitCode: 0, stdout: '', stderr: ''}) + vi.mocked(exec.exec).mockResolvedValue(0) + vi.mocked(fs.writeFile).mockResolvedValue() + vi.mocked(fs.mkdir).mockResolvedValue(undefined) + vi.mocked(fs.access).mockRejectedValue(new Error('not found')) + + // #when + const result = await runSetup() + + // #then + expect(result).toBe(null) + expect(core.setFailed).toHaveBeenCalledWith('opencode-config must be a JSON object') + }) + it('sets outputs for opencode-path and auth-json-path', async () => { // #given vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') diff --git a/src/lib/setup/setup.ts b/src/lib/setup/setup.ts index acca337d..cc831cdc 100644 --- a/src/lib/setup/setup.ts +++ b/src/lib/setup/setup.ts @@ -237,10 +237,18 @@ export async function runSetup(): Promise { // Export CI-safe OpenCode config. OPENCODE_CONFIG_CONTENT has highest precedence over all // other OpenCode config sources (project, global, etc.). User-supplied opencode-config input // is merged on top of the baseline, so user values override the defaults. - const ciConfig: Record = { - autoupdate: false, - ...(inputs.opencodeConfig == null ? {} : (JSON.parse(inputs.opencodeConfig) as Record)), + const ciConfig: Record = {autoupdate: false} + + if (inputs.opencodeConfig != null) { + const parsed = JSON.parse(inputs.opencodeConfig) as unknown + // Validate that the parsed result is a plain object (not null, array, or primitive) + if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) { + core.setFailed('opencode-config must be a JSON object') + return null + } + Object.assign(ciConfig, parsed) } + core.exportVariable('OPENCODE_CONFIG_CONTENT', JSON.stringify(ciConfig)) if (!toolsCacheResult.hit) { diff --git a/src/lib/types.ts b/src/lib/types.ts index 8c5d42b5..a10baa48 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -60,6 +60,8 @@ export interface ActionInputs { readonly omoVersion: string // oMo provider configuration readonly omoProviders: OmoProviders + // OpenCode config to merge with baseline + readonly opencodeConfig: string | null } // oMo provider configuration for installer From f84ad43cad93a69e285e9f8be5f121941e622289 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 15:58:08 -0700 Subject: [PATCH 4/8] feat(setup): add --skip-auth flag to oMo installer for CI reliability (#260) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- dist/main.js | 2 +- src/lib/setup/omo.test.ts | 21 +++++++++++++++++++++ src/lib/setup/omo.ts | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/dist/main.js b/dist/main.js index fab9a994..d66ffee8 100644 --- a/dist/main.js +++ b/dist/main.js @@ -127,7 +127,7 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a `);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function $t(e){let t=await Qt({...e});return{client:Zt({baseUrl:t.url}),server:t}}async function en(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const tn={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},nn=`\x1B[0m`;function rn(){return H.env.NO_COLOR==null}function an(e,t){let[n,r]=tn[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);rn()?H.stdout.write(`\n${r}|${nn} ${i} ${nn}${t}\n`):H.stdout.write(`\n| ${i} ${t}\n`)}function on(e){H.stdout.write(`\n${e}\n`)}const sn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function cn(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function ln(e){let t=cn(e),n=sn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` `)}function un(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const dn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function fn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return dn.some(e=>e.test(t))}function pn(e,t){return un(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function mn(e,t){return un(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}function hn(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function gn(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 _n(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(hn)}function vn(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)]}var yn=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(ge(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(_e(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${me}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},bn=T((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),xn=e(T((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[d.Accept]=this._getExistingOrDefaultHeader(t,d.Accept,f.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===u.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&m.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!h.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},x(this.requestOptions.headers),x(e||{})):x(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[d.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[d.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new l.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===u.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let x=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),Sn=w(),Cn=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function wn(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function Tn(e){return new xn.HttpClient().getAgent(e)}function En(e){return new xn.HttpClient().getAgentDispatcher(e)}function Dn(e){let t=En(e);return(e,n)=>Cn(this,void 0,void 0,function*(){return(0,Sn.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function On(){return process.env.GITHUB_API_URL||`https://api.github.com`}function kn(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function An(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>An.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function jn(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function Mn(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const Nn=Function.bind,Pn=Nn.bind(Nn);function Fn(e,t,n){let r=Pn(Mn,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=Pn(jn,null).apply(null,i)})}function In(){let e=Symbol(`Singular`),t={registry:{}},n=An.bind(null,t,e);return Fn(n,t,e),n}function Ln(){let e={registry:{}},t=An.bind(null,e);return Fn(t,e),t}var Rn={Singular:In,Collection:Ln},zn=`octokit-endpoint.js/0.0.0-development ${kn()}`,Bn={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":zn},mediaType:{format:``}};function Vn(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Hn(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Un(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Hn(t[r])&&r in e?n[r]=Un(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Wn(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function Gn(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Vn(n.headers),Wn(n),Wn(n.headers);let r=Un(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function Kn(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var qn=/\{[^{}}]+\}/g;function Jn(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Xn(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function Zn(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function Qn(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function $n(e,t,n){return t=e===`+`||e===`#`?Zn(t):Qn(t),n?Qn(n)+`=`+t:t}function er(e){return e!=null}function tr(e){return e===`;`||e===`&`||e===`?`}function nr(e,t,n,r){var i=e[n],a=[];if(er(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push($n(t,i,tr(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(er).forEach(function(e){a.push($n(t,e,tr(t)?n:``))}):Object.keys(i).forEach(function(e){er(i[e])&&a.push($n(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(er).forEach(function(n){e.push($n(t,n))}):Object.keys(i).forEach(function(n){er(i[n])&&(e.push(Qn(n)),e.push($n(t,i[n].toString())))}),tr(t)?a.push(Qn(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?er(i)&&a.push(Qn(n)):i===``&&(t===`&`||t===`?`)?a.push(Qn(n)+`=`):i===``&&a.push(``);return a}function rr(e){return{expand:ir.bind(null,e)}}function ir(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(nr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return Zn(i)}),e===`/`?e:e.replace(/\/$/,``)}function ar(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Xn(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Yn(n);n=rr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Xn(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=Kn(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function or(e,t,n){return ar(Gn(e,t,n))}function sr(e,t){let n=Gn(e,t),r=or.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:sr.bind(null,n),merge:Gn.bind(null,n),parse:ar})}var cr=sr(null,Bn),lr=T(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))(),ur=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function hr(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=pr(e.body)||Array.isArray(e.body)?JSON.stringify(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new ur(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new ur(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await gr(o),new ur(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await gr(o),new ur(vr(u.data),s,{response:u,request:e});return u.data=r?await gr(o):o.body,u}async function gr(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(mr);let n=(0,lr.safeParse)(t);if(_r(n)){let t=``;try{return t=await e.text(),JSON.parse(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(mr);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function _r(e){return e.type===`application/json`||e.type===`application/scim+json`}function vr(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function yr(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return hr(n.parse(r));let i=(e,t)=>hr(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:yr.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:yr.bind(null,n)})}var br=yr(cr,fr),xr=`0.0.0-development`;function Sr(e){return`Request failed due to following response errors: `+e.errors.map(e=>` - ${e.message}`).join(` -`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${kn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${kn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Rn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new yn;const ii=On(),ai={baseUrl:ii,request:{agent:Tn(ii),fetch:Dn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=wn(e,n);return r&&(n.auth=r),n}const ci=new yn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(ie(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=W.join(ki(),he.randomUUID()),yield S(W.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(U.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=ye.promisify(Oe.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,U.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=pe.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!U.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of U.readdirSync(e))yield b(W.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=pe.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=W.join(Oi(),e,t,n);j(`checking cache: ${i}`),U.existsSync(i)&&U.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=pe.arch();let r=W.join(Oi(),e);if(U.existsSync(r)){let e=U.readdirSync(r);for(let i of e)if(Ei(i)){let e=W.join(r,i,t||``);U.existsSync(e)&&U.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=W.join(ki(),he.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=W.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${W.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;U.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ve(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ve(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=B.join(t,`auth.json`);await G.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await G.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=H.platform,t=H.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(H.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=fe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Ce.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=fe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>H.platform===`win32`?`${e}.exe`:e,n=fe.join(e,t(`bun`));try{await Ce.symlink(n,fe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};H.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}async function Gi(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`}=n;r.info(`Installing Oh My OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u});let d=``,f=[`oh-my-opencode@${e}`,`install`,`--no-tui`,`--claude=${a}`,`--copilot=${o}`,`--gemini=${s}`,`--openai=${c}`,`--opencode-zen=${l}`,`--zai-coding-plan=${u}`];try{let t=await i.exec(`bunx`,f,{listeners:{stdout:e=>{d+=e.toString()},stderr:e=>{d+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-opencode install returned exit code ${t}`;return r.error(e,{output:d.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${d.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(d),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=M(e),n=d.length>0?`${t}\nOutput: ${d.slice(0,500)}`:t;return r.error(`Failed to run oMo installer`,{error:t,output:d.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-opencode install failed: ${n}`}}}const Ki=`opencode`,qi=`1.2.9`;function Ji(){let e=Ee.platform(),t=Ee.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 Yi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Xi(e,t,n,r){if(H.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 Zi(e,t,n,r,i=qi){let a=Ji(),o=n.find(Ki,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 Qi(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(n)})}if(e!==i)try{let e=await Qi(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}): ${M(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Qi(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=Yi(e,t),o=await r.downloadTool(a);if(!await Xi(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,Ki,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function $i(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ea={restoreCache:async(e,t,n)=>I(e,t,n),saveCache:async(e,t)=>D(e,t)};function ta(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ce}-${t}-oc-${n}-omo-${r}`}function na(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ce}-${t}-oc-${n}-omo-${r}-`]}async function ra(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=na({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function ia(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const aa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function oa(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`;for(let e of t)if(aa.includes(e))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}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function sa(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ca(){return{exec:x,getExecOutput:c}}function la(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null}}async function ua(){let e=Date.now(),n=A({component:`setup`}),r=sa(),o=ca();try{let s=la(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await $i(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=qi}let d=m(`omo-version`).trim(),f=d.length>0?d:N,h=H.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=V(h,`opencode`),v=V(h,`bun`),y=V(De(),`.config`,`opencode`),b=a(),x=await ra({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await Zi(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){let e=m(`omo-providers`).trim(),t=oa(e.length>0?e:se),r=await Gi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1};if(s.opencodeConfig!=null){let e=JSON.parse(s.opencodeConfig);if(typeof e!=`object`||!e||Array.isArray(e))return _(`opencode-config must be a JSON object`),null;Object.assign(te,e)}p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await ia({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),z(`opencode-path`,C.path),z(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=V(i(),`opencode`),k=await Mi(l,O,n);z(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=H.env.GITHUB_REPOSITORY??`unknown/unknown`,j=H.env.GITHUB_REF_NAME??`main`,ie=a(),ae=ee({agentIdentity:`github`,repo:A,ref:j,os:ie}),P=oe({agentIdentity:`github`,repo:A,ref:j,os:ie}),F=`miss`;try{let e=await I([O],ae,[...P]);e==null?n.info(`No cache found`):(F=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){F=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}z(`cache-status`,F),z(`storage-path`,O);let L=Date.now()-e,R={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:F,toolsCacheStatus:S,duration:L};return n.info(`Setup complete`,{duration:L}),R}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function da(e){return{success:!0,data:e}}function fa(e){return{success:!1,error:e}}const pa=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ma(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` +`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${kn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${kn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Rn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new yn;const ii=On(),ai={baseUrl:ii,request:{agent:Tn(ii),fetch:Dn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=wn(e,n);return r&&(n.auth=r),n}const ci=new yn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(ie(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=W.join(ki(),he.randomUUID()),yield S(W.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(U.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=ye.promisify(Oe.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,U.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=pe.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!U.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of U.readdirSync(e))yield b(W.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=pe.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=W.join(Oi(),e,t,n);j(`checking cache: ${i}`),U.existsSync(i)&&U.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=pe.arch();let r=W.join(Oi(),e);if(U.existsSync(r)){let e=U.readdirSync(r);for(let i of e)if(Ei(i)){let e=W.join(r,i,t||``);U.existsSync(e)&&U.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=W.join(ki(),he.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=W.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${W.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;U.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ve(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ve(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=B.join(t,`auth.json`);await G.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await G.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=H.platform,t=H.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(H.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=fe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Ce.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=fe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>H.platform===`win32`?`${e}.exe`:e,n=fe.join(e,t(`bun`));try{await Ce.symlink(n,fe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};H.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}async function Gi(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`}=n;r.info(`Installing Oh My OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u});let d=``,f=[`oh-my-opencode@${e}`,`install`,`--no-tui`,`--skip-auth`,`--claude=${a}`,`--copilot=${o}`,`--gemini=${s}`,`--openai=${c}`,`--opencode-zen=${l}`,`--zai-coding-plan=${u}`];try{let t=await i.exec(`bunx`,f,{listeners:{stdout:e=>{d+=e.toString()},stderr:e=>{d+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-opencode install returned exit code ${t}`;return r.error(e,{output:d.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${d.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(d),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=M(e),n=d.length>0?`${t}\nOutput: ${d.slice(0,500)}`:t;return r.error(`Failed to run oMo installer`,{error:t,output:d.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-opencode install failed: ${n}`}}}const Ki=`opencode`,qi=`1.2.9`;function Ji(){let e=Ee.platform(),t=Ee.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 Yi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Xi(e,t,n,r){if(H.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 Zi(e,t,n,r,i=qi){let a=Ji(),o=n.find(Ki,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 Qi(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(n)})}if(e!==i)try{let e=await Qi(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}): ${M(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Qi(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=Yi(e,t),o=await r.downloadTool(a);if(!await Xi(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,Ki,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function $i(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ea={restoreCache:async(e,t,n)=>I(e,t,n),saveCache:async(e,t)=>D(e,t)};function ta(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ce}-${t}-oc-${n}-omo-${r}`}function na(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ce}-${t}-oc-${n}-omo-${r}-`]}async function ra(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=na({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function ia(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const aa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function oa(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`;for(let e of t)if(aa.includes(e))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}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function sa(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ca(){return{exec:x,getExecOutput:c}}function la(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null}}async function ua(){let e=Date.now(),n=A({component:`setup`}),r=sa(),o=ca();try{let s=la(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await $i(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=qi}let d=m(`omo-version`).trim(),f=d.length>0?d:N,h=H.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=V(h,`opencode`),v=V(h,`bun`),y=V(De(),`.config`,`opencode`),b=a(),x=await ra({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await Zi(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){let e=m(`omo-providers`).trim(),t=oa(e.length>0?e:se),r=await Gi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1};if(s.opencodeConfig!=null){let e=JSON.parse(s.opencodeConfig);if(typeof e!=`object`||!e||Array.isArray(e))return _(`opencode-config must be a JSON object`),null;Object.assign(te,e)}p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await ia({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),z(`opencode-path`,C.path),z(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=V(i(),`opencode`),k=await Mi(l,O,n);z(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=H.env.GITHUB_REPOSITORY??`unknown/unknown`,j=H.env.GITHUB_REF_NAME??`main`,ie=a(),ae=ee({agentIdentity:`github`,repo:A,ref:j,os:ie}),P=oe({agentIdentity:`github`,repo:A,ref:j,os:ie}),F=`miss`;try{let e=await I([O],ae,[...P]);e==null?n.info(`No cache found`):(F=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){F=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}z(`cache-status`,F),z(`storage-path`,O);let L=Date.now()-e,R={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:F,toolsCacheStatus:S,duration:L};return n.info(`Setup complete`,{duration:L}),R}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function da(e){return{success:!0,data:e}}function fa(e){return{success:!1,error:e}}const pa=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ma(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` `),appendMode:!0};case`pull_request_review_comment`:return{directive:ha(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function ha(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` `)}function ga(e,t){let{directive:n,appendMode:r}=ma(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` `)}function _a(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a}=e,o=[];if(o.push(`# Agent Context diff --git a/src/lib/setup/omo.test.ts b/src/lib/setup/omo.test.ts index 9689492d..32168569 100644 --- a/src/lib/setup/omo.test.ts +++ b/src/lib/setup/omo.test.ts @@ -62,6 +62,7 @@ describe('omo', () => { 'oh-my-opencode@1.2.3', 'install', '--no-tui', + '--skip-auth', '--claude=no', '--copilot=no', '--gemini=no', @@ -183,6 +184,7 @@ describe('omo', () => { 'oh-my-opencode@3.5.5', 'install', '--no-tui', + '--skip-auth', '--claude=no', '--copilot=no', '--gemini=no', @@ -218,6 +220,7 @@ describe('omo', () => { 'oh-my-opencode@3.5.5', 'install', '--no-tui', + '--skip-auth', '--claude=yes', '--copilot=yes', '--gemini=yes', @@ -229,6 +232,24 @@ describe('omo', () => { ) }) + it('includes --skip-auth flag for CI reliability', async () => { + // #given - a standard install invocation + const execMock = vi.fn().mockResolvedValue(0) + const mockDeps = createMockDeps({ + execAdapter: createMockExecAdapter({exec: execMock}), + }) + + // #when + await installOmo('3.5.5', mockDeps) + + // #then - --skip-auth must appear after --no-tui in the args + const calledArgs: string[] = (execMock.mock.calls[0] as [string, string[], unknown])[1] + const noTuiIndex = calledArgs.indexOf('--no-tui') + const skipAuthIndex = calledArgs.indexOf('--skip-auth') + expect(skipAuthIndex).toBeGreaterThan(-1) + expect(skipAuthIndex).toBe(noTuiIndex + 1) + }) + it('captures both stdout and stderr', async () => { // #given const mockLogger = createMockLogger() diff --git a/src/lib/setup/omo.ts b/src/lib/setup/omo.ts index 14795d85..fff7d04c 100644 --- a/src/lib/setup/omo.ts +++ b/src/lib/setup/omo.ts @@ -60,6 +60,7 @@ export async function installOmo( `oh-my-opencode@${version}`, 'install', '--no-tui', + '--skip-auth', `--claude=${claude}`, `--copilot=${copilot}`, `--gemini=${gemini}`, From 1f9f2c4895cfce01867eab3cb6fbb711eca70d66 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 16:09:46 -0700 Subject: [PATCH 5/8] feat(setup): add kimi-for-coding to oMo provider inputs (#268) feat(setup): expose kimi-for-coding oMo CLI flag as action input Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- action.yaml | 4 ++-- dist/main.js | 2 +- src/lib/setup/omo.test.ts | 33 +++++++++++++++++++++++++++++++++ src/lib/setup/omo.ts | 4 ++++ src/lib/setup/setup.ts | 7 ++++++- 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/action.yaml b/action.yaml index 23fc8374..9bd0fa6c 100644 --- a/action.yaml +++ b/action.yaml @@ -53,8 +53,8 @@ inputs: omo-providers: description: >- Comma-separated list of oMo providers to enable. Values: claude, claude-max20, - copilot, gemini, openai, opencode-zen, zai-coding-plan. Default: empty - (uses free OpenCode models) + copilot, gemini, openai, opencode-zen, zai-coding-plan, kimi-for-coding. + Default: empty (uses free OpenCode models) required: false opencode-config: description: >- diff --git a/dist/main.js b/dist/main.js index d66ffee8..5619e1a6 100644 --- a/dist/main.js +++ b/dist/main.js @@ -127,7 +127,7 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a `);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function $t(e){let t=await Qt({...e});return{client:Zt({baseUrl:t.url}),server:t}}async function en(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const tn={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},nn=`\x1B[0m`;function rn(){return H.env.NO_COLOR==null}function an(e,t){let[n,r]=tn[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);rn()?H.stdout.write(`\n${r}|${nn} ${i} ${nn}${t}\n`):H.stdout.write(`\n| ${i} ${t}\n`)}function on(e){H.stdout.write(`\n${e}\n`)}const sn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function cn(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function ln(e){let t=cn(e),n=sn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` `)}function un(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const dn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function fn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return dn.some(e=>e.test(t))}function pn(e,t){return un(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function mn(e,t){return un(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}function hn(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function gn(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 _n(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(hn)}function vn(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)]}var yn=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(ge(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(_e(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${me}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},bn=T((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),xn=e(T((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[d.Accept]=this._getExistingOrDefaultHeader(t,d.Accept,f.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===u.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&m.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!h.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},x(this.requestOptions.headers),x(e||{})):x(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[d.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[d.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new l.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===u.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let x=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),Sn=w(),Cn=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function wn(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function Tn(e){return new xn.HttpClient().getAgent(e)}function En(e){return new xn.HttpClient().getAgentDispatcher(e)}function Dn(e){let t=En(e);return(e,n)=>Cn(this,void 0,void 0,function*(){return(0,Sn.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function On(){return process.env.GITHUB_API_URL||`https://api.github.com`}function kn(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function An(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>An.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function jn(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function Mn(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const Nn=Function.bind,Pn=Nn.bind(Nn);function Fn(e,t,n){let r=Pn(Mn,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=Pn(jn,null).apply(null,i)})}function In(){let e=Symbol(`Singular`),t={registry:{}},n=An.bind(null,t,e);return Fn(n,t,e),n}function Ln(){let e={registry:{}},t=An.bind(null,e);return Fn(t,e),t}var Rn={Singular:In,Collection:Ln},zn=`octokit-endpoint.js/0.0.0-development ${kn()}`,Bn={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":zn},mediaType:{format:``}};function Vn(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Hn(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Un(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Hn(t[r])&&r in e?n[r]=Un(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Wn(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function Gn(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Vn(n.headers),Wn(n),Wn(n.headers);let r=Un(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function Kn(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var qn=/\{[^{}}]+\}/g;function Jn(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Xn(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function Zn(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function Qn(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function $n(e,t,n){return t=e===`+`||e===`#`?Zn(t):Qn(t),n?Qn(n)+`=`+t:t}function er(e){return e!=null}function tr(e){return e===`;`||e===`&`||e===`?`}function nr(e,t,n,r){var i=e[n],a=[];if(er(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push($n(t,i,tr(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(er).forEach(function(e){a.push($n(t,e,tr(t)?n:``))}):Object.keys(i).forEach(function(e){er(i[e])&&a.push($n(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(er).forEach(function(n){e.push($n(t,n))}):Object.keys(i).forEach(function(n){er(i[n])&&(e.push(Qn(n)),e.push($n(t,i[n].toString())))}),tr(t)?a.push(Qn(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?er(i)&&a.push(Qn(n)):i===``&&(t===`&`||t===`?`)?a.push(Qn(n)+`=`):i===``&&a.push(``);return a}function rr(e){return{expand:ir.bind(null,e)}}function ir(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(nr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return Zn(i)}),e===`/`?e:e.replace(/\/$/,``)}function ar(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Xn(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Yn(n);n=rr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Xn(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=Kn(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function or(e,t,n){return ar(Gn(e,t,n))}function sr(e,t){let n=Gn(e,t),r=or.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:sr.bind(null,n),merge:Gn.bind(null,n),parse:ar})}var cr=sr(null,Bn),lr=T(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))(),ur=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function hr(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=pr(e.body)||Array.isArray(e.body)?JSON.stringify(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new ur(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new ur(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await gr(o),new ur(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await gr(o),new ur(vr(u.data),s,{response:u,request:e});return u.data=r?await gr(o):o.body,u}async function gr(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(mr);let n=(0,lr.safeParse)(t);if(_r(n)){let t=``;try{return t=await e.text(),JSON.parse(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(mr);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function _r(e){return e.type===`application/json`||e.type===`application/scim+json`}function vr(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function yr(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return hr(n.parse(r));let i=(e,t)=>hr(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:yr.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:yr.bind(null,n)})}var br=yr(cr,fr),xr=`0.0.0-development`;function Sr(e){return`Request failed due to following response errors: `+e.errors.map(e=>` - ${e.message}`).join(` -`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${kn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${kn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Rn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new yn;const ii=On(),ai={baseUrl:ii,request:{agent:Tn(ii),fetch:Dn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=wn(e,n);return r&&(n.auth=r),n}const ci=new yn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(ie(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=W.join(ki(),he.randomUUID()),yield S(W.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(U.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=ye.promisify(Oe.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,U.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=pe.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!U.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of U.readdirSync(e))yield b(W.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=pe.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=W.join(Oi(),e,t,n);j(`checking cache: ${i}`),U.existsSync(i)&&U.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=pe.arch();let r=W.join(Oi(),e);if(U.existsSync(r)){let e=U.readdirSync(r);for(let i of e)if(Ei(i)){let e=W.join(r,i,t||``);U.existsSync(e)&&U.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=W.join(ki(),he.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=W.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${W.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;U.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ve(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ve(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=B.join(t,`auth.json`);await G.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await G.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=H.platform,t=H.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(H.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=fe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Ce.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=fe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>H.platform===`win32`?`${e}.exe`:e,n=fe.join(e,t(`bun`));try{await Ce.symlink(n,fe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};H.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}async function Gi(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`}=n;r.info(`Installing Oh My OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u});let d=``,f=[`oh-my-opencode@${e}`,`install`,`--no-tui`,`--skip-auth`,`--claude=${a}`,`--copilot=${o}`,`--gemini=${s}`,`--openai=${c}`,`--opencode-zen=${l}`,`--zai-coding-plan=${u}`];try{let t=await i.exec(`bunx`,f,{listeners:{stdout:e=>{d+=e.toString()},stderr:e=>{d+=e.toString()}},ignoreReturnCode:!0});if(t!==0){let e=`bunx oh-my-opencode install returned exit code ${t}`;return r.error(e,{output:d.slice(0,1e3)}),{installed:!1,version:null,error:`${e}\n${d.slice(0,500)}`}}let n=/oh-my-opencode@(\d+\.\d+\.\d+)/i.exec(d),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=M(e),n=d.length>0?`${t}\nOutput: ${d.slice(0,500)}`:t;return r.error(`Failed to run oMo installer`,{error:t,output:d.slice(0,500)}),{installed:!1,version:null,error:`bunx oh-my-opencode install failed: ${n}`}}}const Ki=`opencode`,qi=`1.2.9`;function Ji(){let e=Ee.platform(),t=Ee.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 Yi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Xi(e,t,n,r){if(H.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 Zi(e,t,n,r,i=qi){let a=Ji(),o=n.find(Ki,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 Qi(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(n)})}if(e!==i)try{let e=await Qi(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}): ${M(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Qi(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=Yi(e,t),o=await r.downloadTool(a);if(!await Xi(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,Ki,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function $i(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ea={restoreCache:async(e,t,n)=>I(e,t,n),saveCache:async(e,t)=>D(e,t)};function ta(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ce}-${t}-oc-${n}-omo-${r}`}function na(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ce}-${t}-oc-${n}-omo-${r}-`]}async function ra(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=na({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function ia(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const aa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function oa(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`;for(let e of t)if(aa.includes(e))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}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function sa(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ca(){return{exec:x,getExecOutput:c}}function la(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null}}async function ua(){let e=Date.now(),n=A({component:`setup`}),r=sa(),o=ca();try{let s=la(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await $i(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=qi}let d=m(`omo-version`).trim(),f=d.length>0?d:N,h=H.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=V(h,`opencode`),v=V(h,`bun`),y=V(De(),`.config`,`opencode`),b=a(),x=await ra({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await Zi(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){let e=m(`omo-providers`).trim(),t=oa(e.length>0?e:se),r=await Gi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1};if(s.opencodeConfig!=null){let e=JSON.parse(s.opencodeConfig);if(typeof e!=`object`||!e||Array.isArray(e))return _(`opencode-config must be a JSON object`),null;Object.assign(te,e)}p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await ia({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),z(`opencode-path`,C.path),z(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=V(i(),`opencode`),k=await Mi(l,O,n);z(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=H.env.GITHUB_REPOSITORY??`unknown/unknown`,j=H.env.GITHUB_REF_NAME??`main`,ie=a(),ae=ee({agentIdentity:`github`,repo:A,ref:j,os:ie}),P=oe({agentIdentity:`github`,repo:A,ref:j,os:ie}),F=`miss`;try{let e=await I([O],ae,[...P]);e==null?n.info(`No cache found`):(F=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){F=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}z(`cache-status`,F),z(`storage-path`,O);let L=Date.now()-e,R={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:F,toolsCacheStatus:S,duration:L};return n.info(`Setup complete`,{duration:L}),R}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function da(e){return{success:!0,data:e}}function fa(e){return{success:!1,error:e}}const pa=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ma(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` +`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${kn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${kn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Rn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new yn;const ii=On(),ai={baseUrl:ii,request:{agent:Tn(ii),fetch:Dn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=wn(e,n);return r&&(n.auth=r),n}const ci=new yn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(ie(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=W.join(ki(),he.randomUUID()),yield S(W.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(U.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=ye.promisify(Oe.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,U.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=pe.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!U.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of U.readdirSync(e))yield b(W.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=pe.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=W.join(Oi(),e,t,n);j(`checking cache: ${i}`),U.existsSync(i)&&U.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=pe.arch();let r=W.join(Oi(),e);if(U.existsSync(r)){let e=U.readdirSync(r);for(let i of e)if(Ei(i)){let e=W.join(r,i,t||``);U.existsSync(e)&&U.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=W.join(ki(),he.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=W.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${W.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;U.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ve(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ve(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=B.join(t,`auth.json`);await G.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await G.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=H.platform,t=H.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(H.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=fe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Ce.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=fe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>H.platform===`win32`?`${e}.exe`:e,n=fe.join(e,t(`bun`));try{await Ce.symlink(n,fe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};H.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}async function Gi(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 OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u,kimiForCoding:d});let f=``,p=[`oh-my-opencode@${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-opencode 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=M(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-opencode install failed: ${n}`}}}const Ki=`opencode`,qi=`1.2.9`;function Ji(){let e=Ee.platform(),t=Ee.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 Yi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Xi(e,t,n,r){if(H.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 Zi(e,t,n,r,i=qi){let a=Ji(),o=n.find(Ki,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 Qi(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(n)})}if(e!==i)try{let e=await Qi(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}): ${M(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Qi(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=Yi(e,t),o=await r.downloadTool(a);if(!await Xi(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,Ki,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function $i(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ea={restoreCache:async(e,t,n)=>I(e,t,n),saveCache:async(e,t)=>D(e,t)};function ta(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ce}-${t}-oc-${n}-omo-${r}`}function na(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ce}-${t}-oc-${n}-omo-${r}-`]}async function ra(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=na({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function ia(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const aa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function oa(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(aa.includes(e))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 sa(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ca(){return{exec:x,getExecOutput:c}}function la(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null}}async function ua(){let e=Date.now(),n=A({component:`setup`}),r=sa(),o=ca();try{let s=la(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await $i(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=qi}let d=m(`omo-version`).trim(),f=d.length>0?d:N,h=H.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=V(h,`opencode`),v=V(h,`bun`),y=V(De(),`.config`,`opencode`),b=a(),x=await ra({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await Zi(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){let e=m(`omo-providers`).trim(),t=oa(e.length>0?e:se),r=await Gi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1};if(s.opencodeConfig!=null){let e=JSON.parse(s.opencodeConfig);if(typeof e!=`object`||!e||Array.isArray(e))return _(`opencode-config must be a JSON object`),null;Object.assign(te,e)}p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await ia({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),z(`opencode-path`,C.path),z(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=V(i(),`opencode`),k=await Mi(l,O,n);z(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=H.env.GITHUB_REPOSITORY??`unknown/unknown`,j=H.env.GITHUB_REF_NAME??`main`,ie=a(),ae=ee({agentIdentity:`github`,repo:A,ref:j,os:ie}),P=oe({agentIdentity:`github`,repo:A,ref:j,os:ie}),F=`miss`;try{let e=await I([O],ae,[...P]);e==null?n.info(`No cache found`):(F=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){F=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}z(`cache-status`,F),z(`storage-path`,O);let L=Date.now()-e,R={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:F,toolsCacheStatus:S,duration:L};return n.info(`Setup complete`,{duration:L}),R}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function da(e){return{success:!0,data:e}}function fa(e){return{success:!1,error:e}}const pa=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ma(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` `),appendMode:!0};case`pull_request_review_comment`:return{directive:ha(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function ha(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` `)}function ga(e,t){let{directive:n,appendMode:r}=ma(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` `)}function _a(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a}=e,o=[];if(o.push(`# Agent Context diff --git a/src/lib/setup/omo.test.ts b/src/lib/setup/omo.test.ts index 32168569..19e957c3 100644 --- a/src/lib/setup/omo.test.ts +++ b/src/lib/setup/omo.test.ts @@ -69,6 +69,7 @@ describe('omo', () => { '--openai=no', '--opencode-zen=no', '--zai-coding-plan=no', + '--kimi-for-coding=no', ], expect.any(Object), ) @@ -191,6 +192,7 @@ describe('omo', () => { '--openai=no', '--opencode-zen=no', '--zai-coding-plan=no', + '--kimi-for-coding=no', ], expect.objectContaining({ignoreReturnCode: true}), ) @@ -227,6 +229,37 @@ describe('omo', () => { '--openai=yes', '--opencode-zen=no', '--zai-coding-plan=no', + '--kimi-for-coding=no', + ], + expect.objectContaining({ignoreReturnCode: true}), + ) + }) + + it('calls bunx with kimi-for-coding=yes when option is set', async () => { + // #given + const execMock = vi.fn().mockResolvedValue(0) + const mockDeps = createMockDeps({ + execAdapter: createMockExecAdapter({exec: execMock}), + }) + + // #when + await installOmo('3.5.5', mockDeps, {kimiForCoding: 'yes'}) + + // #then - bunx call includes kimi-for-coding=yes + expect(execMock).toHaveBeenCalledWith( + 'bunx', + [ + 'oh-my-opencode@3.5.5', + 'install', + '--no-tui', + '--skip-auth', + '--claude=no', + '--copilot=no', + '--gemini=no', + '--openai=no', + '--opencode-zen=no', + '--zai-coding-plan=no', + '--kimi-for-coding=yes', ], expect.objectContaining({ignoreReturnCode: true}), ) diff --git a/src/lib/setup/omo.ts b/src/lib/setup/omo.ts index fff7d04c..9498eb27 100644 --- a/src/lib/setup/omo.ts +++ b/src/lib/setup/omo.ts @@ -11,6 +11,7 @@ export interface OmoInstallOptions { openai?: 'no' | 'yes' opencodeZen?: 'no' | 'yes' zaiCodingPlan?: 'no' | 'yes' + kimiForCoding?: 'no' | 'yes' } export interface OmoInstallDeps { @@ -43,6 +44,7 @@ export async function installOmo( openai = 'no', opencodeZen = 'no', zaiCodingPlan = 'no', + kimiForCoding = 'no', } = options logger.info('Installing Oh My OpenCode plugin', { @@ -53,6 +55,7 @@ export async function installOmo( openai, opencodeZen, zaiCodingPlan, + kimiForCoding, }) let output = '' @@ -67,6 +70,7 @@ export async function installOmo( `--openai=${openai}`, `--opencode-zen=${opencodeZen}`, `--zai-coding-plan=${zaiCodingPlan}`, + `--kimi-for-coding=${kimiForCoding}`, ] try { diff --git a/src/lib/setup/setup.ts b/src/lib/setup/setup.ts index cc831cdc..519637e1 100644 --- a/src/lib/setup/setup.ts +++ b/src/lib/setup/setup.ts @@ -28,6 +28,7 @@ const VALID_OMO_PROVIDERS = [ 'openai', 'opencode-zen', 'zai-coding-plan', + 'kimi-for-coding', ] as const function parseOmoProviders(input: string): OmoInstallOptions { @@ -42,6 +43,7 @@ function parseOmoProviders(input: string): OmoInstallOptions { let openai: 'no' | 'yes' = 'no' let opencodeZen: 'no' | 'yes' = 'no' let zaiCodingPlan: 'no' | 'yes' = 'no' + let kimiForCoding: 'no' | 'yes' = 'no' for (const provider of providers) { if (!VALID_OMO_PROVIDERS.includes(provider as (typeof VALID_OMO_PROVIDERS)[number])) { @@ -70,10 +72,13 @@ function parseOmoProviders(input: string): OmoInstallOptions { case 'zai-coding-plan': zaiCodingPlan = 'yes' break + case 'kimi-for-coding': + kimiForCoding = 'yes' + break } } - return {claude, copilot, gemini, openai, opencodeZen, zaiCodingPlan} + return {claude, copilot, gemini, openai, opencodeZen, zaiCodingPlan, kimiForCoding} } /** From d6dbbb1e54123f7223db18b437062be154271b7c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 16:21:59 -0700 Subject: [PATCH 6/8] feat(setup): add `omo-config` action input for custom oMo configuration (#274) feat(setup): add omo-config action input for custom oMo configuration Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- README.md | 1 + action.yaml | 5 + dist/main.js | 38 ++--- src/lib/setup/omo-config.test.ts | 245 +++++++++++++++++++++++++++++++ src/lib/setup/omo-config.ts | 81 ++++++++++ src/lib/setup/setup.test.ts | 75 ++++++++++ src/lib/setup/setup.ts | 13 ++ src/lib/setup/types.ts | 1 + 8 files changed, 440 insertions(+), 19 deletions(-) create mode 100644 src/lib/setup/omo-config.test.ts create mode 100644 src/lib/setup/omo-config.ts diff --git a/README.md b/README.md index 61d83857..1041130e 100644 --- a/README.md +++ b/README.md @@ -373,6 +373,7 @@ concurrency: | `s3-bucket` | No | — | S3 bucket name (required if `s3-backup` is true) | | `aws-region` | No | — | AWS region for S3 bucket | | `skip-cache` | No | `false` | Skip cache restore (useful for debugging) | +| `omo-config` | No | — | Custom oMo configuration JSON (deep-merged) | ### Action Outputs diff --git a/action.yaml b/action.yaml index 9bd0fa6c..025dd4c0 100644 --- a/action.yaml +++ b/action.yaml @@ -61,6 +61,11 @@ inputs: JSON object to merge into the OpenCode config (OPENCODE_CONFIG_CONTENT). Values are merged on top of the autoupdate:false baseline; user values win on conflicts. required: false + omo-config: + description: >- + Custom oMo configuration JSON. Written before installer runs. + Deep-merged with existing config. + required: false outputs: session-id: diff --git a/dist/main.js b/dist/main.js index 5619e1a6..515dca2e 100644 --- a/dist/main.js +++ b/dist/main.js @@ -1,4 +1,4 @@ -import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,Q as g,R as _,S as v,T as y,U as b,V as x,W as S,X as C,Y as w,Z as T,_ as E,a as ee,b as te,c as D,d as ne,f as re,g as O,h as k,i as A,j,k as M,l as ie,m as N,n as ae,o as oe,p as se,q as P,r as F,s as I,t as L,u as R,v as ce,w as le,x as ue,y as de,z}from"./state-keys-CDII8qo6.js";import*as B from"node:path";import fe,{join as V}from"node:path";import H from"node:process";import*as pe from"os";import{EOL as me}from"os";import*as he from"crypto";import*as U from"fs";import{existsSync as ge,readFileSync as _e}from"fs";import*as W from"path";import{ok as ve}from"assert";import*as ye from"util";import{Buffer as be}from"node:buffer";import*as xe from"node:crypto";import{pathToFileURL as Se}from"node:url";import*as G from"node:fs/promises";import Ce from"node:fs/promises";import{spawn as we}from"node:child_process";import*as Te from"node:os";import Ee,{homedir as De}from"node:os";import*as Oe from"stream";const ke={maxComments:50,maxCommits:100,maxFiles:100,maxReviews:100,maxBodyBytes:10*1024,maxTotalBytes:100*1024},Ae=`…[truncated]`;function je(e,t){if(e.length===0)return{text:``,truncated:!1};let n=new TextEncoder,r=n.encode(e);if(r.length<=t)return{text:e,truncated:!1};let i=t-n.encode(Ae).length;if(i<=0)return{text:Ae,truncated:!0};let a=r.slice(0,i),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);for(;o.length>0&&o.charCodeAt(o.length-1)===65533;)a=a.slice(0,-1),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);return{text:o+Ae,truncated:!0}}function Me(e){return e.length===0?``:`**Labels:** ${e.map(e=>`\`${e.name}\``).join(`, `)}\n`}function Ne(e){return e.length===0?``:`**Assignees:** ${e.map(e=>`@${e.login}`).join(`, `)}\n`}function Pe(e){let t=[];t.push(`## Issue #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`);let n=Me(e.labels);n.length>0&&t.push(n.trimEnd());let r=Ne(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Body`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Body was truncated due to size limits.*`)),e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),e.commentsTruncated&&(t.push(``),t.push(`*Note: Comments were truncated due to limits.*`)),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` +import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,Q as g,R as _,S as v,T as y,U as b,V as x,W as S,X as C,Y as w,Z as T,_ as E,a as ee,b as te,c as D,d as ne,f as re,g as O,h as k,i as A,j,k as M,l as N,m as P,n as ie,o as ae,p as oe,q as F,r as I,s as se,t as L,u as R,v as ce,w as le,x as ue,y as de,z}from"./state-keys-CDII8qo6.js";import*as B from"node:path";import fe,{join as V}from"node:path";import H from"node:process";import*as pe from"os";import{EOL as me}from"os";import*as he from"crypto";import*as U from"fs";import{existsSync as ge,readFileSync as _e}from"fs";import*as W from"path";import{ok as ve}from"assert";import*as ye from"util";import{Buffer as be}from"node:buffer";import*as xe from"node:crypto";import{pathToFileURL as Se}from"node:url";import*as G from"node:fs/promises";import Ce from"node:fs/promises";import{spawn as we}from"node:child_process";import*as Te from"node:os";import Ee,{homedir as De}from"node:os";import*as Oe from"stream";const ke={maxComments:50,maxCommits:100,maxFiles:100,maxReviews:100,maxBodyBytes:10*1024,maxTotalBytes:100*1024},Ae=`…[truncated]`;function je(e,t){if(e.length===0)return{text:``,truncated:!1};let n=new TextEncoder,r=n.encode(e);if(r.length<=t)return{text:e,truncated:!1};let i=t-n.encode(Ae).length;if(i<=0)return{text:Ae,truncated:!0};let a=r.slice(0,i),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);for(;o.length>0&&o.charCodeAt(o.length-1)===65533;)a=a.slice(0,-1),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);return{text:o+Ae,truncated:!0}}function Me(e){return e.length===0?``:`**Labels:** ${e.map(e=>`\`${e.name}\``).join(`, `)}\n`}function Ne(e){return e.length===0?``:`**Assignees:** ${e.map(e=>`@${e.login}`).join(`, `)}\n`}function Pe(e){let t=[];t.push(`## Issue #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`);let n=Me(e.labels);n.length>0&&t.push(n.trimEnd());let r=Ne(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Body`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Body was truncated due to size limits.*`)),e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),e.commentsTruncated&&(t.push(``),t.push(`*Note: Comments were truncated due to limits.*`)),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` `)}function Fe(e){let t=[];t.push(`## Pull Request #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`),t.push(`**Base:** ${e.baseBranch} ← **Head:** ${e.headBranch}`),e.isFork&&t.push(`**Fork:** Yes (external contributor)`);let n=Me(e.labels);n.length>0&&t.push(n.trimEnd());let r=Ne(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Description`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Description was truncated due to size limits.*`)),e.files.length>0){t.push(``),t.push(`### Files Changed (${e.files.length}${e.filesTruncated?` of ${e.totalFiles}`:``})`),t.push(``),t.push(`| File | +/- |`),t.push(`|------|-----|`);for(let n of e.files)t.push(`| \`${n.path}\` | +${n.additions}/-${n.deletions} |`)}if(e.commits.length>0){t.push(``),t.push(`### Commits (${e.commits.length}${e.commitsTruncated?` of ${e.totalCommits}`:``})`),t.push(``);for(let n of e.commits){let e=n.oid.slice(0,7);t.push(`- \`${e}\` ${n.message.split(` `)[0]}`)}}if(e.reviews.length>0){t.push(``),t.push(`### Reviews (${e.reviews.length}${e.reviewsTruncated?` of ${e.totalReviews}`:``})`),t.push(``);for(let n of e.reviews)t.push(`**${n.author??`unknown`}** - ${n.state}`),n.body.length>0&&t.push(n.body),t.push(``)}if(e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` `)}function Ie(e){return e.type===`issue`?Pe(e):Fe(e)}async function Le(e,t,n,r,i,a){try{let[a,o]=await Promise.all([e.rest.issues.get({owner:t,repo:n,issue_number:r}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),s=a.data,c=je(s.body??``,i.maxBodyBytes),l=o.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),u=(s.labels??[]).filter(e=>typeof e==`object`&&!!e&&`name`in e).map(e=>({name:e.name??``,color:e.color})),d=(s.assignees??[]).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.user?.login??null,createdAt:s.created_at,labels:u,assignees:d,comments:l,commentsTruncated:o.data.length>=i.maxComments,totalComments:o.data.length}}catch(e){return a.warning(`REST issue fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function Re(e,t,n,r,i,a){try{let[o,s,c,l,u]=await Promise.all([e.rest.pulls.get({owner:t,repo:n,pull_number:r}),e.rest.pulls.listCommits({owner:t,repo:n,pull_number:r,per_page:i.maxCommits}),e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:i.maxFiles}),e.rest.pulls.listReviews({owner:t,repo:n,pull_number:r,per_page:i.maxReviews}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),d=await e.rest.pulls.listRequestedReviewers({owner:t,repo:n,pull_number:r}).catch(e=>(a.warning(`Failed to fetch requested reviewers, defaulting to empty`,{owner:t,repo:n,number:r,error:M(e)}),{data:{users:[],teams:[]}})),f=o.data,p=je(f.body??``,i.maxBodyBytes),m=f.base.repo?.owner.login,h=f.head.repo?.owner.login,g=h==null||m!==h,_=u.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),v=s.data.slice(0,i.maxCommits).map(e=>({oid:e.sha,message:e.commit.message,author:e.commit.author?.name??null})),y=c.data.slice(0,i.maxFiles).map(e=>({path:e.filename,additions:e.additions,deletions:e.deletions,status:e.status})),b=l.data.slice(0,i.maxReviews).map(e=>({author:e.user?.login??null,state:e.state,body:e.body??``,createdAt:e.submitted_at??``,comments:[]})),x=(f.labels??[]).map(e=>({name:e.name??``,color:e.color})),S=(f.assignees??[]).map(e=>({login:e?.login??``})),C=(d.data.users??[]).map(e=>e.login),w=(d.data.teams??[]).map(e=>e.name);return{type:`pull_request`,number:f.number,title:f.title,body:p.text,bodyTruncated:p.truncated,state:f.state,author:f.user?.login??null,createdAt:f.created_at,baseBranch:f.base.ref,headBranch:f.head.ref,isFork:g,labels:x,assignees:S,comments:_,commentsTruncated:u.data.length>=i.maxComments,totalComments:u.data.length,commits:v,commitsTruncated:s.data.length>=i.maxCommits,totalCommits:s.data.length,files:y,filesTruncated:c.data.length>=i.maxFiles,totalFiles:c.data.length,reviews:b,reviewsTruncated:l.data.length>=i.maxReviews,totalReviews:l.data.length,authorAssociation:f.author_association,requestedReviewers:C,requestedReviewerTeams:w}}catch(e){return a.warning(`REST pull request fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function ze(e,t,n,r,i,a){try{return await e.graphql(` @@ -127,10 +127,10 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a `);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function $t(e){let t=await Qt({...e});return{client:Zt({baseUrl:t.url}),server:t}}async function en(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const tn={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},nn=`\x1B[0m`;function rn(){return H.env.NO_COLOR==null}function an(e,t){let[n,r]=tn[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);rn()?H.stdout.write(`\n${r}|${nn} ${i} ${nn}${t}\n`):H.stdout.write(`\n| ${i} ${t}\n`)}function on(e){H.stdout.write(`\n${e}\n`)}const sn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function cn(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function ln(e){let t=cn(e),n=sn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` `)}function un(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const dn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function fn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return dn.some(e=>e.test(t))}function pn(e,t){return un(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function mn(e,t){return un(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}function hn(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function gn(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 _n(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(hn)}function vn(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)]}var yn=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(ge(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(_e(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${me}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},bn=T((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),xn=e(T((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[d.Accept]=this._getExistingOrDefaultHeader(t,d.Accept,f.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===u.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&m.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!h.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},x(this.requestOptions.headers),x(e||{})):x(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[d.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[d.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new l.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===u.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let x=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),Sn=w(),Cn=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function wn(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function Tn(e){return new xn.HttpClient().getAgent(e)}function En(e){return new xn.HttpClient().getAgentDispatcher(e)}function Dn(e){let t=En(e);return(e,n)=>Cn(this,void 0,void 0,function*(){return(0,Sn.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function On(){return process.env.GITHUB_API_URL||`https://api.github.com`}function kn(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function An(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>An.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function jn(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function Mn(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const Nn=Function.bind,Pn=Nn.bind(Nn);function Fn(e,t,n){let r=Pn(Mn,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=Pn(jn,null).apply(null,i)})}function In(){let e=Symbol(`Singular`),t={registry:{}},n=An.bind(null,t,e);return Fn(n,t,e),n}function Ln(){let e={registry:{}},t=An.bind(null,e);return Fn(t,e),t}var Rn={Singular:In,Collection:Ln},zn=`octokit-endpoint.js/0.0.0-development ${kn()}`,Bn={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":zn},mediaType:{format:``}};function Vn(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Hn(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Un(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Hn(t[r])&&r in e?n[r]=Un(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Wn(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function Gn(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Vn(n.headers),Wn(n),Wn(n.headers);let r=Un(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function Kn(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var qn=/\{[^{}}]+\}/g;function Jn(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Xn(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function Zn(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function Qn(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function $n(e,t,n){return t=e===`+`||e===`#`?Zn(t):Qn(t),n?Qn(n)+`=`+t:t}function er(e){return e!=null}function tr(e){return e===`;`||e===`&`||e===`?`}function nr(e,t,n,r){var i=e[n],a=[];if(er(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push($n(t,i,tr(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(er).forEach(function(e){a.push($n(t,e,tr(t)?n:``))}):Object.keys(i).forEach(function(e){er(i[e])&&a.push($n(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(er).forEach(function(n){e.push($n(t,n))}):Object.keys(i).forEach(function(n){er(i[n])&&(e.push(Qn(n)),e.push($n(t,i[n].toString())))}),tr(t)?a.push(Qn(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?er(i)&&a.push(Qn(n)):i===``&&(t===`&`||t===`?`)?a.push(Qn(n)+`=`):i===``&&a.push(``);return a}function rr(e){return{expand:ir.bind(null,e)}}function ir(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(nr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return Zn(i)}),e===`/`?e:e.replace(/\/$/,``)}function ar(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Xn(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Yn(n);n=rr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Xn(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=Kn(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function or(e,t,n){return ar(Gn(e,t,n))}function sr(e,t){let n=Gn(e,t),r=or.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:sr.bind(null,n),merge:Gn.bind(null,n),parse:ar})}var cr=sr(null,Bn),lr=T(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))(),ur=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function hr(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=pr(e.body)||Array.isArray(e.body)?JSON.stringify(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new ur(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new ur(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await gr(o),new ur(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await gr(o),new ur(vr(u.data),s,{response:u,request:e});return u.data=r?await gr(o):o.body,u}async function gr(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(mr);let n=(0,lr.safeParse)(t);if(_r(n)){let t=``;try{return t=await e.text(),JSON.parse(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(mr);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function _r(e){return e.type===`application/json`||e.type===`application/scim+json`}function vr(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function yr(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return hr(n.parse(r));let i=(e,t)=>hr(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:yr.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:yr.bind(null,n)})}var br=yr(cr,fr),xr=`0.0.0-development`;function Sr(e){return`Request failed due to following response errors: `+e.errors.map(e=>` - ${e.message}`).join(` -`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${kn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${kn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Rn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new yn;const ii=On(),ai={baseUrl:ii,request:{agent:Tn(ii),fetch:Dn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=wn(e,n);return r&&(n.auth=r),n}const ci=new yn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(ie(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=W.join(ki(),he.randomUUID()),yield S(W.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(U.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=ye.promisify(Oe.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,U.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=pe.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!U.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of U.readdirSync(e))yield b(W.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=pe.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=W.join(Oi(),e,t,n);j(`checking cache: ${i}`),U.existsSync(i)&&U.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=pe.arch();let r=W.join(Oi(),e);if(U.existsSync(r)){let e=U.readdirSync(r);for(let i of e)if(Ei(i)){let e=W.join(r,i,t||``);U.existsSync(e)&&U.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=W.join(ki(),he.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=W.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${W.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;U.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ve(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ve(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=B.join(t,`auth.json`);await G.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await G.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=H.platform,t=H.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(H.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=fe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Ce.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=fe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>H.platform===`win32`?`${e}.exe`:e,n=fe.join(e,t(`bun`));try{await Ce.symlink(n,fe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};H.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}async function Gi(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 OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u,kimiForCoding:d});let f=``,p=[`oh-my-opencode@${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-opencode 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=M(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-opencode install failed: ${n}`}}}const Ki=`opencode`,qi=`1.2.9`;function Ji(){let e=Ee.platform(),t=Ee.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 Yi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Xi(e,t,n,r){if(H.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 Zi(e,t,n,r,i=qi){let a=Ji(),o=n.find(Ki,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 Qi(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(n)})}if(e!==i)try{let e=await Qi(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}): ${M(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function Qi(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=Yi(e,t),o=await r.downloadTool(a);if(!await Xi(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,Ki,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function $i(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ea={restoreCache:async(e,t,n)=>I(e,t,n),saveCache:async(e,t)=>D(e,t)};function ta(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ce}-${t}-oc-${n}-omo-${r}`}function na(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ce}-${t}-oc-${n}-omo-${r}-`]}async function ra(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=na({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function ia(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ea}=e,l=ta({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const aa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function oa(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(aa.includes(e))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 sa(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ca(){return{exec:x,getExecOutput:c}}function la(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null}}async function ua(){let e=Date.now(),n=A({component:`setup`}),r=sa(),o=ca();try{let s=la(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await $i(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=qi}let d=m(`omo-version`).trim(),f=d.length>0?d:N,h=H.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=V(h,`opencode`),v=V(h,`bun`),y=V(De(),`.config`,`opencode`),b=a(),x=await ra({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await Zi(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){let e=m(`omo-providers`).trim(),t=oa(e.length>0?e:se),r=await Gi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1};if(s.opencodeConfig!=null){let e=JSON.parse(s.opencodeConfig);if(typeof e!=`object`||!e||Array.isArray(e))return _(`opencode-config must be a JSON object`),null;Object.assign(te,e)}p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await ia({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),z(`opencode-path`,C.path),z(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=V(i(),`opencode`),k=await Mi(l,O,n);z(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=H.env.GITHUB_REPOSITORY??`unknown/unknown`,j=H.env.GITHUB_REF_NAME??`main`,ie=a(),ae=ee({agentIdentity:`github`,repo:A,ref:j,os:ie}),P=oe({agentIdentity:`github`,repo:A,ref:j,os:ie}),F=`miss`;try{let e=await I([O],ae,[...P]);e==null?n.info(`No cache found`):(F=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){F=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}z(`cache-status`,F),z(`storage-path`,O);let L=Date.now()-e,R={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:F,toolsCacheStatus:S,duration:L};return n.info(`Setup complete`,{duration:L}),R}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function da(e){return{success:!0,data:e}}function fa(e){return{success:!1,error:e}}const pa=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ma(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` -`),appendMode:!0};case`pull_request_review_comment`:return{directive:ha(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function ha(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` -`)}function ga(e,t){let{directive:n,appendMode:r}=ma(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` -`)}function _a(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a}=e,o=[];if(o.push(`# Agent Context +`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${kn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${kn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Rn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new yn;const ii=On(),ai={baseUrl:ii,request:{agent:Tn(ii),fetch:Dn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=wn(e,n);return r&&(n.auth=r),n}const ci=new yn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(N(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=W.join(ki(),he.randomUUID()),yield S(W.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(U.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=ye.promisify(Oe.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,U.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=pe.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!U.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of U.readdirSync(e))yield b(W.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=pe.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=W.join(Oi(),e,t,n);j(`checking cache: ${i}`),U.existsSync(i)&&U.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=pe.arch();let r=W.join(Oi(),e);if(U.existsSync(r)){let e=U.readdirSync(r);for(let i of e)if(Ei(i)){let e=W.join(r,i,t||``);U.existsSync(e)&&U.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=W.join(ki(),he.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=W.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${W.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;U.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ve(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ve(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=B.join(t,`auth.json`);await G.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await G.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=H.platform,t=H.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(H.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=fe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Ce.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=fe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>H.platform===`win32`?`${e}.exe`:e,n=fe.join(e,t(`bun`));try{await Ce.symlink(n,fe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};H.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}function Gi(e,t){let n={...e};for(let[e,r]of Object.entries(t)){let t=n[e];typeof r==`object`&&r&&!Array.isArray(r)&&typeof t==`object`&&t&&!Array.isArray(t)?n[e]=Gi(t,r):n[e]=r}return n}async function Ki(e,t,n){let r=JSON.parse(e);await G.mkdir(t,{recursive:!0});let i=B.join(t,`oh-my-opencode.json`),a={};try{let e=await G.readFile(i,`utf8`),t=JSON.parse(e);typeof t==`object`&&t&&!Array.isArray(t)&&(a=t)}catch{}let o=Gi(a,r);await G.writeFile(i,JSON.stringify(o,null,2)),n.info(`Wrote oMo config`,{path:i,keyCount:Object.keys(r).length})}async function qi(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 OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u,kimiForCoding:d});let f=``,p=[`oh-my-opencode@${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-opencode 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=M(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-opencode install failed: ${n}`}}}const Ji=`opencode`,Yi=`1.2.9`;function Xi(){let e=Ee.platform(),t=Ee.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 Zi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Qi(e,t,n,r){if(H.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 $i(e,t,n,r,i=Yi){let a=Xi(),o=n.find(Ji,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){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(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}): ${M(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=Zi(e,t),o=await r.downloadTool(a);if(!await Qi(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,Ji,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function ta(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const na={restoreCache:async(e,t,n)=>se(e,t,n),saveCache:async(e,t)=>D(e,t)};function ra(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ce}-${t}-oc-${n}-omo-${r}`}function ia(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ce}-${t}-oc-${n}-omo-${r}-`]}async function aa(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=na}=e,l=ra({os:n,opencodeVersion:r,omoVersion:i}),u=ia({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function oa(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=na}=e,l=ra({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const sa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function ca(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(sa.includes(e))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 la(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ua(){return{exec:x,getExecOutput:c}}function da(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null,omoConfig:m(`omo-config`)||null}}async function fa(){let e=Date.now(),n=A({component:`setup`}),r=la(),o=ua();try{let s=da(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await ta(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=Yi}let d=m(`omo-version`).trim(),f=d.length>0?d:P,h=H.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=V(h,`opencode`),v=V(h,`bun`),y=V(De(),`.config`,`opencode`),b=a(),x=await aa({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await $i(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){if(s.omoConfig!=null)try{await Ki(s.omoConfig,y,n)}catch(e){n.warning(`Failed to write omo-config, continuing without custom config`,{error:M(e)})}let e=m(`omo-providers`).trim(),t=ca(e.length>0?e:oe),r=await qi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1};if(s.opencodeConfig!=null){let e=JSON.parse(s.opencodeConfig);if(typeof e!=`object`||!e||Array.isArray(e))return _(`opencode-config must be a JSON object`),null;Object.assign(te,e)}p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await oa({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),z(`opencode-path`,C.path),z(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=V(i(),`opencode`),k=await Mi(l,O,n);z(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=H.env.GITHUB_REPOSITORY??`unknown/unknown`,j=H.env.GITHUB_REF_NAME??`main`,N=a(),ie=ee({agentIdentity:`github`,repo:A,ref:j,os:N}),F=ae({agentIdentity:`github`,repo:A,ref:j,os:N}),I=`miss`;try{let e=await se([O],ie,[...F]);e==null?n.info(`No cache found`):(I=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){I=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}z(`cache-status`,I),z(`storage-path`,O);let L=Date.now()-e,R={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:I,toolsCacheStatus:S,duration:L};return n.info(`Setup complete`,{duration:L}),R}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function pa(e){return{success:!0,data:e}}function ma(e){return{success:!1,error:e}}const ha=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ga(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` +`),appendMode:!0};case`pull_request_review_comment`:return{directive:_a(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function _a(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` +`)}function va(e,t){let{directive:n,appendMode:r}=ga(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` +`)}function ya(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a}=e,o=[];if(o.push(`# Agent Context You are the Fro Bot Agent running in a non-interactive CI environment (GitHub Actions). @@ -149,7 +149,7 @@ Execute the requested operation for repository ${n.repo}. Follow all instruction `):o.push(`## Task Respond to the trigger comment above. Follow all instructions and requirements listed in this prompt. -`):o.push(ga(e.triggerContext,r)),e.triggerContext!=null){let t=e.triggerContext.eventType;(t===`pull_request`||t===`pull_request_review_comment`)&&o.push(xa(n))}if(o.push(` +`):o.push(va(e.triggerContext,r)),e.triggerContext!=null){let t=e.triggerContext.eventType;(t===`pull_request`||t===`pull_request_review_comment`)&&o.push(Ca(n))}if(o.push(` ## Environment - **Repository:** ${n.repo} - **Branch/Ref:** ${n.ref} @@ -167,7 +167,7 @@ Respond to the trigger comment above. Follow all instructions and requirements l \`\`\` ${n.commentBody} \`\`\` -`),a!=null&&o.push(ya(a)),n.diffContext!=null&&o.push(ba(n.diffContext)),n.hydratedContext!=null&&o.push(Ie(n.hydratedContext)),o.push(`## Session Management (REQUIRED) +`),a!=null&&o.push(xa(a)),n.diffContext!=null&&o.push(Sa(n.diffContext)),n.hydratedContext!=null&&o.push(Ie(n.hydratedContext)),o.push(`## Session Management (REQUIRED) Before investigating any issue: 1. Use \`session_search\` to find relevant prior sessions for this repository @@ -178,7 +178,7 @@ Before completing: 1. Ensure your session contains a summary of work done 2. Include key decisions, findings, and outcomes 3. This summary will be searchable in future agent runs -`),n.issueNumber!=null&&o.push(va(n,i,e.sessionId));let s=n.issueNumber??``,c=n.issueNumber!=null;o.push(`## GitHub Operations (Use gh CLI) +`),n.issueNumber!=null&&o.push(ba(n,i,e.sessionId));let s=n.issueNumber??``,c=n.issueNumber!=null;o.push(`## GitHub Operations (Use gh CLI) The \`gh\` CLI is pre-authenticated. Use it for all GitHub operations. ${c?` @@ -215,7 +215,7 @@ gh api repos/${n.repo}/issues --jq '.[].title' gh api repos/${n.repo}/pulls/${s}/files --jq '.[].filename' \`\`\` `);let l=o.join(` -`);return t.debug(`Built agent prompt`,{length:l.length,hasCustom:r!=null,hasSessionContext:a!=null}),l}function va(e,t,n){let r=e.issueNumber??``;return`## Response Protocol (REQUIRED) +`);return t.debug(`Built agent prompt`,{length:l.length,hasCustom:r!=null,hasSessionContext:a!=null}),l}function ba(e,t,n){let r=e.issueNumber??``;return`## Response Protocol (REQUIRED) You MUST post exactly ONE comment or review per invocation. All of your output — your response content AND the Run Summary — goes into that single artifact. @@ -251,12 +251,12 @@ Every response you post — regardless of channel (issue, PR, discussion, review \`\`\` -`}function ya(e){let t=[`## Prior Session Context`];if(e.recentSessions.length>0){t.push(``),t.push(`### Recent Sessions`),t.push(`| ID | Title | Updated | Messages | Agents |`),t.push(`|----|-------|---------|----------|--------|`);for(let n of e.recentSessions.slice(0,5)){let e=new Date(n.updatedAt).toISOString().split(`T`)[0],r=n.agents.join(`, `)||`N/A`,i=n.title||`Untitled`;t.push(`| ${n.id} | ${i} | ${e} | ${n.messageCount} | ${r} |`)}t.push(``),t.push("Use `session_read` to review any of these sessions in detail.")}if(e.priorWorkContext.length>0){t.push(``),t.push(`### Relevant Prior Work`),t.push(``),t.push(`The following sessions contain content related to this issue:`),t.push(``);for(let n of e.priorWorkContext.slice(0,3)){t.push(`**Session ${n.sessionId}:**`),t.push("```markdown");for(let e of n.matches.slice(0,2))t.push(`- ${e.excerpt}`);t.push("```"),t.push(``)}t.push("Use `session_read` to review full context before starting new investigation.")}return t.push(``),t.join(` -`)}function ba(e){let t=[`## Pull Request Diff Summary`];if(t.push(``),t.push(`- **Changed Files:** ${e.changedFiles}`),t.push(`- **Additions:** +${e.additions}`),t.push(`- **Deletions:** -${e.deletions}`),e.truncated&&t.push(`- **Note:** Diff was truncated due to size limits`),e.files.length>0){t.push(``),t.push(`### Changed Files`),t.push(`| File | Status | +/- |`),t.push(`|------|--------|-----|`);for(let n of e.files.slice(0,20))t.push(`| \`${n.filename}\` | ${n.status} | +${n.additions}/-${n.deletions} |`);e.files.length>20&&t.push(`| ... | | +${e.files.length-20} more files |`)}return t.push(``),t.join(` -`)}function xa(e){let t=[`## Output Contract`,``];return t.push(`- Review action: approve/request-changes if confident; otherwise comment-only`),t.push(`- Requested reviewer: ${e.isRequestedReviewer?`yes`:`no`}`),e.authorAssociation!=null&&t.push(`- Author association: ${e.authorAssociation}`),t.push(``),t.join(` -`)}function Sa(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function Ca(e,t,n,r,i){let a=_n(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=vn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function wa(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(Sa(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(on(a),a=``)}else if(e.type===`tool`){let t=e.state;if(t.status===`completed`){let n=e.tool,r=t.input,i=t.title;an(n,i),n.toLowerCase()===`bash`&&Ca(String(r.command??r.cmd??``),String(t.output),l,u,()=>{d++})}}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error;r.error(`Session error`,{error:e});let t=typeof e==`string`?e:String(e);f=fn(e)?pn(t,s??void 0):mn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(on(a),a=``))}return a.length>0&&on(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}async function Ta(e,t,n,r,i,a=E,o){let s=Date.now(),c=0;for(;!r.aborted;){if(await en(500),r.aborted)return{completed:!1,error:`Aborted`};if(o?.sessionError==null)c=0;else{if(c++,c>=3)return i.error(`Session error persisted through grace period`,{sessionId:t,error:o.sessionError,graceCycles:c}),{completed:!1,error:`Session error: ${o.sessionError}`};continue}if(o?.sessionIdle===!0)return i.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let l=Date.now()-s;if(a>0&&l>=a)return i.warning(`Poll timeout reached`,{elapsedMs:l,maxPollTimeMs:a}),{completed:!1,error:`Poll timeout after ${l}ms`};try{let r=((await e.session.status({query:{directory:n}})).data??{})[t];if(r==null)i.debug(`Session status not found in poll response`,{sessionId:t});else if(r.type===`idle`)return i.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else i.debug(`Session status`,{sessionId:t,type:r.type});if(o!=null&&!o.firstMeaningfulEventReceived){let e=Date.now()-s;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:M(e)})}}return{completed:!1,error:`Aborted`}}async function Ea(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}const Da=5e3;function Oa(e){return e==null?!1:Object.values(e.omoProviders).some(e=>e!==`no`)}function ka(e){if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!Oa(e))return{providerID:re.providerID,modelID:re.modelID}}async function Aa(e,t,n,r,i,a,o){let s=a?.agent??R,c=new AbortController,l={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},u=await e.event.subscribe(),d={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},f=wa(u.stream,t,c.signal,o,l).then(e=>{d=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&o.debug(`Event stream error`,{error:e.message})}),p=async()=>{c.abort(),await Ea(f)},m=[{type:`text`,text:n}];r!=null&&r.length>0&&(m.push(...r),o.info(`Including file attachments in prompt`,{count:r.length}));let h=ka(a),g={parts:m};h!=null&&(g.model=h),s!==R&&(g.agent=s),o.debug(`Sending prompt to OpenCode`,{sessionId:t});try{let n=await e.session.promptAsync({path:{id:t},body:g,query:{directory:i}});if(n.error!=null){o.error(`OpenCode prompt failed`,{error:String(n.error)}),await p();let e=fn(n.error)?pn(String(n.error),d.model??void 0):d.llmError;return{success:!1,error:String(n.error),llmError:e,shouldRetry:e!=null,eventStreamResult:d}}let r=a?.timeoutMs??E,s=await Ta(e,t,i,c.signal,o,r,l);if(await p(),!s.completed){let e=s.error??`Session did not reach idle state`;return o.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:d.llmError,shouldRetry:d.llmError!=null,eventStreamResult:d}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:d}}finally{c.abort(),await Ea(f)}}async function ja(e,t){try{let{client:n,server:r}=await $t({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),da({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),fa(Error(`Server bootstrap failed: ${n}`))}}async function Ma(e,t,n,r){let i=Date.now(),a=new AbortController,o=n?.timeoutMs??E,s=null,c=!1,l=r==null,u=null;o>0&&(s=setTimeout(()=>{c=!0,t.warning(`Execution timeout reached`,{timeoutMs:o}),a.abort()},o)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??R,hasModelOverride:n?.model!=null,timeoutMs:o});try{let s;if(r==null){let e=await $t({signal:a.signal});s=e.client,u=e.server,t.debug(`OpenCode server started`,{url:u.url})}else s=r.client,t.debug(`Reusing external OpenCode server`,{url:r.server.url});let l=await s.session.create();if(l.data==null||l.error!=null){let e=l.error==null?`No data returned`:String(l.error);throw Error(`Failed to create session: ${e}`)}let d=l.data.id;t.debug(`Session created`,{sessionId:d});let f=_a({...e,sessionId:d},t),p=v();if(h()){let e=le(),n=xe.createHash(`sha256`).update(f).digest(`hex`),r=B.join(e,`prompt-${d}-${n.slice(0,8)}.txt`);try{await G.mkdir(e,{recursive:!0}),await G.writeFile(r,f,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let m=null,g=null,_=null,y=[],b=[],x=0,S=null,C=null;for(let r=1;r<=3;r++){if(c)return{success:!1,exitCode:130,duration:Date.now()-i,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C};let a=o-(Date.now()-i);if(o>0&&a<=Da&&r>1){t.warning(`Insufficient time remaining for retry`,{remainingMs:a,requiredMs:Da,attempt:r});break}let l=r===1?f:`The previous request was interrupted by a network error (fetch failed). +`}function xa(e){let t=[`## Prior Session Context`];if(e.recentSessions.length>0){t.push(``),t.push(`### Recent Sessions`),t.push(`| ID | Title | Updated | Messages | Agents |`),t.push(`|----|-------|---------|----------|--------|`);for(let n of e.recentSessions.slice(0,5)){let e=new Date(n.updatedAt).toISOString().split(`T`)[0],r=n.agents.join(`, `)||`N/A`,i=n.title||`Untitled`;t.push(`| ${n.id} | ${i} | ${e} | ${n.messageCount} | ${r} |`)}t.push(``),t.push("Use `session_read` to review any of these sessions in detail.")}if(e.priorWorkContext.length>0){t.push(``),t.push(`### Relevant Prior Work`),t.push(``),t.push(`The following sessions contain content related to this issue:`),t.push(``);for(let n of e.priorWorkContext.slice(0,3)){t.push(`**Session ${n.sessionId}:**`),t.push("```markdown");for(let e of n.matches.slice(0,2))t.push(`- ${e.excerpt}`);t.push("```"),t.push(``)}t.push("Use `session_read` to review full context before starting new investigation.")}return t.push(``),t.join(` +`)}function Sa(e){let t=[`## Pull Request Diff Summary`];if(t.push(``),t.push(`- **Changed Files:** ${e.changedFiles}`),t.push(`- **Additions:** +${e.additions}`),t.push(`- **Deletions:** -${e.deletions}`),e.truncated&&t.push(`- **Note:** Diff was truncated due to size limits`),e.files.length>0){t.push(``),t.push(`### Changed Files`),t.push(`| File | Status | +/- |`),t.push(`|------|--------|-----|`);for(let n of e.files.slice(0,20))t.push(`| \`${n.filename}\` | ${n.status} | +${n.additions}/-${n.deletions} |`);e.files.length>20&&t.push(`| ... | | +${e.files.length-20} more files |`)}return t.push(``),t.join(` +`)}function Ca(e){let t=[`## Output Contract`,``];return t.push(`- Review action: approve/request-changes if confident; otherwise comment-only`),t.push(`- Requested reviewer: ${e.isRequestedReviewer?`yes`:`no`}`),e.authorAssociation!=null&&t.push(`- Author association: ${e.authorAssociation}`),t.push(``),t.join(` +`)}function wa(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function Ta(e,t,n,r,i){let a=_n(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=vn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function Ea(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(wa(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(on(a),a=``)}else if(e.type===`tool`){let t=e.state;if(t.status===`completed`){let n=e.tool,r=t.input,i=t.title;an(n,i),n.toLowerCase()===`bash`&&Ta(String(r.command??r.cmd??``),String(t.output),l,u,()=>{d++})}}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error;r.error(`Session error`,{error:e});let t=typeof e==`string`?e:String(e);f=fn(e)?pn(t,s??void 0):mn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(on(a),a=``))}return a.length>0&&on(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}async function Da(e,t,n,r,i,a=E,o){let s=Date.now(),c=0;for(;!r.aborted;){if(await en(500),r.aborted)return{completed:!1,error:`Aborted`};if(o?.sessionError==null)c=0;else{if(c++,c>=3)return i.error(`Session error persisted through grace period`,{sessionId:t,error:o.sessionError,graceCycles:c}),{completed:!1,error:`Session error: ${o.sessionError}`};continue}if(o?.sessionIdle===!0)return i.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let l=Date.now()-s;if(a>0&&l>=a)return i.warning(`Poll timeout reached`,{elapsedMs:l,maxPollTimeMs:a}),{completed:!1,error:`Poll timeout after ${l}ms`};try{let r=((await e.session.status({query:{directory:n}})).data??{})[t];if(r==null)i.debug(`Session status not found in poll response`,{sessionId:t});else if(r.type===`idle`)return i.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else i.debug(`Session status`,{sessionId:t,type:r.type});if(o!=null&&!o.firstMeaningfulEventReceived){let e=Date.now()-s;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:M(e)})}}return{completed:!1,error:`Aborted`}}async function Oa(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}const ka=5e3;function Aa(e){return e==null?!1:Object.values(e.omoProviders).some(e=>e!==`no`)}function ja(e){if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!Aa(e))return{providerID:re.providerID,modelID:re.modelID}}async function Ma(e,t,n,r,i,a,o){let s=a?.agent??R,c=new AbortController,l={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},u=await e.event.subscribe(),d={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},f=Ea(u.stream,t,c.signal,o,l).then(e=>{d=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&o.debug(`Event stream error`,{error:e.message})}),p=async()=>{c.abort(),await Oa(f)},m=[{type:`text`,text:n}];r!=null&&r.length>0&&(m.push(...r),o.info(`Including file attachments in prompt`,{count:r.length}));let h=ja(a),g={parts:m};h!=null&&(g.model=h),s!==R&&(g.agent=s),o.debug(`Sending prompt to OpenCode`,{sessionId:t});try{let n=await e.session.promptAsync({path:{id:t},body:g,query:{directory:i}});if(n.error!=null){o.error(`OpenCode prompt failed`,{error:String(n.error)}),await p();let e=fn(n.error)?pn(String(n.error),d.model??void 0):d.llmError;return{success:!1,error:String(n.error),llmError:e,shouldRetry:e!=null,eventStreamResult:d}}let r=a?.timeoutMs??E,s=await Da(e,t,i,c.signal,o,r,l);if(await p(),!s.completed){let e=s.error??`Session did not reach idle state`;return o.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:d.llmError,shouldRetry:d.llmError!=null,eventStreamResult:d}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:d}}finally{c.abort(),await Oa(f)}}async function Na(e,t){try{let{client:n,server:r}=await $t({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),pa({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),ma(Error(`Server bootstrap failed: ${n}`))}}async function Pa(e,t,n,r){let i=Date.now(),a=new AbortController,o=n?.timeoutMs??E,s=null,c=!1,l=r==null,u=null;o>0&&(s=setTimeout(()=>{c=!0,t.warning(`Execution timeout reached`,{timeoutMs:o}),a.abort()},o)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??R,hasModelOverride:n?.model!=null,timeoutMs:o});try{let s;if(r==null){let e=await $t({signal:a.signal});s=e.client,u=e.server,t.debug(`OpenCode server started`,{url:u.url})}else s=r.client,t.debug(`Reusing external OpenCode server`,{url:r.server.url});let l=await s.session.create();if(l.data==null||l.error!=null){let e=l.error==null?`No data returned`:String(l.error);throw Error(`Failed to create session: ${e}`)}let d=l.data.id;t.debug(`Session created`,{sessionId:d});let f=ya({...e,sessionId:d},t),p=v();if(h()){let e=le(),n=xe.createHash(`sha256`).update(f).digest(`hex`),r=B.join(e,`prompt-${d}-${n.slice(0,8)}.txt`);try{await G.mkdir(e,{recursive:!0}),await G.writeFile(r,f,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let m=null,g=null,_=null,y=[],b=[],x=0,S=null,C=null;for(let r=1;r<=3;r++){if(c)return{success:!1,exitCode:130,duration:Date.now()-i,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C};let a=o-(Date.now()-i);if(o>0&&a<=ka&&r>1){t.warning(`Insufficient time remaining for retry`,{remainingMs:a,requiredMs:ka,attempt:r});break}let l=r===1?f:`The previous request was interrupted by a network error (fetch failed). Please continue where you left off. If you were in the middle of a task, resume it. -If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void 0;t.debug(`Sending prompt`,{attempt:r,isRetry:r>1});try{let e=await Aa(s,d,l,u,p,n,t);if(e.success){let{eventStreamResult:n}=e;m=n.tokens,g=n.model,_=n.cost,y=[...n.prsCreated],b=[...n.commitsCreated],x=n.commentsPosted;let a=Date.now()-i;return t.info(`OpenCode execution completed`,{sessionId:d,durationMs:a,attempts:r}),{success:!0,exitCode:0,duration:a,sessionId:d,error:null,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:null}}if(S=e.error,C=e.llmError,!e.shouldRetry||r>=3){e.shouldRetry&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:e.error});break}t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:e.error,delayMs:Da,sessionId:d}),await en(Da)}catch(e){let n=M(e);t.error(`Prompt attempt failed with exception`,{attempt:r,error:n}),S=n;let i=fn(e)?pn(n):null;if(C=i,i==null||r>=3){i!=null&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:n});break}t.warning(`LLM fetch error detected (exception), retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:n,delayMs:Da,sessionId:d}),await en(Da)}}return{success:!1,exitCode:1,duration:Date.now()-i,sessionId:d,error:S??`Unknown error`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C}}catch(e){let n=Date.now()-i,r=M(e);return t.error(`OpenCode execution failed`,{error:r,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:fn(e)?pn(r):null}}finally{s!=null&&clearTimeout(s),a.abort(),l&&u?.close()}}async function Na(e,t){let n=e??`opencode`;try{let e=``;await x(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function Pa(e){let{logger:n,opencodeVersion:r}=e,i=H.env.OPENCODE_PATH??null,a=await Na(i,n);if(a.available&&a.version!=null)return n.info(`OpenCode already available`,{version:a.version}),{path:i??`opencode`,version:a.version,didSetup:!1};n.info(`OpenCode not found, running auto-setup`,{requestedVersion:r});let o=await ua();if(o==null)throw Error(`Auto-setup failed: runSetup returned null`);return t(o.opencodePath),H.env.OPENCODE_PATH=o.opencodePath,n.info(`Auto-setup completed`,{version:o.opencodeVersion,path:o.opencodePath}),{path:o.opencodePath,version:o.opencodeVersion,didSetup:!0}}const Fa=`agent: working`;async function Ia(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await Ue(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function La(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await Ke(e,t.repo,Fa,`fcf2e1`,`Agent is currently working on this`,n)&&await qe(e,t.repo,t.issueNumber,[Fa],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function Ra(e,t,n){await Promise.all([Ia(e,t,n),La(e,t,n)])}async function za(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await We(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Ge(e,t.repo,t.commentId,r.id,n)}async function Ba(e,t,n,r){t.commentId!=null&&await Ue(e,t.repo,t.commentId,n,r)}async function Va(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:M(e)})}}async function Ha(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await za(e,t,n),await Ba(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:M(e)})}}async function Ua(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Je(e,t.repo,t.issueNumber,Fa,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function Wa(e,t,n,r){n?await Va(e,t,r):await Ha(e,t,r),await Ua(e,t,r)}const Ga={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 Ka(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function qa(e){let t=[],n=new Set;return Ka(Ga.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Ka(Ga.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Ka(Ga.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&gn(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),Ga.htmlImage.lastIndex=0,t}function Ja(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 Ya={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`]},Xa=[`github.com`,`githubusercontent.com`];async function Za(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(!Xa.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=be.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=Ja(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await G.mkdtemp(B.join(Te.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=B.join(p,m);return await G.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:M(t)}),null}}async function Qa(e,t,n=Ya,r){return Promise.all(e.map(async(e,i)=>Za(e,i,t,n,r)))}async function $a(e,t){for(let n of e)try{await G.unlink(n);let e=B.dirname(n);await G.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:M(e)})}}function eo(e){return e.map(e=>({type:`file`,mime:e.mime,url:Se(e.tempPath).toString(),filename:e.filename}))}function to(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 no(e,t,n,r){return{processed:n,skipped:r,modifiedBody:to(e,t,n),fileParts:eo(n),tempFiles:n.map(e=>e.tempPath)}}function ro(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function io(e,t=Ya,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 (${ro(o.sizeBytes)} > ${ro(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 (${ro(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!ao(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 ao(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}const oo=``;function so(e,t){return t==null?!1:e===t||e===`${t}[bot]`}function co(e,t,n){return so(e,n)&&t.includes(oo)}async function lo(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:M(e)}),null}}async function uo(e,t,n,r){let i=[],a=1;for(;a<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:a});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;i.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:co(t,e.body??``,n)})}if(r.length<100)break;a++}catch(e){r.warning(`Failed to fetch comments page`,{target:t,page:a,error:M(e)});break}return i}async function fo(e,t,n,r){try{let i=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` +If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void 0;t.debug(`Sending prompt`,{attempt:r,isRetry:r>1});try{let e=await Ma(s,d,l,u,p,n,t);if(e.success){let{eventStreamResult:n}=e;m=n.tokens,g=n.model,_=n.cost,y=[...n.prsCreated],b=[...n.commitsCreated],x=n.commentsPosted;let a=Date.now()-i;return t.info(`OpenCode execution completed`,{sessionId:d,durationMs:a,attempts:r}),{success:!0,exitCode:0,duration:a,sessionId:d,error:null,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:null}}if(S=e.error,C=e.llmError,!e.shouldRetry||r>=3){e.shouldRetry&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:e.error});break}t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:e.error,delayMs:ka,sessionId:d}),await en(ka)}catch(e){let n=M(e);t.error(`Prompt attempt failed with exception`,{attempt:r,error:n}),S=n;let i=fn(e)?pn(n):null;if(C=i,i==null||r>=3){i!=null&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:n});break}t.warning(`LLM fetch error detected (exception), retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:n,delayMs:ka,sessionId:d}),await en(ka)}}return{success:!1,exitCode:1,duration:Date.now()-i,sessionId:d,error:S??`Unknown error`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C}}catch(e){let n=Date.now()-i,r=M(e);return t.error(`OpenCode execution failed`,{error:r,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:fn(e)?pn(r):null}}finally{s!=null&&clearTimeout(s),a.abort(),l&&u?.close()}}async function Fa(e,t){let n=e??`opencode`;try{let e=``;await x(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function Ia(e){let{logger:n,opencodeVersion:r}=e,i=H.env.OPENCODE_PATH??null,a=await Fa(i,n);if(a.available&&a.version!=null)return n.info(`OpenCode already available`,{version:a.version}),{path:i??`opencode`,version:a.version,didSetup:!1};n.info(`OpenCode not found, running auto-setup`,{requestedVersion:r});let o=await fa();if(o==null)throw Error(`Auto-setup failed: runSetup returned null`);return t(o.opencodePath),H.env.OPENCODE_PATH=o.opencodePath,n.info(`Auto-setup completed`,{version:o.opencodeVersion,path:o.opencodePath}),{path:o.opencodePath,version:o.opencodeVersion,didSetup:!0}}const La=`agent: working`;async function Ra(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await Ue(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function za(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await Ke(e,t.repo,La,`fcf2e1`,`Agent is currently working on this`,n)&&await qe(e,t.repo,t.issueNumber,[La],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function Ba(e,t,n){await Promise.all([Ra(e,t,n),za(e,t,n)])}async function Va(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await We(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Ge(e,t.repo,t.commentId,r.id,n)}async function Ha(e,t,n,r){t.commentId!=null&&await Ue(e,t.repo,t.commentId,n,r)}async function Ua(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await Va(e,t,n),await Ha(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:M(e)})}}async function Wa(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await Va(e,t,n),await Ha(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:M(e)})}}async function Ga(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Je(e,t.repo,t.issueNumber,La,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function Ka(e,t,n,r){n?await Ua(e,t,r):await Wa(e,t,r),await Ga(e,t,r)}const qa={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 Ja(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function Ya(e){let t=[],n=new Set;return Ja(qa.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Ja(qa.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Ja(qa.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&gn(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),qa.htmlImage.lastIndex=0,t}function Xa(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 Za={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`]},Qa=[`github.com`,`githubusercontent.com`];async function $a(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(!Qa.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=be.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=Xa(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await G.mkdtemp(B.join(Te.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=B.join(p,m);return await G.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:M(t)}),null}}async function eo(e,t,n=Za,r){return Promise.all(e.map(async(e,i)=>$a(e,i,t,n,r)))}async function to(e,t){for(let n of e)try{await G.unlink(n);let e=B.dirname(n);await G.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:M(e)})}}function no(e){return e.map(e=>({type:`file`,mime:e.mime,url:Se(e.tempPath).toString(),filename:e.filename}))}function ro(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 io(e,t,n,r){return{processed:n,skipped:r,modifiedBody:ro(e,t,n),fileParts:no(n),tempFiles:n.map(e=>e.tempPath)}}function ao(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function oo(e,t=Za,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 (${ao(o.sizeBytes)} > ${ao(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 (${ao(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!so(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 so(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}const co=``;function lo(e,t){return t==null?!1:e===t||e===`${t}[bot]`}function uo(e,t,n){return lo(e,n)&&t.includes(co)}async function fo(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:M(e)}),null}}async function po(e,t,n,r){let i=[],a=1;for(;a<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:a});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;i.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:uo(t,e.body??``,n)})}if(r.length<100)break;a++}catch(e){r.warning(`Failed to fetch comments page`,{target:t,page:a,error:M(e)});break}return i}async function mo(e,t,n,r){try{let i=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` query GetDiscussion($owner: String!, $repo: String!, $number: Int!, $after: String) { repository(owner: $owner, name: $repo) { discussion(number: $number) { @@ -280,7 +280,7 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void } } } -`,{owner:t.owner,repo:t.repo,number:t.number,after:a})).repository.discussion;if(d==null)return r.debug(`Discussion not found`,{target:t}),null;u===0&&(o=d.id,s=d.title,c=d.body,l=d.author?.login??`unknown`);for(let e of d.comments.nodes){let t=e.author?.login??`unknown`;i.push({id:e.id,body:e.body,author:t,authorAssociation:`NONE`,createdAt:e.createdAt,updatedAt:e.updatedAt,isBot:co(t,e.body,n)})}if(!d.comments.pageInfo.hasNextPage)break;a=d.comments.pageInfo.endCursor,u++}return{type:`discussion`,number:t.number,title:s,body:c,author:l,comments:i,discussionId:o??void 0}}catch(e){return r.warning(`Failed to fetch discussion`,{target:t,error:M(e)}),null}}async function po(e,t,n,r){if(t.type===`discussion`)return fo(e,t,n,r);let i=await lo(e,t,r);if(i==null)return null;let a=await uo(e,t,n,r);return{type:t.type,number:t.number,title:i.title,body:i.body,author:i.author,comments:a}}function mo(e,t){let n=e.comments.filter(e=>so(e.author,t)&&e.body.includes(oo));return n.length===0?null:n.at(-1)??null}async function ho(e,t,n,r){try{let{data:i}=await e.rest.issues.createComment({owner:t.owner,repo:t.repo,issue_number:t.number,body:n});return r.debug(`Created issue comment`,{commentId:i.id,target:t}),{commentId:i.id,created:!0,updated:!1,url:i.html_url}}catch(e){return r.warning(`Failed to create issue comment`,{target:t,error:M(e)}),null}}async function go(e,t,n,r,i){try{let{data:a}=await e.rest.issues.updateComment({owner:t.owner,repo:t.repo,comment_id:n,body:r});return i.debug(`Updated issue comment`,{commentId:a.id,target:t}),{commentId:a.id,created:!1,updated:!0,url:a.html_url}}catch(e){return i.warning(`Failed to update issue comment`,{target:t,commentId:n,error:M(e)}),null}}async function _o(e,t,n,r){try{let i=(await e.graphql(` +`,{owner:t.owner,repo:t.repo,number:t.number,after:a})).repository.discussion;if(d==null)return r.debug(`Discussion not found`,{target:t}),null;u===0&&(o=d.id,s=d.title,c=d.body,l=d.author?.login??`unknown`);for(let e of d.comments.nodes){let t=e.author?.login??`unknown`;i.push({id:e.id,body:e.body,author:t,authorAssociation:`NONE`,createdAt:e.createdAt,updatedAt:e.updatedAt,isBot:uo(t,e.body,n)})}if(!d.comments.pageInfo.hasNextPage)break;a=d.comments.pageInfo.endCursor,u++}return{type:`discussion`,number:t.number,title:s,body:c,author:l,comments:i,discussionId:o??void 0}}catch(e){return r.warning(`Failed to fetch discussion`,{target:t,error:M(e)}),null}}async function ho(e,t,n,r){if(t.type===`discussion`)return mo(e,t,n,r);let i=await fo(e,t,r);if(i==null)return null;let a=await po(e,t,n,r);return{type:t.type,number:t.number,title:i.title,body:i.body,author:i.author,comments:a}}function go(e,t){let n=e.comments.filter(e=>lo(e.author,t)&&e.body.includes(co));return n.length===0?null:n.at(-1)??null}async function _o(e,t,n,r){try{let{data:i}=await e.rest.issues.createComment({owner:t.owner,repo:t.repo,issue_number:t.number,body:n});return r.debug(`Created issue comment`,{commentId:i.id,target:t}),{commentId:i.id,created:!0,updated:!1,url:i.html_url}}catch(e){return r.warning(`Failed to create issue comment`,{target:t,error:M(e)}),null}}async function vo(e,t,n,r,i){try{let{data:a}=await e.rest.issues.updateComment({owner:t.owner,repo:t.repo,comment_id:n,body:r});return i.debug(`Updated issue comment`,{commentId:a.id,target:t}),{commentId:a.id,created:!1,updated:!0,url:a.html_url}}catch(e){return i.warning(`Failed to update issue comment`,{target:t,commentId:n,error:M(e)}),null}}async function yo(e,t,n,r){try{let i=(await e.graphql(` query GetDiscussionId($owner: String!, $repo: String!, $number: Int!) { repository(owner: $owner, name: $repo) { discussion(number: $number) { @@ -301,7 +301,7 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void } } } -`,{owner:t.owner,repo:t.repo,number:t.number})).repository.discussion;if(i==null)return r.warning(`Discussion not found`,{target:t}),null;if(n.updateExisting===!0&&n.botLogin!=null){let i=await po(e,t,n.botLogin,r);if(i!=null){let t=mo(i,n.botLogin);if(t!=null&&typeof t.id==`string`){let i=await e.graphql(` +`,{owner:t.owner,repo:t.repo,number:t.number})).repository.discussion;if(i==null)return r.warning(`Discussion not found`,{target:t}),null;if(n.updateExisting===!0&&n.botLogin!=null){let i=await ho(e,t,n.botLogin,r);if(i!=null){let t=go(i,n.botLogin);if(t!=null&&typeof t.id==`string`){let i=await e.graphql(` mutation UpdateDiscussionComment($commentId: ID!, $body: String!) { updateDiscussionComment(input: {commentId: $commentId, body: $body}) { comment { id url } @@ -313,6 +313,6 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void comment { id url } } } -`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:M(e)}),null}}async function vo(e,t,n,r){if(t.type===`discussion`)return _o(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await po(e,t,n.botLogin,r);if(i!=null){let a=mo(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return go(e,t,a.id,n.body,r)}}return ho(e,t,n.body,r)}function yo(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function bo(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function xo(e){let t=ci,n=yo(t.eventName),r=bo(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function So(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function Co(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function wo(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 To(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Eo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function Do(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`;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}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function Oo(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return fa(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return fa(Error(`auth-json is required but was not provided`));So(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?Co(i,`session-retention`):O,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:R,p=m(`model`).trim(),h=p.length>0?wo(p):null,g=m(`timeout`).trim(),_=g.length>0?To(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:k,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:N,C=m(`omo-providers`).trim(),w=Do(C.length>0?C:se),T=m(`opencode-config`).trim(),ee=T.length>0?T:null;return ee!=null&&So(ee,`opencode-config`),da({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:w,opencodeConfig:ee})}catch(e){return fa(e instanceof Error?e:Error(String(e)))}}function ko(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Ao(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function jo(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(P.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,ko(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Ao(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(P.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&P.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&P.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(P.addHeading(`Token Usage`,3),P.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&P.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&P.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(P.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&P.addList([...c.prsCreated]),c.commitsCreated.length>0&&P.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&P.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){P.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;P.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await P.write(),t.debug(`Wrote job summary`)}catch(e){let r=M(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Mo(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function No(e){z(`session-id`,e.sessionId??``),z(`cache-status`,e.cacheStatus),z(`duration`,e.duration)}function Po(e){let t=B.resolve(e);return t.endsWith(B.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function Fo(e){return typeof e==`boolean`?e:null}function Io(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function Lo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Io(e.diffs)}}function Ro(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function zo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Bo(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:zo(e.time),summary:Lo(e.summary),share:Ro(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Vo(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Io(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Ho(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:Fo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function Uo(e){return Z(e)?Q(e.role)===`assistant`?Ho(e):Vo(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Wo(e){let t=Uo(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(qo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function Go(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Ko(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function qo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=Go(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:Fo(e.synthetic)??void 0,ignored:Fo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Ko(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Jo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Bo):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function Yo(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Wo)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function Xo(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Bo);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function Zo(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function Qo(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function $o(e,t,n){let r=Po(t),i=await Qo(e,n);for(let e of i){if(Po(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Po(t)===r)return e}return null}async function es(e,t,n){return Jo(e,t,n)}async function ts(e,t,n){return Yo(e,t,n)}async function ns(e,t,n){return Zo(e,t,n)}async function rs(e,t,n,r){return Xo(e,t,n,r)}const is={maxSessions:50,maxAgeDays:30};async function as(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await $o(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await es(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await ns(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:M(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function os(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await es(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await ts(e,t.id,r),i=ss(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ss(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function cs(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ls(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await os(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ls(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ls(e,t,n,r,i){let a=await ts(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=us(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function us(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ds(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` -`)}async function fs(e,t,n,r){let i=ds(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:i}]}});if(t.error!=null){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}r.info(`Session summary written via SDK`,{sessionId:e})}catch(t){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:M(t)})}}const ps=/^[0-9a-f]{40}$/i;function ms(){return{exec:x,getExecOutput:c}}async function hs(e){let{workspacePath:t,logger:n,execAdapter:r=ms()}=e,i=B.join(t,`.git`),a=B.join(i,`opencode`);try{let e=(await G.readFile(a,`utf8`)).trim();if(e.length>0){if(ps.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:M(e)})}try{if((await G.stat(i)).isDirectory()===!1){let e=await G.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=B.resolve(t,n[1]),a=B.join(i,`opencode`)}}catch{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 G.writeFile(a,s,`utf8`),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){n.warning(`Failed to cache project ID (continuing)`,{error:M(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:M(e)}}}const gs={botLogin:null,requireMention:!0,allowedAssociations:pa,skipDraftPRs:!0,promptInput:null};function _s(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${vs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function vs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function ys(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${vs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function bs(e,t){return t.includes(e)}function xs(e){return e.endsWith(`[bot]`)}function Ss(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=_s(e,t);return{hasMention:n,command:n?ys(e,t):null}}function Cs(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},i=e.comment.body,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function ws(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:e.comment.body??e.discussion.body??null,locked:e.discussion.locked},i=e.comment.body??null,a=e.comment.id,{hasMention:o,command:s}=Ss(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Ts(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Es(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:xs(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=Ss(e.issue.body??``,t);return{author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,action:e.action}}const Ds=[`opened`,`edited`];function Os(e){return Ds.includes(e)}function ks(e,t,n){let r=e.action;return r==null||!Os(r)?(n.debug(`Skipping unsupported issues action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${r}' is not supported (only 'opened' and 'edited')`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):r===`edited`&&!e.hasMention?(n.debug(`Skipping issues.edited without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}):e.target?.locked===!0?(n.debug(`Skipping locked issue`),{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}):{shouldSkip:!1}}function As(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:xs(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft},{hasMention:i,command:a}=Ss(e.pullRequest.body??``,t);return{author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,action:e.action}}const js=[`opened`,`synchronize`,`reopened`];function Ms(e){return js.includes(e)}function Ns(e,t,n){let r=e.action;return r==null||!Ms(r)?(n.debug(`Skipping unsupported pull_request action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${r}' is not supported`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.skipDraftPRs&&e.target?.isDraft===!0?(n.debug(`Skipping draft PR`),{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}):e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):{shouldSkip:!1}}function Ps(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:xs(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=Ss(e.comment.body,t);return{author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,action:e.action}}function Fs(e,t,n){let r=n?.trim()??``;return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Is(e,t){return(e.promptInput?.trim()??``)===``?(t.debug(`Skipping schedule event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}):{shouldSkip:!1}}function Ls(e,t){return(e.commentBody?.trim()??``)===``?(t.debug(`Skipping workflow_dispatch event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}):{shouldSkip:!1}}function Rs(e,t,n,r){let{targetLabel:i,actionLabel:a}=r;return e.action===`created`?e.target?.locked===!0?(n.debug(`Skipping locked ${i}`),{shouldSkip:!0,reason:`issue_locked`,message:`${i} is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping ${a} without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created ${a} action`,{action:e.action}),{shouldSkip:!0,reason:`action_not_created`,message:`${a} action is '${e.action}', not 'created'`})}function zs(e,t,n){return Rs(e,t,n,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function Bs(e,t,n){return Rs(e,t,n,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}function Vs(e,t,n){let r=e.action;return r===`created`?e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!bs(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping review comment without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created review comment action`,{action:r}),{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${r}' is not supported (only 'created')`})}function Hs(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e.eventName}`};switch(e.eventType){case`issue_comment`:return zs(e,t,n);case`discussion_comment`:return Bs(e,t,n);case`issues`:return ks(e,t,n);case`pull_request`:return Ns(e,t,n);case`pull_request_review_comment`:return Vs(e,t,n);case`schedule`:return Is(t,n);case`workflow_dispatch`:return Ls(e,n);default:return{shouldSkip:!1}}}function Us(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:{let n=Cs(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`discussion_comment`:{let n=ws(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`workflow_dispatch`:{let t=Ts(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`issues`:{let n=Es(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request`:{let n=As(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request_review_comment`:{let n=Ps(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`schedule`:{let t=Fs(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null}}}function Ws(e,t,n={}){let r={...gs,...n},i=Us(e,r.botLogin,r.promptInput);t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Hs(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function Gs(){let e=Date.now(),t=A({phase:`bootstrap`}),n=null,i=!1,o=0,s=null,c=null,l=null,u=null,d=Mo();d.start(),f(L.SHOULD_SAVE_CACHE,`false`),f(L.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let p=Oo();if(!p.success)return _(`Invalid inputs: ${p.error.message}`),1;let m=p.data,h=A({phase:`main`});h.info(`Action inputs parsed`,{sessionRetention:m.sessionRetention,s3Backup:m.s3Backup,hasGithubToken:m.githubToken.length>0,hasPrompt:m.prompt!=null,agent:m.agent,hasModelOverride:m.model!=null,timeoutMs:m.timeoutMs});let g=await Pa({logger:h,opencodeVersion:m.opencodeVersion});g.didSetup?h.info(`OpenCode auto-setup completed`,{version:g.version}):h.info(`OpenCode already available`,{version:g.version}),f(L.OPENCODE_VERSION,g.version),l=g.version;let b=A({phase:`context`}),x=xo(b);s=Bi({token:m.githubToken,logger:b});let S=await Vi(s,b),C=A({phase:`trigger`}),w=Ws(x,C,{botLogin:S,requireMention:!0,promptInput:m.prompt});if(!w.shouldProcess)return C.info(`Skipping event`,{reason:w.skipReason,message:w.skipMessage}),No({sessionId:null,cacheStatus:`miss`,duration:Date.now()-e}),0;C.info(`Event routed for processing`,{eventType:w.context.eventType,hasMention:w.context.hasMention,command:w.context.command?.action??null}),f(L.SHOULD_SAVE_CACHE,`true`);let T=await et({logger:b,octokit:s,triggerContext:w.context,botLogin:S});n={repo:T.repo,commentId:T.commentId,issueNumber:T.issueNumber,issueType:T.issueType,botLogin:S};let E=A({phase:`acknowledgment`});await Ra(s,n,E);let ee={agentIdentity:`github`,repo:te(),ref:de(),os:a()},D=A({phase:`cache`}),ne=v(),re=B.join(ne,`.git`,`opencode`),O=await ae({components:ee,logger:D,storagePath:y(),authPath:r(),projectIdPath:re,opencodeVersion:g.version}),k=O.corrupted?`corrupted`:O.hit?`hit`:`miss`;d.setCacheStatus(k),h.info(`Cache restore completed`,{cacheStatus:k,key:O.key});let j=await hs({workspacePath:ne,logger:D});j.source===`error`?D.warning(`Failed to generate project ID (continuing)`,{error:j.error}):D.debug(`Project ID ready`,{projectId:j.projectId,source:j.source});let M=A({phase:`server-bootstrap`}),ie=await ja(new AbortController().signal,M);if(!ie.success)return _(`OpenCode server bootstrap failed: ${ie.error.message}`),1;u=ie.data,M.info(`SDK server bootstrapped successfully`);let N=A({phase:`session`}),oe=Po(ne),se=await os(u.client,oe,{limit:10},N);N.debug(`Listed recent sessions`,{count:se.length});let P=T.issueTitle??T.repo,F=await cs(P,u.client,oe,{limit:5},N);N.debug(`Searched prior sessions`,{query:P,resultCount:F.length});for(let e of F)d.addSessionUsed(e.sessionId);let I=A({phase:`attachments`}),R=T.commentBody??``,ce=qa(R);if(ce.length>0){I.info(`Processing attachments`,{count:ce.length});let{validated:e,skipped:t}=io(await Qa(ce,m.githubToken,void 0,I),void 0,I);(e.length>0||t.length>0)&&(c=no(R,ce,e,t),I.info(`Attachments processed`,{processed:e.length,skipped:t.length}))}let le={context:T,customPrompt:m.prompt,cacheStatus:k,sessionContext:{recentSessions:se,priorWorkContext:F},triggerContext:w.context,fileParts:c?.fileParts},ue=H.env.SKIP_AGENT_EXECUTION===`true`,z,fe=Date.now();if(ue)h.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),z={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let e=await Ma(le,A({phase:`execution`}),{agent:m.agent,model:m.model,timeoutMs:m.timeoutMs,omoProviders:m.omoProviders},u??void 0),t=e.sessionId;if(t==null){let e=await rs(u.client,oe,fe,N);e!=null&&(t=e.session.id,N.debug(`Identified session from execution`,{sessionId:t}))}z={...e,sessionId:t}}z.sessionId!=null&&f(L.SESSION_ID,z.sessionId),i=z.success,z.sessionId!=null&&d.addSessionCreated(z.sessionId),z.tokenUsage!=null&&d.setTokenUsage(z.tokenUsage,z.model,z.cost);for(let e of z.prsCreated)d.addPRCreated(e);for(let e of z.commitsCreated)d.addCommitCreated(e);for(let e=0;e0&&n.owner.length>0&&n.repo.length>0){let e=ln(z.llmError),t=A({phase:`error-comment`}),r=await vo(s,n,{body:e},t);r==null?t.warning(`Failed to post LLM error comment`):(t.info(`Posted LLM error comment`,{commentUrl:r.url}),d.incrementComments())}else h.warning(`Cannot post error comment: missing target context`);o=0}}catch(n){o=1;let r=Date.now()-e,i=n instanceof Error?n.name:`UnknownError`,a=n instanceof Error?n.message:String(n);d.recordError(i,a,!1),d.end(),No({sessionId:null,cacheStatus:`miss`,duration:r}),n instanceof Error?(t.error(`Agent failed`,{error:n.message}),_(n.message)):(t.error(`Agent failed with unknown error`),_(`An unknown error occurred`))}finally{try{if(c!=null){let e=A({phase:`attachment-cleanup`});await $a(c.tempFiles,e)}if(n!=null&&s!=null){let e=A({phase:`cleanup`});await Wa(s,n,i,e)}let e=A({phase:`prune`}),t=v();if(u!=null){let n=Po(t),r=await as(u.client,n,is,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let o={agentIdentity:`github`,repo:te(),ref:de(),os:a()},d=A({phase:`cache-save`}),p=B.join(t,`.git`,`opencode`);await F({components:o,runId:ue(),logger:d,storagePath:y(),authPath:r(),projectIdPath:p,opencodeVersion:l})&&f(L.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(u!=null)try{u.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}return o}await Gs().then(e=>{H.exit(e)});export{}; \ No newline at end of file +`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:M(e)}),null}}async function bo(e,t,n,r){if(t.type===`discussion`)return yo(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await ho(e,t,n.botLogin,r);if(i!=null){let a=go(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return vo(e,t,a.id,n.body,r)}}return _o(e,t,n.body,r)}function xo(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function So(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function Co(e){let t=ci,n=xo(t.eventName),r=So(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function wo(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function To(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function Eo(e){let t=e.trim(),n=t.indexOf(`/`);if(n===-1)throw Error(`Invalid model format: "${e}". Expected "provider/model" (e.g., "anthropic/claude-sonnet-4-20250514")`);let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();if(r.length===0)throw Error(`Invalid model format: "${e}". Provider cannot be empty.`);if(i.length===0)throw Error(`Invalid model format: "${e}". Model ID cannot be empty.`);return{providerID:r,modelID:i}}function Do(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Oo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function ko(e){let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),n=`no`,r=`no`,i=`no`,a=`no`,o=`no`,s=`no`;for(let e of t){if(!Oo.includes(e))throw Error(`Invalid omo-providers value: "${e}". Valid values: ${Oo.join(`, `)}`);switch(e){case`claude`:n=`yes`;break;case`claude-max20`:n=`max20`;break;case`copilot`:r=`yes`;break;case`gemini`:i=`yes`;break;case`openai`:a=`yes`;break;case`opencode-zen`:o=`yes`;break;case`zai-coding-plan`:s=`yes`;break}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function Ao(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return ma(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return ma(Error(`auth-json is required but was not provided`));wo(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?To(i,`session-retention`):O,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:R,p=m(`model`).trim(),h=p.length>0?Eo(p):null,g=m(`timeout`).trim(),_=g.length>0?Do(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:k,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:P,C=m(`omo-providers`).trim(),w=ko(C.length>0?C:oe),T=m(`opencode-config`).trim(),ee=T.length>0?T:null;return ee!=null&&wo(ee,`opencode-config`),pa({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:w,opencodeConfig:ee})}catch(e){return ma(e instanceof Error?e:Error(String(e)))}}function jo(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Mo(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function No(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(F.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,jo(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Mo(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(F.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&F.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&F.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(F.addHeading(`Token Usage`,3),F.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&F.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&F.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(F.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&F.addList([...c.prsCreated]),c.commitsCreated.length>0&&F.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&F.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){F.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;F.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await F.write(),t.debug(`Wrote job summary`)}catch(e){let r=M(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Po(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function Fo(e){z(`session-id`,e.sessionId??``),z(`cache-status`,e.cacheStatus),z(`duration`,e.duration)}function Io(e){let t=B.resolve(e);return t.endsWith(B.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function Lo(e){return typeof e==`boolean`?e:null}function Ro(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function zo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Ro(e.diffs)}}function Bo(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function Vo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Ho(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:Vo(e.time),summary:zo(e.summary),share:Bo(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Uo(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Ro(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Wo(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:Lo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function Go(e){return Z(e)?Q(e.role)===`assistant`?Wo(e):Uo(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Ko(e){let t=Go(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(Yo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function qo(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Jo(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function Yo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=qo(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:Lo(e.synthetic)??void 0,ignored:Lo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Jo(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Xo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Ho):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function Zo(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Ko)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function Qo(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Ho);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function $o(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function es(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function ts(e,t,n){let r=Io(t),i=await es(e,n);for(let e of i){if(Io(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Io(t)===r)return e}return null}async function ns(e,t,n){return Xo(e,t,n)}async function rs(e,t,n){return Zo(e,t,n)}async function is(e,t,n){return $o(e,t,n)}async function as(e,t,n,r){return Qo(e,t,n,r)}const os={maxSessions:50,maxAgeDays:30};async function ss(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await ts(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await ns(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await is(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:M(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function cs(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await ns(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await rs(e,t.id,r),i=ls(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ls(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function us(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ds(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await cs(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ds(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ds(e,t,n,r,i){let a=await rs(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=fs(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function fs(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ps(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` +`)}async function ms(e,t,n,r){let i=ps(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:i}]}});if(t.error!=null){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}r.info(`Session summary written via SDK`,{sessionId:e})}catch(t){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:M(t)})}}const hs=/^[0-9a-f]{40}$/i;function gs(){return{exec:x,getExecOutput:c}}async function _s(e){let{workspacePath:t,logger:n,execAdapter:r=gs()}=e,i=B.join(t,`.git`),a=B.join(i,`opencode`);try{let e=(await G.readFile(a,`utf8`)).trim();if(e.length>0){if(hs.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:M(e)})}try{if((await G.stat(i)).isDirectory()===!1){let e=await G.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=B.resolve(t,n[1]),a=B.join(i,`opencode`)}}catch{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 G.writeFile(a,s,`utf8`),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){n.warning(`Failed to cache project ID (continuing)`,{error:M(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:M(e)}}}const vs={botLogin:null,requireMention:!0,allowedAssociations:ha,skipDraftPRs:!0,promptInput:null};function ys(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${bs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function bs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function xs(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${bs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function Ss(e,t){return t.includes(e)}function Cs(e){return e.endsWith(`[bot]`)}function ws(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=ys(e,t);return{hasMention:n,command:n?xs(e,t):null}}function Ts(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Cs(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},i=e.comment.body,a=e.comment.id,{hasMention:o,command:s}=ws(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Es(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Cs(e.comment.author)},r={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:e.comment.body??e.discussion.body??null,locked:e.discussion.locked},i=e.comment.body??null,a=e.comment.id,{hasMention:o,command:s}=ws(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Ds(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Os(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:Cs(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=ws(e.issue.body??``,t);return{author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,action:e.action}}const ks=[`opened`,`edited`];function As(e){return ks.includes(e)}function js(e,t,n){let r=e.action;return r==null||!As(r)?(n.debug(`Skipping unsupported issues action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${r}' is not supported (only 'opened' and 'edited')`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):r===`edited`&&!e.hasMention?(n.debug(`Skipping issues.edited without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}):e.target?.locked===!0?(n.debug(`Skipping locked issue`),{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}):{shouldSkip:!1}}function Ms(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:Cs(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft},{hasMention:i,command:a}=ws(e.pullRequest.body??``,t);return{author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,action:e.action}}const Ns=[`opened`,`synchronize`,`reopened`];function Ps(e){return Ns.includes(e)}function Fs(e,t,n){let r=e.action;return r==null||!Ps(r)?(n.debug(`Skipping unsupported pull_request action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${r}' is not supported`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.skipDraftPRs&&e.target?.isDraft===!0?(n.debug(`Skipping draft PR`),{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}):e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):{shouldSkip:!1}}function Is(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Cs(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=ws(e.comment.body,t);return{author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,action:e.action}}function Ls(e,t,n){let r=n?.trim()??``;return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Rs(e,t){return(e.promptInput?.trim()??``)===``?(t.debug(`Skipping schedule event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}):{shouldSkip:!1}}function zs(e,t){return(e.commentBody?.trim()??``)===``?(t.debug(`Skipping workflow_dispatch event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}):{shouldSkip:!1}}function Bs(e,t,n,r){let{targetLabel:i,actionLabel:a}=r;return e.action===`created`?e.target?.locked===!0?(n.debug(`Skipping locked ${i}`),{shouldSkip:!0,reason:`issue_locked`,message:`${i} is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping ${a} without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created ${a} action`,{action:e.action}),{shouldSkip:!0,reason:`action_not_created`,message:`${a} action is '${e.action}', not 'created'`})}function Vs(e,t,n){return Bs(e,t,n,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function Hs(e,t,n){return Bs(e,t,n,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}function Us(e,t,n){let r=e.action;return r===`created`?e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping review comment without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created review comment action`,{action:r}),{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${r}' is not supported (only 'created')`})}function Ws(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e.eventName}`};switch(e.eventType){case`issue_comment`:return Vs(e,t,n);case`discussion_comment`:return Hs(e,t,n);case`issues`:return js(e,t,n);case`pull_request`:return Fs(e,t,n);case`pull_request_review_comment`:return Us(e,t,n);case`schedule`:return Rs(t,n);case`workflow_dispatch`:return zs(e,n);default:return{shouldSkip:!1}}}function Gs(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:{let n=Ts(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`discussion_comment`:{let n=Es(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`workflow_dispatch`:{let t=Ds(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`issues`:{let n=Os(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request`:{let n=Ms(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request_review_comment`:{let n=Is(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`schedule`:{let t=Ls(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null}}}function Ks(e,t,n={}){let r={...vs,...n},i=Gs(e,r.botLogin,r.promptInput);t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Ws(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function qs(){let e=Date.now(),t=A({phase:`bootstrap`}),n=null,i=!1,o=0,s=null,c=null,l=null,u=null,d=Po();d.start(),f(L.SHOULD_SAVE_CACHE,`false`),f(L.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let p=Ao();if(!p.success)return _(`Invalid inputs: ${p.error.message}`),1;let m=p.data,h=A({phase:`main`});h.info(`Action inputs parsed`,{sessionRetention:m.sessionRetention,s3Backup:m.s3Backup,hasGithubToken:m.githubToken.length>0,hasPrompt:m.prompt!=null,agent:m.agent,hasModelOverride:m.model!=null,timeoutMs:m.timeoutMs});let g=await Ia({logger:h,opencodeVersion:m.opencodeVersion});g.didSetup?h.info(`OpenCode auto-setup completed`,{version:g.version}):h.info(`OpenCode already available`,{version:g.version}),f(L.OPENCODE_VERSION,g.version),l=g.version;let b=A({phase:`context`}),x=Co(b);s=Bi({token:m.githubToken,logger:b});let S=await Vi(s,b),C=A({phase:`trigger`}),w=Ks(x,C,{botLogin:S,requireMention:!0,promptInput:m.prompt});if(!w.shouldProcess)return C.info(`Skipping event`,{reason:w.skipReason,message:w.skipMessage}),Fo({sessionId:null,cacheStatus:`miss`,duration:Date.now()-e}),0;C.info(`Event routed for processing`,{eventType:w.context.eventType,hasMention:w.context.hasMention,command:w.context.command?.action??null}),f(L.SHOULD_SAVE_CACHE,`true`);let T=await et({logger:b,octokit:s,triggerContext:w.context,botLogin:S});n={repo:T.repo,commentId:T.commentId,issueNumber:T.issueNumber,issueType:T.issueType,botLogin:S};let E=A({phase:`acknowledgment`});await Ba(s,n,E);let ee={agentIdentity:`github`,repo:te(),ref:de(),os:a()},D=A({phase:`cache`}),ne=v(),re=B.join(ne,`.git`,`opencode`),O=await ie({components:ee,logger:D,storagePath:y(),authPath:r(),projectIdPath:re,opencodeVersion:g.version}),k=O.corrupted?`corrupted`:O.hit?`hit`:`miss`;d.setCacheStatus(k),h.info(`Cache restore completed`,{cacheStatus:k,key:O.key});let j=await _s({workspacePath:ne,logger:D});j.source===`error`?D.warning(`Failed to generate project ID (continuing)`,{error:j.error}):D.debug(`Project ID ready`,{projectId:j.projectId,source:j.source});let M=A({phase:`server-bootstrap`}),N=await Na(new AbortController().signal,M);if(!N.success)return _(`OpenCode server bootstrap failed: ${N.error.message}`),1;u=N.data,M.info(`SDK server bootstrapped successfully`);let P=A({phase:`session`}),ae=Io(ne),oe=await cs(u.client,ae,{limit:10},P);P.debug(`Listed recent sessions`,{count:oe.length});let F=T.issueTitle??T.repo,I=await us(F,u.client,ae,{limit:5},P);P.debug(`Searched prior sessions`,{query:F,resultCount:I.length});for(let e of I)d.addSessionUsed(e.sessionId);let se=A({phase:`attachments`}),R=T.commentBody??``,ce=Ya(R);if(ce.length>0){se.info(`Processing attachments`,{count:ce.length});let{validated:e,skipped:t}=oo(await eo(ce,m.githubToken,void 0,se),void 0,se);(e.length>0||t.length>0)&&(c=io(R,ce,e,t),se.info(`Attachments processed`,{processed:e.length,skipped:t.length}))}let le={context:T,customPrompt:m.prompt,cacheStatus:k,sessionContext:{recentSessions:oe,priorWorkContext:I},triggerContext:w.context,fileParts:c?.fileParts},ue=H.env.SKIP_AGENT_EXECUTION===`true`,z,fe=Date.now();if(ue)h.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),z={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let e=await Pa(le,A({phase:`execution`}),{agent:m.agent,model:m.model,timeoutMs:m.timeoutMs,omoProviders:m.omoProviders},u??void 0),t=e.sessionId;if(t==null){let e=await as(u.client,ae,fe,P);e!=null&&(t=e.session.id,P.debug(`Identified session from execution`,{sessionId:t}))}z={...e,sessionId:t}}z.sessionId!=null&&f(L.SESSION_ID,z.sessionId),i=z.success,z.sessionId!=null&&d.addSessionCreated(z.sessionId),z.tokenUsage!=null&&d.setTokenUsage(z.tokenUsage,z.model,z.cost);for(let e of z.prsCreated)d.addPRCreated(e);for(let e of z.commitsCreated)d.addCommitCreated(e);for(let e=0;e0&&n.owner.length>0&&n.repo.length>0){let e=ln(z.llmError),t=A({phase:`error-comment`}),r=await bo(s,n,{body:e},t);r==null?t.warning(`Failed to post LLM error comment`):(t.info(`Posted LLM error comment`,{commentUrl:r.url}),d.incrementComments())}else h.warning(`Cannot post error comment: missing target context`);o=0}}catch(n){o=1;let r=Date.now()-e,i=n instanceof Error?n.name:`UnknownError`,a=n instanceof Error?n.message:String(n);d.recordError(i,a,!1),d.end(),Fo({sessionId:null,cacheStatus:`miss`,duration:r}),n instanceof Error?(t.error(`Agent failed`,{error:n.message}),_(n.message)):(t.error(`Agent failed with unknown error`),_(`An unknown error occurred`))}finally{try{if(c!=null){let e=A({phase:`attachment-cleanup`});await to(c.tempFiles,e)}if(n!=null&&s!=null){let e=A({phase:`cleanup`});await Ka(s,n,i,e)}let e=A({phase:`prune`}),t=v();if(u!=null){let n=Io(t),r=await ss(u.client,n,os,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let o={agentIdentity:`github`,repo:te(),ref:de(),os:a()},d=A({phase:`cache-save`}),p=B.join(t,`.git`,`opencode`);await I({components:o,runId:ue(),logger:d,storagePath:y(),authPath:r(),projectIdPath:p,opencodeVersion:l})&&f(L.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(u!=null)try{u.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}return o}await qs().then(e=>{H.exit(e)});export{}; \ No newline at end of file diff --git a/src/lib/setup/omo-config.test.ts b/src/lib/setup/omo-config.test.ts new file mode 100644 index 00000000..47dfbe23 --- /dev/null +++ b/src/lib/setup/omo-config.test.ts @@ -0,0 +1,245 @@ +import type {Logger} from './types.js' +import * as fs from 'node:fs/promises' +import * as os from 'node:os' +import * as path from 'node:path' +import {afterEach, beforeEach, describe, expect, it} from 'vitest' +import {createMockLogger} from '../test-helpers.js' +import {deepMerge, writeOmoConfig} from './omo-config.js' + +describe('deepMerge', () => { + it('merges top-level keys from both objects', () => { + // #given + const target = {a: 1, b: 2} + const source = {b: 3, c: 4} + + // #when + const result = deepMerge(target, source) + + // #then - source values win on conflict + expect(result).toEqual({a: 1, b: 3, c: 4}) + }) + + it('recursively merges nested objects', () => { + // #given + const target = {a: {x: 1, y: 2}, b: 'keep'} + const source = {a: {y: 99, z: 3}} + + // #when + const result = deepMerge(target, source) + + // #then - nested merge preserves unaffected keys + expect(result).toEqual({a: {x: 1, y: 99, z: 3}, b: 'keep'}) + }) + + it('overwrites arrays rather than merging them', () => { + // #given + const target = {arr: [1, 2, 3]} + const source = {arr: [4, 5]} + + // #when + const result = deepMerge(target, source) + + // #then - source array replaces target array + expect(result).toEqual({arr: [4, 5]}) + }) + + it('handles null source gracefully', () => { + // #given + const target = {a: 1} + + // #when + const result = deepMerge(target, {}) + + // #then + expect(result).toEqual({a: 1}) + }) + + it('does not mutate target or source objects', () => { + // #given + const target = {a: {x: 1}} + const source = {a: {y: 2}} + const targetCopy = JSON.parse(JSON.stringify(target)) as typeof target + const sourceCopy = JSON.parse(JSON.stringify(source)) as typeof source + + // #when + deepMerge(target, source) + + // #then - originals unchanged + expect(target).toEqual(targetCopy) + expect(source).toEqual(sourceCopy) + }) + + it('source primitive overwrites target object', () => { + // #given + const target = {a: {x: 1}} + const source = {a: 'string'} + + // #when + const result = deepMerge(target, source) + + // #then - source wins + expect(result).toEqual({a: 'string'}) + }) + + it('handles deeply nested merge', () => { + // #given + const target = {level1: {level2: {level3: {keep: true, override: 'old'}}}} + const source = {level1: {level2: {level3: {override: 'new'}, extra: 42}}} + + // #when + const result = deepMerge(target, source) + + // #then + expect(result).toEqual({level1: {level2: {level3: {keep: true, override: 'new'}, extra: 42}}}) + }) +}) + +describe('writeOmoConfig', () => { + let tmpDir: string + let logger: Logger + + beforeEach(async () => { + tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'omo-config-test-')) + logger = createMockLogger() + }) + + afterEach(async () => { + await fs.rm(tmpDir, {recursive: true, force: true}) + }) + + it('creates config directory if it does not exist', async () => { + // #given + const configDir = path.join(tmpDir, 'nested', 'dir', 'opencode') + const configJson = JSON.stringify({theme: 'dark'}) + + // #when + await writeOmoConfig(configJson, configDir, logger) + + // #then - directory created and file written + const filePath = path.join(configDir, 'oh-my-opencode.json') + const content = await fs.readFile(filePath, 'utf8') + expect(JSON.parse(content)).toEqual({theme: 'dark'}) + }) + + it('writes config to oh-my-opencode.json in configDir', async () => { + // #given + const configJson = JSON.stringify({model: 'claude-opus-4-5', theme: 'light'}) + + // #when + await writeOmoConfig(configJson, tmpDir, logger) + + // #then + const filePath = path.join(tmpDir, 'oh-my-opencode.json') + const content = await fs.readFile(filePath, 'utf8') + expect(JSON.parse(content)).toEqual({model: 'claude-opus-4-5', theme: 'light'}) + }) + + it('deep-merges with existing config, user values win', async () => { + // #given - existing config has some keys + const existingConfig = {theme: 'dark', keybindings: 'vim', plugins: ['a', 'b']} + const filePath = path.join(tmpDir, 'oh-my-opencode.json') + await fs.writeFile(filePath, JSON.stringify(existingConfig)) + + const userConfig = JSON.stringify({theme: 'light', model: 'gpt-4o'}) + + // #when + await writeOmoConfig(userConfig, tmpDir, logger) + + // #then - user theme overrides existing, keybindings preserved, model added + const content = await fs.readFile(filePath, 'utf8') + expect(JSON.parse(content)).toEqual({ + theme: 'light', + keybindings: 'vim', + plugins: ['a', 'b'], + model: 'gpt-4o', + }) + }) + + it('writes user config as-is when no existing config', async () => { + // #given - no pre-existing config file + const configJson = JSON.stringify({hooks: {before: 'echo start'}}) + + // #when + await writeOmoConfig(configJson, tmpDir, logger) + + // #then + const filePath = path.join(tmpDir, 'oh-my-opencode.json') + const content = await fs.readFile(filePath, 'utf8') + expect(JSON.parse(content)).toEqual({hooks: {before: 'echo start'}}) + }) + + it('throws on invalid JSON input', async () => { + // #given + const invalidJson = '{invalid json}' + + // #when / #then + await expect(writeOmoConfig(invalidJson, tmpDir, logger)).rejects.toThrow() + }) + + it('logs info after writing config', async () => { + // #given + const configJson = JSON.stringify({theme: 'dark'}) + + // #when + await writeOmoConfig(configJson, tmpDir, logger) + + // #then + expect((logger.info as ReturnType).mock.calls.length).toBeGreaterThan(0) + }) + + it('handles nested object merge in user config', async () => { + // #given - existing config has nested structure + const existingConfig = { + providers: { + anthropic: {model: 'claude-3-5-sonnet', maxTokens: 4096}, + openai: {model: 'gpt-4o'}, + }, + } + const filePath = path.join(tmpDir, 'oh-my-opencode.json') + await fs.writeFile(filePath, JSON.stringify(existingConfig)) + + // user overrides anthropic model only + const userConfig = JSON.stringify({providers: {anthropic: {model: 'claude-opus-4-5'}}}) + + // #when + await writeOmoConfig(userConfig, tmpDir, logger) + + // #then - nested merge preserves maxTokens and openai + const content = await fs.readFile(filePath, 'utf8') + expect(JSON.parse(content)).toEqual({ + providers: { + anthropic: {model: 'claude-opus-4-5', maxTokens: 4096}, + openai: {model: 'gpt-4o'}, + }, + }) + }) + + it('overwrites existing file when existing config is not valid JSON', async () => { + // #given - corrupt existing file + const filePath = path.join(tmpDir, 'oh-my-opencode.json') + await fs.writeFile(filePath, 'not valid json {{{') + + const userConfig = JSON.stringify({theme: 'dark'}) + + // #when - should not throw; falls back to user config only + await writeOmoConfig(userConfig, tmpDir, logger) + + // #then - user config written as-is + const content = await fs.readFile(filePath, 'utf8') + expect(JSON.parse(content)).toEqual({theme: 'dark'}) + }) + + it('writes valid JSON (pretty-printed)', async () => { + // #given + const configJson = JSON.stringify({a: 1, b: {c: 2}}) + + // #when + await writeOmoConfig(configJson, tmpDir, logger) + + // #then - output is pretty-printed (contains newlines) + const filePath = path.join(tmpDir, 'oh-my-opencode.json') + const raw = await fs.readFile(filePath, 'utf8') + expect(raw).toContain('\n') + expect(JSON.parse(raw)).toEqual({a: 1, b: {c: 2}}) + }) +}) diff --git a/src/lib/setup/omo-config.ts b/src/lib/setup/omo-config.ts new file mode 100644 index 00000000..eab5df38 --- /dev/null +++ b/src/lib/setup/omo-config.ts @@ -0,0 +1,81 @@ +import type {Logger} from './types.js' +import * as fs from 'node:fs/promises' +import * as path from 'node:path' + +const OMO_CONFIG_FILENAME = 'oh-my-opencode.json' + +/** + * Deep-merge two plain objects. + * + * Source values win over target values on conflict. + * Arrays are replaced (not merged element-by-element). + * Primitive source values always overwrite target. + * + * Neither the target nor the source is mutated. + * + * @param target - Base object (lower priority) + * @param source - Override object (higher priority) + * @returns New merged object + */ +export function deepMerge(target: Record, source: Record): Record { + const result: Record = {...target} + + for (const [key, sourceValue] of Object.entries(source)) { + const targetValue = result[key] + + if ( + sourceValue != null && + typeof sourceValue === 'object' && + !Array.isArray(sourceValue) && + targetValue != null && + typeof targetValue === 'object' && + !Array.isArray(targetValue) + ) { + result[key] = deepMerge(targetValue as Record, sourceValue as Record) + } else { + result[key] = sourceValue + } + } + + return result +} + +/** + * Write oMo configuration JSON to the oMo config file, deep-merging with any + * existing configuration so that user-provided values take priority. + * + * The config file is written to `/oh-my-opencode.json`. + * If the directory does not exist it is created. If the existing file + * contains invalid JSON, it is silently replaced with the user config. + * + * @param configJson - Raw JSON string from the `omo-config` action input + * @param configDir - Directory containing `oh-my-opencode.json` + * (typically `~/.config/opencode`) + * @param logger - Logger instance + */ +export async function writeOmoConfig(configJson: string, configDir: string, logger: Logger): Promise { + // Parse user-supplied JSON first — throw early if invalid + const userConfig = JSON.parse(configJson) as Record + + await fs.mkdir(configDir, {recursive: true}) + + const filePath = path.join(configDir, OMO_CONFIG_FILENAME) + + // Attempt to read existing config; silently ignore missing / corrupt files + let existingConfig: Record = {} + try { + const raw = await fs.readFile(filePath, 'utf8') + const parsed: unknown = JSON.parse(raw) + if (parsed != null && typeof parsed === 'object' && !Array.isArray(parsed)) { + existingConfig = parsed as Record + } + } catch { + // File absent or corrupt — start from empty base + } + + const merged = deepMerge(existingConfig, userConfig) + + await fs.writeFile(filePath, JSON.stringify(merged, null, 2)) + + logger.info('Wrote oMo config', {path: filePath, keyCount: Object.keys(userConfig).length}) +} diff --git a/src/lib/setup/setup.test.ts b/src/lib/setup/setup.test.ts index 97edd739..78bb647e 100644 --- a/src/lib/setup/setup.test.ts +++ b/src/lib/setup/setup.test.ts @@ -737,5 +737,80 @@ describe('setup', () => { expect(result?.omoInstalled).toBe(true) }) }) + + describe('omo-config input', () => { + beforeEach(() => { + vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') + vi.mocked(exec.getExecOutput).mockResolvedValue({exitCode: 0, stdout: '', stderr: ''}) + vi.mocked(exec.exec).mockResolvedValue(0) + vi.mocked(fs.writeFile).mockResolvedValue() + vi.mocked(fs.mkdir).mockResolvedValue(undefined) + vi.mocked(fs.access).mockRejectedValue(new Error('not found')) + vi.mocked(fs.readFile).mockRejectedValue(Object.assign(new Error('not found'), {code: 'ENOENT'})) + }) + + it('writes omo-config JSON to oh-my-opencode.json before installer runs', async () => { + // #given + const customConfig = JSON.stringify({theme: 'dark', model: 'claude-opus-4-5'}) + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{"anthropic": {"api_key": "sk-ant-test"}}', + 'opencode-version': 'latest', + 'omo-config': customConfig, + } + return inputs[name] ?? '' + }) + + // #when + const result = await runSetup() + + // #then - writeFile called for oh-my-opencode.json + expect(result).not.toBeNull() + const writeFileCalls = vi.mocked(fs.writeFile).mock.calls + const omoConfigCall = writeFileCalls.find( + ([filePath]) => typeof filePath === 'string' && filePath.includes('oh-my-opencode.json'), + ) + expect(omoConfigCall).toBeDefined() + const written = JSON.parse(omoConfigCall?.[1] as string) as Record + expect(written).toMatchObject({theme: 'dark', model: 'claude-opus-4-5'}) + }) + + it('does not write oh-my-opencode.json when omo-config is not provided', async () => { + // #given - no omo-config input (default mock returns empty string) + + // #when + const result = await runSetup() + + // #then - oh-my-opencode.json is not written + expect(result).not.toBeNull() + const writeFileCalls = vi.mocked(fs.writeFile).mock.calls + const omoConfigCall = writeFileCalls.find( + ([filePath]) => typeof filePath === 'string' && filePath.includes('oh-my-opencode.json'), + ) + expect(omoConfigCall).toBeUndefined() + }) + + it('continues setup and warns when omo-config JSON is invalid', async () => { + // #given - invalid JSON in omo-config + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{"anthropic": {"api_key": "sk-ant-test"}}', + 'opencode-version': 'latest', + 'omo-config': '{invalid json}', + } + return inputs[name] ?? '' + }) + + // #when + const result = await runSetup() + + // #then - setup continues despite bad omo-config + expect(result).not.toBeNull() + expect(core.setFailed).not.toHaveBeenCalled() + expect(core.warning).toHaveBeenCalledWith(expect.stringContaining('omo-config')) + }) + }) }) }) diff --git a/src/lib/setup/setup.ts b/src/lib/setup/setup.ts index 519637e1..0389c574 100644 --- a/src/lib/setup/setup.ts +++ b/src/lib/setup/setup.ts @@ -16,6 +16,7 @@ import {createLogger} from '../logger.js' import {parseAuthJsonInput, populateAuthJson} from './auth-json.js' import {installBun} from './bun.js' import {configureGhAuth, configureGitIdentity} from './gh-auth.js' +import {writeOmoConfig} from './omo-config.js' import {installOmo} from './omo.js' import {FALLBACK_VERSION, getLatestVersion, installOpenCode} from './opencode.js' import {restoreToolsCache, saveToolsCache} from './tools-cache.js' @@ -114,6 +115,7 @@ function parseSetupInputs(): SetupInputs { appId: core.getInput('app-id') || null, privateKey: core.getInput('private-key') || null, opencodeConfig: core.getInput('opencode-config') || null, + omoConfig: core.getInput('omo-config') || null, } } @@ -225,6 +227,17 @@ export async function runSetup(): Promise { // Run oMo installer to ensure config values (e.g. provider settings) are current. // Skip if Bun install failed — bunx won't be available. if (bunInstalled) { + // Write omo-config before installer runs so it can observe any custom settings + if (inputs.omoConfig != null) { + try { + await writeOmoConfig(inputs.omoConfig, omoConfigPath, logger) + } catch (error) { + logger.warning('Failed to write omo-config, continuing without custom config', { + error: toErrorMessage(error), + }) + } + } + const omoProvidersRaw = core.getInput('omo-providers').trim() const omoOptions = parseOmoProviders(omoProvidersRaw.length > 0 ? omoProvidersRaw : DEFAULT_OMO_PROVIDERS) const omoResult = await installOmo(omoVersion, {logger, execAdapter}, omoOptions) diff --git a/src/lib/setup/types.ts b/src/lib/setup/types.ts index 1709a475..cc5ad1ac 100644 --- a/src/lib/setup/types.ts +++ b/src/lib/setup/types.ts @@ -14,6 +14,7 @@ export interface SetupInputs { readonly appId: string | null readonly privateKey: string | null readonly opencodeConfig: string | null + readonly omoConfig: string | null } /** From a0fda79786f6b408d0b85cb9983c327f631d1279 Mon Sep 17 00:00:00 2001 From: "Marcus R. Brown" Date: Sun, 1 Mar 2026 16:33:42 -0700 Subject: [PATCH 7/8] fix(inputs): add kimi-for-coding to input validation and types Previously, kimi-for-coding was listed as a valid value in action.yaml and handled in setup.ts's parseOmoProviders, but was absent from inputs.ts. This caused users who set 'omo-providers: kimi-for-coding' to fail input validation with: Invalid omo-providers value: "kimi-for-coding". Valid values: ... Three files updated: 1. src/lib/inputs.ts: added 'kimi-for-coding' to VALID_OMO_PROVIDERS and parseOmoProviders function 2. src/lib/types.ts: added readonly kimiForCoding field to OmoProviders 3. src/lib/agent/opencode.test.ts: updated all OmoProviders test objects Fixes PR #266 blocking issue; all 961 tests pass. --- dist/main.js | 2 +- src/lib/agent/opencode.test.ts | 60 ++++++++++++++++++++++++++++++---- src/lib/inputs.ts | 7 +++- src/lib/types.ts | 1 + 4 files changed, 62 insertions(+), 8 deletions(-) diff --git a/dist/main.js b/dist/main.js index 515dca2e..65cd0bac 100644 --- a/dist/main.js +++ b/dist/main.js @@ -313,6 +313,6 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void comment { id url } } } -`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:M(e)}),null}}async function bo(e,t,n,r){if(t.type===`discussion`)return yo(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await ho(e,t,n.botLogin,r);if(i!=null){let a=go(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return vo(e,t,a.id,n.body,r)}}return _o(e,t,n.body,r)}function xo(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function So(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function Co(e){let t=ci,n=xo(t.eventName),r=So(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function wo(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function To(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function Eo(e){let t=e.trim(),n=t.indexOf(`/`);if(n===-1)throw Error(`Invalid model format: "${e}". Expected "provider/model" (e.g., "anthropic/claude-sonnet-4-20250514")`);let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();if(r.length===0)throw Error(`Invalid model format: "${e}". Provider cannot be empty.`);if(i.length===0)throw Error(`Invalid model format: "${e}". Model ID cannot be empty.`);return{providerID:r,modelID:i}}function Do(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Oo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`];function ko(e){let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),n=`no`,r=`no`,i=`no`,a=`no`,o=`no`,s=`no`;for(let e of t){if(!Oo.includes(e))throw Error(`Invalid omo-providers value: "${e}". Valid values: ${Oo.join(`, `)}`);switch(e){case`claude`:n=`yes`;break;case`claude-max20`:n=`max20`;break;case`copilot`:r=`yes`;break;case`gemini`:i=`yes`;break;case`openai`:a=`yes`;break;case`opencode-zen`:o=`yes`;break;case`zai-coding-plan`:s=`yes`;break}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s}}function Ao(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return ma(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return ma(Error(`auth-json is required but was not provided`));wo(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?To(i,`session-retention`):O,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:R,p=m(`model`).trim(),h=p.length>0?Eo(p):null,g=m(`timeout`).trim(),_=g.length>0?Do(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:k,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:P,C=m(`omo-providers`).trim(),w=ko(C.length>0?C:oe),T=m(`opencode-config`).trim(),ee=T.length>0?T:null;return ee!=null&&wo(ee,`opencode-config`),pa({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:w,opencodeConfig:ee})}catch(e){return ma(e instanceof Error?e:Error(String(e)))}}function jo(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Mo(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function No(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(F.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,jo(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Mo(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(F.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&F.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&F.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(F.addHeading(`Token Usage`,3),F.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&F.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&F.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(F.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&F.addList([...c.prsCreated]),c.commitsCreated.length>0&&F.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&F.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){F.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;F.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await F.write(),t.debug(`Wrote job summary`)}catch(e){let r=M(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Po(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function Fo(e){z(`session-id`,e.sessionId??``),z(`cache-status`,e.cacheStatus),z(`duration`,e.duration)}function Io(e){let t=B.resolve(e);return t.endsWith(B.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function Lo(e){return typeof e==`boolean`?e:null}function Ro(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function zo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Ro(e.diffs)}}function Bo(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function Vo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Ho(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:Vo(e.time),summary:zo(e.summary),share:Bo(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Uo(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Ro(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Wo(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:Lo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function Go(e){return Z(e)?Q(e.role)===`assistant`?Wo(e):Uo(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Ko(e){let t=Go(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(Yo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function qo(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Jo(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function Yo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=qo(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:Lo(e.synthetic)??void 0,ignored:Lo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Jo(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Xo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Ho):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function Zo(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Ko)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function Qo(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Ho);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function $o(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function es(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function ts(e,t,n){let r=Io(t),i=await es(e,n);for(let e of i){if(Io(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Io(t)===r)return e}return null}async function ns(e,t,n){return Xo(e,t,n)}async function rs(e,t,n){return Zo(e,t,n)}async function is(e,t,n){return $o(e,t,n)}async function as(e,t,n,r){return Qo(e,t,n,r)}const os={maxSessions:50,maxAgeDays:30};async function ss(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await ts(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await ns(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await is(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:M(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function cs(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await ns(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await rs(e,t.id,r),i=ls(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ls(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function us(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ds(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await cs(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ds(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ds(e,t,n,r,i){let a=await rs(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=fs(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function fs(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ps(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` +`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:M(e)}),null}}async function bo(e,t,n,r){if(t.type===`discussion`)return yo(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await ho(e,t,n.botLogin,r);if(i!=null){let a=go(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return vo(e,t,a.id,n.body,r)}}return _o(e,t,n.body,r)}function xo(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function So(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function Co(e){let t=ci,n=xo(t.eventName),r=So(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function wo(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function To(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function Eo(e){let t=e.trim(),n=t.indexOf(`/`);if(n===-1)throw Error(`Invalid model format: "${e}". Expected "provider/model" (e.g., "anthropic/claude-sonnet-4-20250514")`);let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();if(r.length===0)throw Error(`Invalid model format: "${e}". Provider cannot be empty.`);if(i.length===0)throw Error(`Invalid model format: "${e}". Model ID cannot be empty.`);return{providerID:r,modelID:i}}function Do(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Oo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function ko(e){let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),n=`no`,r=`no`,i=`no`,a=`no`,o=`no`,s=`no`,c=`no`;for(let e of t){if(!Oo.includes(e))throw Error(`Invalid omo-providers value: "${e}". Valid values: ${Oo.join(`, `)}`);switch(e){case`claude`:n=`yes`;break;case`claude-max20`:n=`max20`;break;case`copilot`:r=`yes`;break;case`gemini`:i=`yes`;break;case`openai`:a=`yes`;break;case`opencode-zen`:o=`yes`;break;case`zai-coding-plan`:s=`yes`;break;case`kimi-for-coding`:c=`yes`;break}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s,kimiForCoding:c}}function Ao(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return ma(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return ma(Error(`auth-json is required but was not provided`));wo(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?To(i,`session-retention`):O,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:R,p=m(`model`).trim(),h=p.length>0?Eo(p):null,g=m(`timeout`).trim(),_=g.length>0?Do(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:k,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:P,C=m(`omo-providers`).trim(),w=ko(C.length>0?C:oe),T=m(`opencode-config`).trim(),ee=T.length>0?T:null;return ee!=null&&wo(ee,`opencode-config`),pa({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:w,opencodeConfig:ee})}catch(e){return ma(e instanceof Error?e:Error(String(e)))}}function jo(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Mo(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function No(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(F.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,jo(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Mo(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(F.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&F.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&F.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(F.addHeading(`Token Usage`,3),F.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&F.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&F.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(F.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&F.addList([...c.prsCreated]),c.commitsCreated.length>0&&F.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&F.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){F.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;F.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await F.write(),t.debug(`Wrote job summary`)}catch(e){let r=M(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Po(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function Fo(e){z(`session-id`,e.sessionId??``),z(`cache-status`,e.cacheStatus),z(`duration`,e.duration)}function Io(e){let t=B.resolve(e);return t.endsWith(B.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function Lo(e){return typeof e==`boolean`?e:null}function Ro(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function zo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Ro(e.diffs)}}function Bo(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function Vo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Ho(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:Vo(e.time),summary:zo(e.summary),share:Bo(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Uo(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Ro(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Wo(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:Lo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function Go(e){return Z(e)?Q(e.role)===`assistant`?Wo(e):Uo(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Ko(e){let t=Go(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(Yo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function qo(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Jo(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function Yo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=qo(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:Lo(e.synthetic)??void 0,ignored:Lo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Jo(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Xo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Ho):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function Zo(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Ko)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function Qo(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Ho);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function $o(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function es(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function ts(e,t,n){let r=Io(t),i=await es(e,n);for(let e of i){if(Io(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Io(t)===r)return e}return null}async function ns(e,t,n){return Xo(e,t,n)}async function rs(e,t,n){return Zo(e,t,n)}async function is(e,t,n){return $o(e,t,n)}async function as(e,t,n,r){return Qo(e,t,n,r)}const os={maxSessions:50,maxAgeDays:30};async function ss(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await ts(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await ns(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await is(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:M(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function cs(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await ns(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await rs(e,t.id,r),i=ls(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ls(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function us(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ds(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await cs(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ds(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ds(e,t,n,r,i){let a=await rs(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=fs(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function fs(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ps(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` `)}async function ms(e,t,n,r){let i=ps(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:i}]}});if(t.error!=null){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}r.info(`Session summary written via SDK`,{sessionId:e})}catch(t){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:M(t)})}}const hs=/^[0-9a-f]{40}$/i;function gs(){return{exec:x,getExecOutput:c}}async function _s(e){let{workspacePath:t,logger:n,execAdapter:r=gs()}=e,i=B.join(t,`.git`),a=B.join(i,`opencode`);try{let e=(await G.readFile(a,`utf8`)).trim();if(e.length>0){if(hs.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:M(e)})}try{if((await G.stat(i)).isDirectory()===!1){let e=await G.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=B.resolve(t,n[1]),a=B.join(i,`opencode`)}}catch{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 G.writeFile(a,s,`utf8`),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){n.warning(`Failed to cache project ID (continuing)`,{error:M(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:M(e)}}}const vs={botLogin:null,requireMention:!0,allowedAssociations:ha,skipDraftPRs:!0,promptInput:null};function ys(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${bs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function bs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function xs(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${bs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function Ss(e,t){return t.includes(e)}function Cs(e){return e.endsWith(`[bot]`)}function ws(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=ys(e,t);return{hasMention:n,command:n?xs(e,t):null}}function Ts(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Cs(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},i=e.comment.body,a=e.comment.id,{hasMention:o,command:s}=ws(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Es(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Cs(e.comment.author)},r={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:e.comment.body??e.discussion.body??null,locked:e.discussion.locked},i=e.comment.body??null,a=e.comment.id,{hasMention:o,command:s}=ws(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Ds(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Os(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:Cs(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=ws(e.issue.body??``,t);return{author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,action:e.action}}const ks=[`opened`,`edited`];function As(e){return ks.includes(e)}function js(e,t,n){let r=e.action;return r==null||!As(r)?(n.debug(`Skipping unsupported issues action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${r}' is not supported (only 'opened' and 'edited')`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):r===`edited`&&!e.hasMention?(n.debug(`Skipping issues.edited without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}):e.target?.locked===!0?(n.debug(`Skipping locked issue`),{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}):{shouldSkip:!1}}function Ms(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:Cs(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft},{hasMention:i,command:a}=ws(e.pullRequest.body??``,t);return{author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,action:e.action}}const Ns=[`opened`,`synchronize`,`reopened`];function Ps(e){return Ns.includes(e)}function Fs(e,t,n){let r=e.action;return r==null||!Ps(r)?(n.debug(`Skipping unsupported pull_request action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${r}' is not supported`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.skipDraftPRs&&e.target?.isDraft===!0?(n.debug(`Skipping draft PR`),{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}):e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):{shouldSkip:!1}}function Is(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Cs(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=ws(e.comment.body,t);return{author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,action:e.action}}function Ls(e,t,n){let r=n?.trim()??``;return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Rs(e,t){return(e.promptInput?.trim()??``)===``?(t.debug(`Skipping schedule event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}):{shouldSkip:!1}}function zs(e,t){return(e.commentBody?.trim()??``)===``?(t.debug(`Skipping workflow_dispatch event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}):{shouldSkip:!1}}function Bs(e,t,n,r){let{targetLabel:i,actionLabel:a}=r;return e.action===`created`?e.target?.locked===!0?(n.debug(`Skipping locked ${i}`),{shouldSkip:!0,reason:`issue_locked`,message:`${i} is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping ${a} without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created ${a} action`,{action:e.action}),{shouldSkip:!0,reason:`action_not_created`,message:`${a} action is '${e.action}', not 'created'`})}function Vs(e,t,n){return Bs(e,t,n,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function Hs(e,t,n){return Bs(e,t,n,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}function Us(e,t,n){let r=e.action;return r===`created`?e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping review comment without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created review comment action`,{action:r}),{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${r}' is not supported (only 'created')`})}function Ws(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e.eventName}`};switch(e.eventType){case`issue_comment`:return Vs(e,t,n);case`discussion_comment`:return Hs(e,t,n);case`issues`:return js(e,t,n);case`pull_request`:return Fs(e,t,n);case`pull_request_review_comment`:return Us(e,t,n);case`schedule`:return Rs(t,n);case`workflow_dispatch`:return zs(e,n);default:return{shouldSkip:!1}}}function Gs(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:{let n=Ts(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`discussion_comment`:{let n=Es(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`workflow_dispatch`:{let t=Ds(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`issues`:{let n=Os(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request`:{let n=Ms(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request_review_comment`:{let n=Is(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`schedule`:{let t=Ls(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null}}}function Ks(e,t,n={}){let r={...vs,...n},i=Gs(e,r.botLogin,r.promptInput);t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Ws(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function qs(){let e=Date.now(),t=A({phase:`bootstrap`}),n=null,i=!1,o=0,s=null,c=null,l=null,u=null,d=Po();d.start(),f(L.SHOULD_SAVE_CACHE,`false`),f(L.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let p=Ao();if(!p.success)return _(`Invalid inputs: ${p.error.message}`),1;let m=p.data,h=A({phase:`main`});h.info(`Action inputs parsed`,{sessionRetention:m.sessionRetention,s3Backup:m.s3Backup,hasGithubToken:m.githubToken.length>0,hasPrompt:m.prompt!=null,agent:m.agent,hasModelOverride:m.model!=null,timeoutMs:m.timeoutMs});let g=await Ia({logger:h,opencodeVersion:m.opencodeVersion});g.didSetup?h.info(`OpenCode auto-setup completed`,{version:g.version}):h.info(`OpenCode already available`,{version:g.version}),f(L.OPENCODE_VERSION,g.version),l=g.version;let b=A({phase:`context`}),x=Co(b);s=Bi({token:m.githubToken,logger:b});let S=await Vi(s,b),C=A({phase:`trigger`}),w=Ks(x,C,{botLogin:S,requireMention:!0,promptInput:m.prompt});if(!w.shouldProcess)return C.info(`Skipping event`,{reason:w.skipReason,message:w.skipMessage}),Fo({sessionId:null,cacheStatus:`miss`,duration:Date.now()-e}),0;C.info(`Event routed for processing`,{eventType:w.context.eventType,hasMention:w.context.hasMention,command:w.context.command?.action??null}),f(L.SHOULD_SAVE_CACHE,`true`);let T=await et({logger:b,octokit:s,triggerContext:w.context,botLogin:S});n={repo:T.repo,commentId:T.commentId,issueNumber:T.issueNumber,issueType:T.issueType,botLogin:S};let E=A({phase:`acknowledgment`});await Ba(s,n,E);let ee={agentIdentity:`github`,repo:te(),ref:de(),os:a()},D=A({phase:`cache`}),ne=v(),re=B.join(ne,`.git`,`opencode`),O=await ie({components:ee,logger:D,storagePath:y(),authPath:r(),projectIdPath:re,opencodeVersion:g.version}),k=O.corrupted?`corrupted`:O.hit?`hit`:`miss`;d.setCacheStatus(k),h.info(`Cache restore completed`,{cacheStatus:k,key:O.key});let j=await _s({workspacePath:ne,logger:D});j.source===`error`?D.warning(`Failed to generate project ID (continuing)`,{error:j.error}):D.debug(`Project ID ready`,{projectId:j.projectId,source:j.source});let M=A({phase:`server-bootstrap`}),N=await Na(new AbortController().signal,M);if(!N.success)return _(`OpenCode server bootstrap failed: ${N.error.message}`),1;u=N.data,M.info(`SDK server bootstrapped successfully`);let P=A({phase:`session`}),ae=Io(ne),oe=await cs(u.client,ae,{limit:10},P);P.debug(`Listed recent sessions`,{count:oe.length});let F=T.issueTitle??T.repo,I=await us(F,u.client,ae,{limit:5},P);P.debug(`Searched prior sessions`,{query:F,resultCount:I.length});for(let e of I)d.addSessionUsed(e.sessionId);let se=A({phase:`attachments`}),R=T.commentBody??``,ce=Ya(R);if(ce.length>0){se.info(`Processing attachments`,{count:ce.length});let{validated:e,skipped:t}=oo(await eo(ce,m.githubToken,void 0,se),void 0,se);(e.length>0||t.length>0)&&(c=io(R,ce,e,t),se.info(`Attachments processed`,{processed:e.length,skipped:t.length}))}let le={context:T,customPrompt:m.prompt,cacheStatus:k,sessionContext:{recentSessions:oe,priorWorkContext:I},triggerContext:w.context,fileParts:c?.fileParts},ue=H.env.SKIP_AGENT_EXECUTION===`true`,z,fe=Date.now();if(ue)h.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),z={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let e=await Pa(le,A({phase:`execution`}),{agent:m.agent,model:m.model,timeoutMs:m.timeoutMs,omoProviders:m.omoProviders},u??void 0),t=e.sessionId;if(t==null){let e=await as(u.client,ae,fe,P);e!=null&&(t=e.session.id,P.debug(`Identified session from execution`,{sessionId:t}))}z={...e,sessionId:t}}z.sessionId!=null&&f(L.SESSION_ID,z.sessionId),i=z.success,z.sessionId!=null&&d.addSessionCreated(z.sessionId),z.tokenUsage!=null&&d.setTokenUsage(z.tokenUsage,z.model,z.cost);for(let e of z.prsCreated)d.addPRCreated(e);for(let e of z.commitsCreated)d.addCommitCreated(e);for(let e=0;e0&&n.owner.length>0&&n.repo.length>0){let e=ln(z.llmError),t=A({phase:`error-comment`}),r=await bo(s,n,{body:e},t);r==null?t.warning(`Failed to post LLM error comment`):(t.info(`Posted LLM error comment`,{commentUrl:r.url}),d.incrementComments())}else h.warning(`Cannot post error comment: missing target context`);o=0}}catch(n){o=1;let r=Date.now()-e,i=n instanceof Error?n.name:`UnknownError`,a=n instanceof Error?n.message:String(n);d.recordError(i,a,!1),d.end(),Fo({sessionId:null,cacheStatus:`miss`,duration:r}),n instanceof Error?(t.error(`Agent failed`,{error:n.message}),_(n.message)):(t.error(`Agent failed with unknown error`),_(`An unknown error occurred`))}finally{try{if(c!=null){let e=A({phase:`attachment-cleanup`});await to(c.tempFiles,e)}if(n!=null&&s!=null){let e=A({phase:`cleanup`});await Ka(s,n,i,e)}let e=A({phase:`prune`}),t=v();if(u!=null){let n=Io(t),r=await ss(u.client,n,os,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let o={agentIdentity:`github`,repo:te(),ref:de(),os:a()},d=A({phase:`cache-save`}),p=B.join(t,`.git`,`opencode`);await I({components:o,runId:ue(),logger:d,storagePath:y(),authPath:r(),projectIdPath:p,opencodeVersion:l})&&f(L.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(u!=null)try{u.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}return o}await qs().then(e=>{H.exit(e)});export{}; \ No newline at end of file diff --git a/src/lib/agent/opencode.test.ts b/src/lib/agent/opencode.test.ts index 49b679b4..7f6fb149 100644 --- a/src/lib/agent/opencode.test.ts +++ b/src/lib/agent/opencode.test.ts @@ -235,7 +235,15 @@ describe('executeOpenCode', () => { agent: 'sisyphus', model: {providerID: 'anthropic', modelID: 'claude-sonnet-4-20250514'}, timeoutMs: 1800000, - omoProviders: {claude: 'no', copilot: 'no', gemini: 'no', openai: 'no', opencodeZen: 'no', zaiCodingPlan: 'no'}, + omoProviders: { + claude: 'no', + copilot: 'no', + gemini: 'no', + openai: 'no', + opencodeZen: 'no', + zaiCodingPlan: 'no', + kimiForCoding: 'no', + }, } // #when @@ -267,7 +275,15 @@ describe('executeOpenCode', () => { agent: 'sisyphus', model: null, timeoutMs: 1800000, - omoProviders: {claude: 'no', copilot: 'no', gemini: 'no', openai: 'no', opencodeZen: 'no', zaiCodingPlan: 'no'}, + omoProviders: { + claude: 'no', + copilot: 'no', + gemini: 'no', + openai: 'no', + opencodeZen: 'no', + zaiCodingPlan: 'no', + kimiForCoding: 'no', + }, } // #when @@ -295,7 +311,15 @@ describe('executeOpenCode', () => { agent: 'sisyphus', model: null, timeoutMs: 1800000, - omoProviders: {claude: 'yes', copilot: 'no', gemini: 'no', openai: 'no', opencodeZen: 'no', zaiCodingPlan: 'no'}, + omoProviders: { + claude: 'yes', + copilot: 'no', + gemini: 'no', + openai: 'no', + opencodeZen: 'no', + zaiCodingPlan: 'no', + kimiForCoding: 'no', + }, } // #when @@ -320,7 +344,15 @@ describe('executeOpenCode', () => { agent: 'sisyphus', model: {providerID: 'openai', modelID: 'gpt-5'}, timeoutMs: 1800000, - omoProviders: {claude: 'yes', copilot: 'no', gemini: 'no', openai: 'yes', opencodeZen: 'no', zaiCodingPlan: 'no'}, + omoProviders: { + claude: 'yes', + copilot: 'no', + gemini: 'no', + openai: 'yes', + opencodeZen: 'no', + zaiCodingPlan: 'no', + kimiForCoding: 'no', + }, } // #when @@ -345,7 +377,15 @@ describe('executeOpenCode', () => { agent: 'CustomAgent', model: null, timeoutMs: 1800000, - omoProviders: {claude: 'no', copilot: 'no', gemini: 'no', openai: 'no', opencodeZen: 'no', zaiCodingPlan: 'no'}, + omoProviders: { + claude: 'no', + copilot: 'no', + gemini: 'no', + openai: 'no', + opencodeZen: 'no', + zaiCodingPlan: 'no', + kimiForCoding: 'no', + }, } // #when @@ -371,7 +411,15 @@ describe('executeOpenCode', () => { agent: 'oracle', model: null, timeoutMs: 1800000, - omoProviders: {claude: 'no', copilot: 'no', gemini: 'no', openai: 'no', opencodeZen: 'no', zaiCodingPlan: 'no'}, + omoProviders: { + claude: 'no', + copilot: 'no', + gemini: 'no', + openai: 'no', + opencodeZen: 'no', + zaiCodingPlan: 'no', + kimiForCoding: 'no', + }, } // #when diff --git a/src/lib/inputs.ts b/src/lib/inputs.ts index 3bad9988..bfe530fb 100644 --- a/src/lib/inputs.ts +++ b/src/lib/inputs.ts @@ -65,6 +65,7 @@ const VALID_OMO_PROVIDERS = [ 'openai', 'opencode-zen', 'zai-coding-plan', + 'kimi-for-coding', ] as const type OmoProviderInput = (typeof VALID_OMO_PROVIDERS)[number] @@ -81,6 +82,7 @@ function parseOmoProviders(input: string): OmoProviders { let openai: 'no' | 'yes' = 'no' let opencodeZen: 'no' | 'yes' = 'no' let zaiCodingPlan: 'no' | 'yes' = 'no' + let kimiForCoding: 'no' | 'yes' = 'no' for (const provider of providers) { if (!VALID_OMO_PROVIDERS.includes(provider as OmoProviderInput)) { @@ -109,10 +111,13 @@ function parseOmoProviders(input: string): OmoProviders { case 'zai-coding-plan': zaiCodingPlan = 'yes' break + case 'kimi-for-coding': + kimiForCoding = 'yes' + break } } - return {claude, copilot, gemini, openai, opencodeZen, zaiCodingPlan} + return {claude, copilot, gemini, openai, opencodeZen, zaiCodingPlan, kimiForCoding} } /** diff --git a/src/lib/types.ts b/src/lib/types.ts index a10baa48..b9cdf382 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -72,6 +72,7 @@ export interface OmoProviders { readonly openai: 'no' | 'yes' readonly opencodeZen: 'no' | 'yes' readonly zaiCodingPlan: 'no' | 'yes' + readonly kimiForCoding: 'no' | 'yes' } // Action outputs From 619abdfa8536ac47549e825f6376bd2f0f3e41d7 Mon Sep 17 00:00:00 2001 From: "Marcus R. Brown" Date: Sun, 1 Mar 2026 20:26:35 -0700 Subject: [PATCH 8/8] fix(setup): harden opencode/omo config input parsing - trim setup inputs and treat whitespace-only config values as not provided - fail fast with explicit error when opencode-config is invalid JSON - enforce opencode-config and omo-config as JSON objects (not null/array/primitive) - harden oMo deep merge against prototype-pollution keys - add regression tests for null/array/string/invalid JSON and whitespace handling - document opencode-config input in README - rebuild dist/main.js --- README.md | 1 + dist/main.js | 44 ++++++++--------- src/lib/inputs.test.ts | 57 ++++++++++++++++++++++ src/lib/inputs.ts | 9 ++++ src/lib/setup/omo-config.test.ts | 37 +++++++++++++- src/lib/setup/omo-config.ts | 40 +++++++++++----- src/lib/setup/setup.test.ts | 82 +++++++++++++++++++++++++++++++- src/lib/setup/setup.ts | 22 +++++++-- 8 files changed, 250 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 1041130e..c3d6f62a 100644 --- a/README.md +++ b/README.md @@ -374,6 +374,7 @@ concurrency: | `aws-region` | No | — | AWS region for S3 bucket | | `skip-cache` | No | `false` | Skip cache restore (useful for debugging) | | `omo-config` | No | — | Custom oMo configuration JSON (deep-merged) | +| `opencode-config` | No | — | Custom OpenCode configuration JSON (deep-merged) | ### Action Outputs diff --git a/dist/main.js b/dist/main.js index 65cd0bac..c318689b 100644 --- a/dist/main.js +++ b/dist/main.js @@ -1,7 +1,7 @@ -import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,Q as g,R as _,S as v,T as y,U as b,V as x,W as S,X as C,Y as w,Z as T,_ as E,a as ee,b as te,c as D,d as ne,f as re,g as O,h as k,i as A,j,k as M,l as N,m as P,n as ie,o as ae,p as oe,q as F,r as I,s as se,t as L,u as R,v as ce,w as le,x as ue,y as de,z}from"./state-keys-CDII8qo6.js";import*as B from"node:path";import fe,{join as V}from"node:path";import H from"node:process";import*as pe from"os";import{EOL as me}from"os";import*as he from"crypto";import*as U from"fs";import{existsSync as ge,readFileSync as _e}from"fs";import*as W from"path";import{ok as ve}from"assert";import*as ye from"util";import{Buffer as be}from"node:buffer";import*as xe from"node:crypto";import{pathToFileURL as Se}from"node:url";import*as G from"node:fs/promises";import Ce from"node:fs/promises";import{spawn as we}from"node:child_process";import*as Te from"node:os";import Ee,{homedir as De}from"node:os";import*as Oe from"stream";const ke={maxComments:50,maxCommits:100,maxFiles:100,maxReviews:100,maxBodyBytes:10*1024,maxTotalBytes:100*1024},Ae=`…[truncated]`;function je(e,t){if(e.length===0)return{text:``,truncated:!1};let n=new TextEncoder,r=n.encode(e);if(r.length<=t)return{text:e,truncated:!1};let i=t-n.encode(Ae).length;if(i<=0)return{text:Ae,truncated:!0};let a=r.slice(0,i),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);for(;o.length>0&&o.charCodeAt(o.length-1)===65533;)a=a.slice(0,-1),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);return{text:o+Ae,truncated:!0}}function Me(e){return e.length===0?``:`**Labels:** ${e.map(e=>`\`${e.name}\``).join(`, `)}\n`}function Ne(e){return e.length===0?``:`**Assignees:** ${e.map(e=>`@${e.login}`).join(`, `)}\n`}function Pe(e){let t=[];t.push(`## Issue #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`);let n=Me(e.labels);n.length>0&&t.push(n.trimEnd());let r=Ne(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Body`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Body was truncated due to size limits.*`)),e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),e.commentsTruncated&&(t.push(``),t.push(`*Note: Comments were truncated due to limits.*`)),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` +import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as u,K as d,L as f,M as p,N as m,O as h,Q as g,R as _,S as v,T as y,U as b,V as x,W as S,X as C,Y as w,Z as T,_ as E,a as D,b as ee,c as O,d as te,f as ne,g as k,h as A,i as j,j as M,k as N,l as re,m as P,n as ie,o as ae,p as oe,q as F,r as I,s as se,t as L,u as R,v as ce,w as le,x as ue,y as de,z}from"./state-keys-CDII8qo6.js";import*as B from"node:path";import fe,{join as V}from"node:path";import H from"node:process";import*as pe from"os";import{EOL as me}from"os";import*as he from"crypto";import*as U from"fs";import{existsSync as ge,readFileSync as _e}from"fs";import*as W from"path";import{ok as ve}from"assert";import*as ye from"util";import{Buffer as be}from"node:buffer";import*as xe from"node:crypto";import{pathToFileURL as Se}from"node:url";import*as G from"node:fs/promises";import Ce from"node:fs/promises";import{spawn as we}from"node:child_process";import*as Te from"node:os";import Ee,{homedir as De}from"node:os";import*as Oe from"stream";const ke={maxComments:50,maxCommits:100,maxFiles:100,maxReviews:100,maxBodyBytes:10*1024,maxTotalBytes:100*1024},Ae=`…[truncated]`;function je(e,t){if(e.length===0)return{text:``,truncated:!1};let n=new TextEncoder,r=n.encode(e);if(r.length<=t)return{text:e,truncated:!1};let i=t-n.encode(Ae).length;if(i<=0)return{text:Ae,truncated:!0};let a=r.slice(0,i),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);for(;o.length>0&&o.charCodeAt(o.length-1)===65533;)a=a.slice(0,-1),o=new TextDecoder(`utf-8`,{fatal:!1}).decode(a);return{text:o+Ae,truncated:!0}}function Me(e){return e.length===0?``:`**Labels:** ${e.map(e=>`\`${e.name}\``).join(`, `)}\n`}function Ne(e){return e.length===0?``:`**Assignees:** ${e.map(e=>`@${e.login}`).join(`, `)}\n`}function Pe(e){let t=[];t.push(`## Issue #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`);let n=Me(e.labels);n.length>0&&t.push(n.trimEnd());let r=Ne(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Body`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Body was truncated due to size limits.*`)),e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),e.commentsTruncated&&(t.push(``),t.push(`*Note: Comments were truncated due to limits.*`)),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` `)}function Fe(e){let t=[];t.push(`## Pull Request #${e.number}`),t.push(``),t.push(`**Title:** ${e.title}`),t.push(`**State:** ${e.state}`),t.push(`**Author:** ${e.author??`unknown`}`),t.push(`**Created:** ${e.createdAt}`),t.push(`**Base:** ${e.baseBranch} ← **Head:** ${e.headBranch}`),e.isFork&&t.push(`**Fork:** Yes (external contributor)`);let n=Me(e.labels);n.length>0&&t.push(n.trimEnd());let r=Ne(e.assignees);if(r.length>0&&t.push(r.trimEnd()),t.push(``),t.push(`### Description`),t.push(``),t.push(e.body),e.bodyTruncated&&(t.push(``),t.push(`*Note: Description was truncated due to size limits.*`)),e.files.length>0){t.push(``),t.push(`### Files Changed (${e.files.length}${e.filesTruncated?` of ${e.totalFiles}`:``})`),t.push(``),t.push(`| File | +/- |`),t.push(`|------|-----|`);for(let n of e.files)t.push(`| \`${n.path}\` | +${n.additions}/-${n.deletions} |`)}if(e.commits.length>0){t.push(``),t.push(`### Commits (${e.commits.length}${e.commitsTruncated?` of ${e.totalCommits}`:``})`),t.push(``);for(let n of e.commits){let e=n.oid.slice(0,7);t.push(`- \`${e}\` ${n.message.split(` `)[0]}`)}}if(e.reviews.length>0){t.push(``),t.push(`### Reviews (${e.reviews.length}${e.reviewsTruncated?` of ${e.totalReviews}`:``})`),t.push(``);for(let n of e.reviews)t.push(`**${n.author??`unknown`}** - ${n.state}`),n.body.length>0&&t.push(n.body),t.push(``)}if(e.comments.length>0){t.push(``),t.push(`### Comments (${e.comments.length}${e.commentsTruncated?` of ${e.totalComments}`:``})`),t.push(``);for(let n of e.comments)t.push(`**${n.author??`unknown`}** (${n.createdAt}):`),t.push(n.body),t.push(``)}return t.join(` -`)}function Ie(e){return e.type===`issue`?Pe(e):Fe(e)}async function Le(e,t,n,r,i,a){try{let[a,o]=await Promise.all([e.rest.issues.get({owner:t,repo:n,issue_number:r}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),s=a.data,c=je(s.body??``,i.maxBodyBytes),l=o.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),u=(s.labels??[]).filter(e=>typeof e==`object`&&!!e&&`name`in e).map(e=>({name:e.name??``,color:e.color})),d=(s.assignees??[]).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.user?.login??null,createdAt:s.created_at,labels:u,assignees:d,comments:l,commentsTruncated:o.data.length>=i.maxComments,totalComments:o.data.length}}catch(e){return a.warning(`REST issue fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function Re(e,t,n,r,i,a){try{let[o,s,c,l,u]=await Promise.all([e.rest.pulls.get({owner:t,repo:n,pull_number:r}),e.rest.pulls.listCommits({owner:t,repo:n,pull_number:r,per_page:i.maxCommits}),e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:i.maxFiles}),e.rest.pulls.listReviews({owner:t,repo:n,pull_number:r,per_page:i.maxReviews}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),d=await e.rest.pulls.listRequestedReviewers({owner:t,repo:n,pull_number:r}).catch(e=>(a.warning(`Failed to fetch requested reviewers, defaulting to empty`,{owner:t,repo:n,number:r,error:M(e)}),{data:{users:[],teams:[]}})),f=o.data,p=je(f.body??``,i.maxBodyBytes),m=f.base.repo?.owner.login,h=f.head.repo?.owner.login,g=h==null||m!==h,_=u.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),v=s.data.slice(0,i.maxCommits).map(e=>({oid:e.sha,message:e.commit.message,author:e.commit.author?.name??null})),y=c.data.slice(0,i.maxFiles).map(e=>({path:e.filename,additions:e.additions,deletions:e.deletions,status:e.status})),b=l.data.slice(0,i.maxReviews).map(e=>({author:e.user?.login??null,state:e.state,body:e.body??``,createdAt:e.submitted_at??``,comments:[]})),x=(f.labels??[]).map(e=>({name:e.name??``,color:e.color})),S=(f.assignees??[]).map(e=>({login:e?.login??``})),C=(d.data.users??[]).map(e=>e.login),w=(d.data.teams??[]).map(e=>e.name);return{type:`pull_request`,number:f.number,title:f.title,body:p.text,bodyTruncated:p.truncated,state:f.state,author:f.user?.login??null,createdAt:f.created_at,baseBranch:f.base.ref,headBranch:f.head.ref,isFork:g,labels:x,assignees:S,comments:_,commentsTruncated:u.data.length>=i.maxComments,totalComments:u.data.length,commits:v,commitsTruncated:s.data.length>=i.maxCommits,totalCommits:s.data.length,files:y,filesTruncated:c.data.length>=i.maxFiles,totalFiles:c.data.length,reviews:b,reviewsTruncated:l.data.length>=i.maxReviews,totalReviews:l.data.length,authorAssociation:f.author_association,requestedReviewers:C,requestedReviewerTeams:w}}catch(e){return a.warning(`REST pull request fallback failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function ze(e,t,n,r,i,a){try{return await e.graphql(` +`)}function Ie(e){return e.type===`issue`?Pe(e):Fe(e)}async function Le(e,t,n,r,i,a){try{let[a,o]=await Promise.all([e.rest.issues.get({owner:t,repo:n,issue_number:r}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),s=a.data,c=je(s.body??``,i.maxBodyBytes),l=o.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),u=(s.labels??[]).filter(e=>typeof e==`object`&&!!e&&`name`in e).map(e=>({name:e.name??``,color:e.color})),d=(s.assignees??[]).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.user?.login??null,createdAt:s.created_at,labels:u,assignees:d,comments:l,commentsTruncated:o.data.length>=i.maxComments,totalComments:o.data.length}}catch(e){return a.warning(`REST issue fallback failed`,{owner:t,repo:n,number:r,error:N(e)}),null}}async function Re(e,t,n,r,i,a){try{let[o,s,c,l,u]=await Promise.all([e.rest.pulls.get({owner:t,repo:n,pull_number:r}),e.rest.pulls.listCommits({owner:t,repo:n,pull_number:r,per_page:i.maxCommits}),e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:i.maxFiles}),e.rest.pulls.listReviews({owner:t,repo:n,pull_number:r,per_page:i.maxReviews}),e.rest.issues.listComments({owner:t,repo:n,issue_number:r,per_page:i.maxComments})]),d=await e.rest.pulls.listRequestedReviewers({owner:t,repo:n,pull_number:r}).catch(e=>(a.warning(`Failed to fetch requested reviewers, defaulting to empty`,{owner:t,repo:n,number:r,error:N(e)}),{data:{users:[],teams:[]}})),f=o.data,p=je(f.body??``,i.maxBodyBytes),m=f.base.repo?.owner.login,h=f.head.repo?.owner.login,g=h==null||m!==h,_=u.data.slice(0,i.maxComments).map(e=>({id:e.node_id??String(e.id),author:e.user?.login??null,body:e.body??``,createdAt:e.created_at,authorAssociation:e.author_association,isMinimized:!1})),v=s.data.slice(0,i.maxCommits).map(e=>({oid:e.sha,message:e.commit.message,author:e.commit.author?.name??null})),y=c.data.slice(0,i.maxFiles).map(e=>({path:e.filename,additions:e.additions,deletions:e.deletions,status:e.status})),b=l.data.slice(0,i.maxReviews).map(e=>({author:e.user?.login??null,state:e.state,body:e.body??``,createdAt:e.submitted_at??``,comments:[]})),x=(f.labels??[]).map(e=>({name:e.name??``,color:e.color})),S=(f.assignees??[]).map(e=>({login:e?.login??``})),C=(d.data.users??[]).map(e=>e.login),w=(d.data.teams??[]).map(e=>e.name);return{type:`pull_request`,number:f.number,title:f.title,body:p.text,bodyTruncated:p.truncated,state:f.state,author:f.user?.login??null,createdAt:f.created_at,baseBranch:f.base.ref,headBranch:f.head.ref,isFork:g,labels:x,assignees:S,comments:_,commentsTruncated:u.data.length>=i.maxComments,totalComments:u.data.length,commits:v,commitsTruncated:s.data.length>=i.maxCommits,totalCommits:s.data.length,files:y,filesTruncated:c.data.length>=i.maxFiles,totalFiles:c.data.length,reviews:b,reviewsTruncated:l.data.length>=i.maxReviews,totalReviews:l.data.length,authorAssociation:f.author_association,requestedReviewers:C,requestedReviewerTeams:w}}catch(e){return a.warning(`REST pull request fallback failed`,{owner:t,repo:n,number:r,error:N(e)}),null}}async function ze(e,t,n,r,i,a){try{return await e.graphql(` query GetIssue($owner: String!, $repo: String!, $number: Int!, $maxComments: Int!) { repository(owner: $owner, name: $repo) { issue(number: $number) { @@ -31,7 +31,7 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a } } } -`,{owner:t,repo:n,number:r,maxComments:i})}catch(e){return a.warning(`GraphQL issue query failed`,{owner:t,repo:n,number:r,error:M(e)}),null}}async function Be(e,t,n,r,i,a,o,s,c){try{return await e.graphql(` +`,{owner:t,repo:n,number:r,maxComments:i})}catch(e){return a.warning(`GraphQL issue query failed`,{owner:t,repo:n,number:r,error:N(e)}),null}}async function Be(e,t,n,r,i,a,o,s,c){try{return await e.graphql(` query GetPullRequest( $owner: String!, $repo: String!, @@ -119,7 +119,7 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a } } } -`,{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:M(e)}),null}}async function Ve(e,t,n,r,i,a){let o=await ze(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=je(s.body??``,i.maxBodyBytes),l=s.comments.nodes.slice(0,i.maxComments),u=s.comments.totalCount>l.length,d=l.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),f=s.labels.nodes.map(e=>({name:e.name,color:e.color})),p=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:f,assignees:p,comments:d,commentsTruncated:u,totalComments:s.comments.totalCount}}async function He(e,t,n,r,i,a){let o=await Be(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=je(s.body??``,i.maxBodyBytes),l=s.baseRepository?.owner.login,u=s.headRepository?.owner.login,d=u==null||l!==u,f=s.comments.nodes.slice(0,i.maxComments),p=s.comments.totalCount>f.length,m=f.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),h=s.commits.nodes.slice(0,i.maxCommits),g=s.commits.totalCount>h.length,_=h.map(e=>({oid:e.commit.oid,message:e.commit.message,author:e.commit.author?.name??null})),v=s.files.nodes.slice(0,i.maxFiles),y=s.files.totalCount>v.length,b=v.map(e=>({path:e.path,additions:e.additions,deletions:e.deletions})),x=s.reviews.nodes.slice(0,i.maxReviews),S=s.reviews.totalCount>x.length,C=x.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}))})),w=s.labels.nodes.map(e=>({name:e.name,color:e.color})),T=s.assignees.nodes.map(e=>({login:e.login})),E=s.reviewRequests.nodes.map(e=>`login`in e.requestedReviewer?e.requestedReviewer.login:null).filter(e=>e!=null),ee=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:w,assignees:T,comments:m,commentsTruncated:p,totalComments:s.comments.totalCount,commits:_,commitsTruncated:g,totalCommits:s.commits.totalCount,files:b,filesTruncated:y,totalFiles:s.files.totalCount,reviews:C,reviewsTruncated:S,totalReviews:s.reviews.totalCount,authorAssociation:s.authorAssociation,requestedReviewers:E,requestedReviewerTeams:ee}}function K(e){let[t,n]=e.split(`/`);if(t==null||n==null||t.length===0||n.length===0)throw Error(`Invalid repository string: ${e}`);return{owner:t,repo:n}}async function Ue(e,t,n,r,i){try{let{owner:a,repo:o}=K(t),{data:s}=await e.rest.reactions.createForIssueComment({owner:a,repo:o,comment_id:n,content:r});return i.debug(`Created comment reaction`,{commentId:n,content:r,reactionId:s.id}),{id:s.id}}catch(e){return i.warning(`Failed to create comment reaction`,{commentId:n,content:r,error:M(e)}),null}}async function We(e,t,n,r){try{let{owner:r,repo:i}=K(t),{data:a}=await e.rest.reactions.listForIssueComment({owner:r,repo:i,comment_id:n,per_page:100});return a.map(e=>({id:e.id,content:e.content,userLogin:e.user?.login??null}))}catch(e){return r.warning(`Failed to list comment reactions`,{commentId:n,error:M(e)}),[]}}async function Ge(e,t,n,r,i){try{let{owner:a,repo:o}=K(t);return await e.rest.reactions.deleteForIssueComment({owner:a,repo:o,comment_id:n,reaction_id:r}),i.debug(`Deleted comment reaction`,{commentId:n,reactionId:r}),!0}catch(e){return i.warning(`Failed to delete comment reaction`,{commentId:n,reactionId:r,error:M(e)}),!1}}async function Ke(e,t,n,r,i,a){let{owner:o,repo:s}=K(t);try{return await e.rest.issues.createLabel({owner:o,repo:s,name:n,color:r,description:i}),a.debug(`Created label`,{name:n,color:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===422?(a.debug(`Label already exists`,{name:n}),!0):(a.warning(`Failed to create label`,{name:n,error:M(e)}),!1)}}async function qe(e,t,n,r,i){try{let{owner:a,repo:o}=K(t);return await e.rest.issues.addLabels({owner:a,repo:o,issue_number:n,labels:[...r]}),i.debug(`Added labels to issue`,{issueNumber:n,labels:r}),!0}catch(e){return i.warning(`Failed to add labels to issue`,{issueNumber:n,labels:r,error:M(e)}),!1}}async function Je(e,t,n,r,i){try{let{owner:a,repo:o}=K(t);return await e.rest.issues.removeLabel({owner:a,repo:o,issue_number:n,name:r}),i.debug(`Removed label from issue`,{issueNumber:n,label:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===404?(i.debug(`Label was not present on issue`,{issueNumber:n,label:r}),!0):(i.warning(`Failed to remove label from issue`,{issueNumber:n,label:r,error:M(e)}),!1)}}async function Ye(e,t,n){try{let{owner:n,repo:r}=K(t),{data:i}=await e.rest.repos.get({owner:n,repo:r});return i.default_branch}catch(e){return n.warning(`Failed to get default branch`,{repo:t,error:M(e)}),`main`}}async function Xe(e,t,n){try{let{data:n}=await e.rest.users.getByUsername({username:t});return{id:n.id,login:n.login}}catch(e){return n.debug(`Failed to get user by username`,{username:t,error:M(e)}),null}}const Ze={PER_PAGE:100,MAX_PAGES:50};async function Qe(e,t,n,r,i){i.debug(`Fetching PR diff`,{prNumber:r});let a=[],o=1,s=!1;for(;o<=Ze.MAX_PAGES;){let{data:c}=await e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:Ze.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.lengthZe.MAX_PAGES&&(s=!0,i.warning(`PR diff pagination limit reached`,{filesLoaded:a.length,maxPages:Ze.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}}async function $e(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 Qe(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:M(e)}),null}}async function et(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?.number??null,g=l?.title??null,_=u?.login??null,v=await $e(r,n,p,t),y=await tt(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):!1;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 Ye(n,p,t),diffContext:v,hydratedContext:y,authorAssociation:x,isRequestedReviewer:S}}async function tt(e,t,n,r,i,a){if(r==null||i==null)return null;let o=ke;return i===`issue`?await Ve(e,t,n,r,o,a)??Le(e,t,n,r,o,a):await He(e,t,n,r,o,a)??Re(e,t,n,r,o,a)}const nt=({onSseError:e,onSseEvent:t,responseTransformer:n,responseValidator:r,sseDefaultRetryDelay:i,sseMaxRetryAttempts:a,sseMaxRetryDelay:o,sseSleepFn:s,url:c,...l})=>{let u,d=s??(e=>new Promise(t=>setTimeout(t,e)));return{stream:async function*(){let s=i??3e3,f=0,p=l.signal??new AbortController().signal;for(;!p.aborted;){f++;let i=l.headers instanceof Headers?l.headers:new Headers(l.headers);u!==void 0&&i.set(`Last-Event-ID`,u);try{let e=await fetch(c,{...l,headers:i,signal:p});if(!e.ok)throw Error(`SSE failed: ${e.status} ${e.statusText}`);if(!e.body)throw Error(`No body in SSE response`);let a=e.body.pipeThrough(new TextDecoderStream).getReader(),o=``,d=()=>{try{a.cancel()}catch{}};p.addEventListener(`abort`,d);try{for(;;){let{done:e,value:i}=await a.read();if(e)break;o+=i;let c=o.split(` +`,{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:N(e)}),null}}async function Ve(e,t,n,r,i,a){let o=await ze(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=je(s.body??``,i.maxBodyBytes),l=s.comments.nodes.slice(0,i.maxComments),u=s.comments.totalCount>l.length,d=l.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),f=s.labels.nodes.map(e=>({name:e.name,color:e.color})),p=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:f,assignees:p,comments:d,commentsTruncated:u,totalComments:s.comments.totalCount}}async function He(e,t,n,r,i,a){let o=await Be(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=je(s.body??``,i.maxBodyBytes),l=s.baseRepository?.owner.login,u=s.headRepository?.owner.login,d=u==null||l!==u,f=s.comments.nodes.slice(0,i.maxComments),p=s.comments.totalCount>f.length,m=f.map(e=>({id:e.id,author:e.author?.login??null,body:e.body,createdAt:e.createdAt,authorAssociation:e.authorAssociation,isMinimized:e.isMinimized})),h=s.commits.nodes.slice(0,i.maxCommits),g=s.commits.totalCount>h.length,_=h.map(e=>({oid:e.commit.oid,message:e.commit.message,author:e.commit.author?.name??null})),v=s.files.nodes.slice(0,i.maxFiles),y=s.files.totalCount>v.length,b=v.map(e=>({path:e.path,additions:e.additions,deletions:e.deletions})),x=s.reviews.nodes.slice(0,i.maxReviews),S=s.reviews.totalCount>x.length,C=x.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}))})),w=s.labels.nodes.map(e=>({name:e.name,color:e.color})),T=s.assignees.nodes.map(e=>({login:e.login})),E=s.reviewRequests.nodes.map(e=>`login`in e.requestedReviewer?e.requestedReviewer.login:null).filter(e=>e!=null),D=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:w,assignees:T,comments:m,commentsTruncated:p,totalComments:s.comments.totalCount,commits:_,commitsTruncated:g,totalCommits:s.commits.totalCount,files:b,filesTruncated:y,totalFiles:s.files.totalCount,reviews:C,reviewsTruncated:S,totalReviews:s.reviews.totalCount,authorAssociation:s.authorAssociation,requestedReviewers:E,requestedReviewerTeams:D}}function K(e){let[t,n]=e.split(`/`);if(t==null||n==null||t.length===0||n.length===0)throw Error(`Invalid repository string: ${e}`);return{owner:t,repo:n}}async function Ue(e,t,n,r,i){try{let{owner:a,repo:o}=K(t),{data:s}=await e.rest.reactions.createForIssueComment({owner:a,repo:o,comment_id:n,content:r});return i.debug(`Created comment reaction`,{commentId:n,content:r,reactionId:s.id}),{id:s.id}}catch(e){return i.warning(`Failed to create comment reaction`,{commentId:n,content:r,error:N(e)}),null}}async function We(e,t,n,r){try{let{owner:r,repo:i}=K(t),{data:a}=await e.rest.reactions.listForIssueComment({owner:r,repo:i,comment_id:n,per_page:100});return a.map(e=>({id:e.id,content:e.content,userLogin:e.user?.login??null}))}catch(e){return r.warning(`Failed to list comment reactions`,{commentId:n,error:N(e)}),[]}}async function Ge(e,t,n,r,i){try{let{owner:a,repo:o}=K(t);return await e.rest.reactions.deleteForIssueComment({owner:a,repo:o,comment_id:n,reaction_id:r}),i.debug(`Deleted comment reaction`,{commentId:n,reactionId:r}),!0}catch(e){return i.warning(`Failed to delete comment reaction`,{commentId:n,reactionId:r,error:N(e)}),!1}}async function Ke(e,t,n,r,i,a){let{owner:o,repo:s}=K(t);try{return await e.rest.issues.createLabel({owner:o,repo:s,name:n,color:r,description:i}),a.debug(`Created label`,{name:n,color:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===422?(a.debug(`Label already exists`,{name:n}),!0):(a.warning(`Failed to create label`,{name:n,error:N(e)}),!1)}}async function qe(e,t,n,r,i){try{let{owner:a,repo:o}=K(t);return await e.rest.issues.addLabels({owner:a,repo:o,issue_number:n,labels:[...r]}),i.debug(`Added labels to issue`,{issueNumber:n,labels:r}),!0}catch(e){return i.warning(`Failed to add labels to issue`,{issueNumber:n,labels:r,error:N(e)}),!1}}async function Je(e,t,n,r,i){try{let{owner:a,repo:o}=K(t);return await e.rest.issues.removeLabel({owner:a,repo:o,issue_number:n,name:r}),i.debug(`Removed label from issue`,{issueNumber:n,label:r}),!0}catch(e){return e instanceof Error&&`status`in e&&e.status===404?(i.debug(`Label was not present on issue`,{issueNumber:n,label:r}),!0):(i.warning(`Failed to remove label from issue`,{issueNumber:n,label:r,error:N(e)}),!1)}}async function Ye(e,t,n){try{let{owner:n,repo:r}=K(t),{data:i}=await e.rest.repos.get({owner:n,repo:r});return i.default_branch}catch(e){return n.warning(`Failed to get default branch`,{repo:t,error:N(e)}),`main`}}async function Xe(e,t,n){try{let{data:n}=await e.rest.users.getByUsername({username:t});return{id:n.id,login:n.login}}catch(e){return n.debug(`Failed to get user by username`,{username:t,error:N(e)}),null}}const Ze={PER_PAGE:100,MAX_PAGES:50};async function Qe(e,t,n,r,i){i.debug(`Fetching PR diff`,{prNumber:r});let a=[],o=1,s=!1;for(;o<=Ze.MAX_PAGES;){let{data:c}=await e.rest.pulls.listFiles({owner:t,repo:n,pull_number:r,per_page:Ze.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.lengthZe.MAX_PAGES&&(s=!0,i.warning(`PR diff pagination limit reached`,{filesLoaded:a.length,maxPages:Ze.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}}async function $e(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 Qe(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:N(e)}),null}}async function et(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?.number??null,g=l?.title??null,_=u?.login??null,v=await $e(r,n,p,t),y=await tt(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):!1;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 Ye(n,p,t),diffContext:v,hydratedContext:y,authorAssociation:x,isRequestedReviewer:S}}async function tt(e,t,n,r,i,a){if(r==null||i==null)return null;let o=ke;return i===`issue`?await Ve(e,t,n,r,o,a)??Le(e,t,n,r,o,a):await He(e,t,n,r,o,a)??Re(e,t,n,r,o,a)}const nt=({onSseError:e,onSseEvent:t,responseTransformer:n,responseValidator:r,sseDefaultRetryDelay:i,sseMaxRetryAttempts:a,sseMaxRetryDelay:o,sseSleepFn:s,url:c,...l})=>{let u,d=s??(e=>new Promise(t=>setTimeout(t,e)));return{stream:async function*(){let s=i??3e3,f=0,p=l.signal??new AbortController().signal;for(;!p.aborted;){f++;let i=l.headers instanceof Headers?l.headers:new Headers(l.headers);u!==void 0&&i.set(`Last-Event-ID`,u);try{let e=await fetch(c,{...l,headers:i,signal:p});if(!e.ok)throw Error(`SSE failed: ${e.status} ${e.statusText}`);if(!e.body)throw Error(`No body in SSE response`);let a=e.body.pipeThrough(new TextDecoderStream).getReader(),o=``,d=()=>{try{a.cancel()}catch{}};p.addEventListener(`abort`,d);try{for(;;){let{done:e,value:i}=await a.read();if(e)break;o+=i;let c=o.split(` `);o=c.pop()??``;for(let e of c){let i=e.split(` `),a=[],o;for(let e of i)if(e.startsWith(`data:`))a.push(e.replace(/^data:\s*/,``));else if(e.startsWith(`event:`))o=e.replace(/^event:\s*/,``);else if(e.startsWith(`id:`))u=e.replace(/^id:\s*/,``);else if(e.startsWith(`retry:`)){let t=Number.parseInt(e.replace(/^retry:\s*/,``),10);Number.isNaN(t)||(s=t)}let c,l=!1;if(a.length){let e=a.join(` @@ -127,10 +127,10 @@ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J a `);for(let e of n)if(e.startsWith(`opencode server listening`)){let n=e.match(/on\s+(https?:\/\/[^\s]+)/);if(!n)throw Error(`Failed to parse server url from output: ${e}`);clearTimeout(i),t(n[1]);return}}),n.stderr?.on(`data`,e=>{a+=e.toString()}),n.on(`exit`,e=>{clearTimeout(i);let t=`Server exited with code ${e}`;a.trim()&&(t+=`\nServer output: ${a}`),r(Error(t))}),n.on(`error`,e=>{clearTimeout(i),r(e)}),e.signal&&e.signal.addEventListener(`abort`,()=>{clearTimeout(i),r(Error(`Aborted`))})}),close(){n.kill()}}}async function $t(e){let t=await Qt({...e});return{client:Zt({baseUrl:t.url}),server:t}}async function en(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid sleep duration: ${e}`);return new Promise(t=>setTimeout(t,e))}const tn={todowrite:[`Todo`,`\x1B[33m\x1B[1m`],todoread:[`Todo`,`\x1B[33m\x1B[1m`],bash:[`Bash`,`\x1B[31m\x1B[1m`],edit:[`Edit`,`\x1B[32m\x1B[1m`],glob:[`Glob`,`\x1B[34m\x1B[1m`],grep:[`Grep`,`\x1B[34m\x1B[1m`],list:[`List`,`\x1B[34m\x1B[1m`],read:[`Read`,`\x1B[35m\x1B[1m`],write:[`Write`,`\x1B[32m\x1B[1m`],websearch:[`Search`,`\x1B[2m\x1B[1m`]},nn=`\x1B[0m`;function rn(){return H.env.NO_COLOR==null}function an(e,t){let[n,r]=tn[e.toLowerCase()]??[e,`\x1B[36m\x1B[1m`],i=n.padEnd(10,` `);rn()?H.stdout.write(`\n${r}|${nn} ${i} ${nn}${t}\n`):H.stdout.write(`\n| ${i} ${t}\n`)}function on(e){H.stdout.write(`\n${e}\n`)}const sn={api_error:`API Error`,configuration:`Configuration Error`,internal:`Internal Error`,llm_fetch_error:`LLM Fetch Error`,llm_timeout:`LLM Timeout`,permission:`Permission Error`,rate_limit:`Rate Limit`,validation:`Validation Error`};function cn(e){return e.type===`rate_limit`?`:warning:`:e.type===`llm_timeout`?`:hourglass:`:e.type===`llm_fetch_error`||e.retryable?`:warning:`:`:x:`}function ln(e){let t=cn(e),n=sn[e.type],r=[];return r.push(`${t} **${n}**`),r.push(``),r.push(e.message),e.details!=null&&(r.push(``),r.push(`> ${e.details}`)),e.suggestedAction!=null&&(r.push(``),r.push(`**Suggested action:** ${e.suggestedAction}`)),e.retryable&&(r.push(``),r.push(`_This error is retryable._`)),e.resetTime!=null&&(r.push(``),r.push(`_Rate limit resets at: ${e.resetTime.toISOString()}_`)),r.join(` `)}function un(e,t,n,r){return{type:e,message:t,retryable:n,details:r?.details,suggestedAction:r?.suggestedAction,resetTime:r?.resetTime}}const dn=[/fetch failed/i,/connect\s*timeout/i,/connecttimeouterror/i,/timed?\s*out/i,/econnrefused/i,/econnreset/i,/etimedout/i,/network error/i];function fn(e){if(e==null)return!1;let t=``;if(typeof e==`string`)t=e;else if(e instanceof Error)t=e.message,`cause`in e&&typeof e.cause==`string`&&(t+=` ${e.cause}`);else if(typeof e==`object`){let n=e;typeof n.message==`string`&&(t=n.message),typeof n.cause==`string`&&(t+=` ${n.cause}`)}return dn.some(e=>e.test(t))}function pn(e,t){return un(`llm_fetch_error`,`LLM request failed: ${e}`,!0,{details:t==null?void 0:`Model: ${t}`,suggestedAction:`This is a transient network error. The request may succeed on retry, or try a different model.`})}function mn(e,t){return un(`configuration`,`Agent error: ${e}`,!1,{details:t==null?void 0:`Requested agent: ${t}`,suggestedAction:`Verify the agent name is correct and the required plugins (e.g., oMo) are installed.`})}function hn(e){try{let t=new URL(e);return t.hostname===`github.com`||t.hostname===`api.github.com`}catch{return!1}}function gn(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 _n(e){let t=e.match(/https:\/\/github\.com\/[a-zA-Z0-9-]+\/[\w.-]+\/(?:pull|issues)\/\d+(?:#issuecomment-\d+)?/g)??[];return[...new Set(t)].filter(hn)}function vn(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)]}var yn=class{constructor(){if(this.payload={},process.env.GITHUB_EVENT_PATH)if(ge(process.env.GITHUB_EVENT_PATH))this.payload=JSON.parse(_e(process.env.GITHUB_EVENT_PATH,{encoding:`utf8`}));else{let e=process.env.GITHUB_EVENT_PATH;process.stdout.write(`GITHUB_EVENT_PATH ${e} does not exist${me}`)}this.eventName=process.env.GITHUB_EVENT_NAME,this.sha=process.env.GITHUB_SHA,this.ref=process.env.GITHUB_REF,this.workflow=process.env.GITHUB_WORKFLOW,this.action=process.env.GITHUB_ACTION,this.actor=process.env.GITHUB_ACTOR,this.job=process.env.GITHUB_JOB,this.runAttempt=parseInt(process.env.GITHUB_RUN_ATTEMPT,10),this.runNumber=parseInt(process.env.GITHUB_RUN_NUMBER,10),this.runId=parseInt(process.env.GITHUB_RUN_ID,10),this.apiUrl=process.env.GITHUB_API_URL??`https://api.github.com`,this.serverUrl=process.env.GITHUB_SERVER_URL??`https://github.com`,this.graphqlUrl=process.env.GITHUB_GRAPHQL_URL??`https://api.github.com/graphql`}get issue(){let e=this.payload;return Object.assign(Object.assign({},this.repo),{number:(e.issue||e.pull_request||e).number})}get repo(){if(process.env.GITHUB_REPOSITORY){let[e,t]=process.env.GITHUB_REPOSITORY.split(`/`);return{owner:e,repo:t}}if(this.payload.repository)return{owner:this.payload.repository.owner.login,repo:this.payload.repository.name};throw Error(`context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'`)}},bn=T((e=>{Object.defineProperty(e,`__esModule`,{value:!0}),e.getProxyUrl=t,e.checkBypass=n;function t(e){let t=e.protocol===`https:`;if(n(e))return;let r=t?process.env.https_proxy||process.env.HTTPS_PROXY:process.env.http_proxy||process.env.HTTP_PROXY;if(r)try{return new i(r)}catch{if(!r.startsWith(`http://`)&&!r.startsWith(`https://`))return new i(`http://${r}`)}else return}function n(e){if(!e.hostname)return!1;let t=e.hostname;if(r(t))return!0;let n=process.env.no_proxy||process.env.NO_PROXY||``;if(!n)return!1;let i;e.port?i=Number(e.port):e.protocol===`http:`?i=80:e.protocol===`https:`&&(i=443);let a=[e.hostname.toUpperCase()];typeof i==`number`&&a.push(`${a[0]}:${i}`);for(let e of n.split(`,`).map(e=>e.trim().toUpperCase()).filter(e=>e))if(e===`*`||a.some(t=>t===e||t.endsWith(`.${e}`)||e.startsWith(`.`)&&t.endsWith(`${e}`)))return!0;return!1}function r(e){let t=e.toLowerCase();return t===`localhost`||t.startsWith(`127.`)||t.startsWith(`[::1]`)||t.startsWith(`[0:0:0:0:0:0:0:1]`)}var i=class extends URL{constructor(e,t){super(e,t),this._decodedUsername=decodeURIComponent(super.username),this._decodedPassword=decodeURIComponent(super.password)}get username(){return this._decodedUsername}get password(){return this._decodedPassword}}})),xn=e(T((e=>{var t=e&&e.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),n=e&&e.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),r=e&&e.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},e(t)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=e(r),o=0;oi(this,void 0,void 0,function*(){let t=Buffer.alloc(0);this.message.on(`data`,e=>{t=Buffer.concat([t,e])}),this.message.on(`end`,()=>{e(t.toString())})}))})}readBodyBuffer(){return i(this,void 0,void 0,function*(){return new Promise(e=>i(this,void 0,void 0,function*(){let t=[];this.message.on(`data`,e=>{t.push(e)}),this.message.on(`end`,()=>{e(Buffer.concat(t))})}))})}};e.HttpClientResponse=y;function b(e){return new URL(e).protocol===`https:`}e.HttpClient=class{constructor(e,t,n){this._ignoreSslError=!1,this._allowRedirects=!0,this._allowRedirectDowngrade=!1,this._maxRedirects=50,this._allowRetries=!1,this._maxRetries=1,this._keepAlive=!1,this._disposed=!1,this.userAgent=this._getUserAgentWithOrchestrationId(e),this.handlers=t||[],this.requestOptions=n,n&&(n.ignoreSslError!=null&&(this._ignoreSslError=n.ignoreSslError),this._socketTimeout=n.socketTimeout,n.allowRedirects!=null&&(this._allowRedirects=n.allowRedirects),n.allowRedirectDowngrade!=null&&(this._allowRedirectDowngrade=n.allowRedirectDowngrade),n.maxRedirects!=null&&(this._maxRedirects=Math.max(n.maxRedirects,0)),n.keepAlive!=null&&(this._keepAlive=n.keepAlive),n.allowRetries!=null&&(this._allowRetries=n.allowRetries),n.maxRetries!=null&&(this._maxRetries=n.maxRetries))}options(e,t){return i(this,void 0,void 0,function*(){return this.request(`OPTIONS`,e,null,t||{})})}get(e,t){return i(this,void 0,void 0,function*(){return this.request(`GET`,e,null,t||{})})}del(e,t){return i(this,void 0,void 0,function*(){return this.request(`DELETE`,e,null,t||{})})}post(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`POST`,e,t,n||{})})}patch(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PATCH`,e,t,n||{})})}put(e,t,n){return i(this,void 0,void 0,function*(){return this.request(`PUT`,e,t,n||{})})}head(e,t){return i(this,void 0,void 0,function*(){return this.request(`HEAD`,e,null,t||{})})}sendStream(e,t,n,r){return i(this,void 0,void 0,function*(){return this.request(e,t,n,r)})}getJson(e){return i(this,arguments,void 0,function*(e,t={}){t[d.Accept]=this._getExistingOrDefaultHeader(t,d.Accept,f.ApplicationJson);let n=yield this.get(e,t);return this._processResponse(n,this.requestOptions)})}postJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.post(e,r,n);return this._processResponse(i,this.requestOptions)})}putJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.put(e,r,n);return this._processResponse(i,this.requestOptions)})}patchJson(e,t){return i(this,arguments,void 0,function*(e,t,n={}){let r=JSON.stringify(t,null,2);n[d.Accept]=this._getExistingOrDefaultHeader(n,d.Accept,f.ApplicationJson),n[d.ContentType]=this._getExistingOrDefaultContentTypeHeader(n,f.ApplicationJson);let i=yield this.patch(e,r,n);return this._processResponse(i,this.requestOptions)})}request(e,t,n,r){return i(this,void 0,void 0,function*(){if(this._disposed)throw Error(`Client has already been disposed.`);let i=new URL(t),a=this._prepareRequest(e,i,r),o=this._allowRetries&&_.includes(e)?this._maxRetries+1:1,s=0,c;do{if(c=yield this.requestRaw(a,n),c&&c.message&&c.message.statusCode===u.Unauthorized){let e;for(let t of this.handlers)if(t.canHandleAuthentication(c)){e=t;break}return e?e.handleAuthentication(this,a,n):c}let t=this._maxRedirects;for(;c.message.statusCode&&m.includes(c.message.statusCode)&&this._allowRedirects&&t>0;){let o=c.message.headers.location;if(!o)break;let s=new URL(o);if(i.protocol===`https:`&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade)throw Error(`Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.`);if(yield c.readBody(),s.hostname!==i.hostname)for(let e in r)e.toLowerCase()===`authorization`&&delete r[e];a=this._prepareRequest(e,s,r),c=yield this.requestRaw(a,n),t--}if(!c.message.statusCode||!h.includes(c.message.statusCode))return c;s+=1,s{function i(e,t){e?r(e):t?n(t):r(Error(`Unknown error`))}this.requestRawWithCallback(e,t,i)})})}requestRawWithCallback(e,t,n){typeof t==`string`&&(e.options.headers||(e.options.headers={}),e.options.headers[`Content-Length`]=Buffer.byteLength(t,`utf8`));let r=!1;function i(e,t){r||(r=!0,n(e,t))}let a=e.httpModule.request(e.options,e=>{i(void 0,new y(e))}),o;a.on(`socket`,e=>{o=e}),a.setTimeout(this._socketTimeout||3*6e4,()=>{o&&o.end(),i(Error(`Request timeout: ${e.options.path}`))}),a.on(`error`,function(e){i(e)}),t&&typeof t==`string`&&a.write(t,`utf8`),t&&typeof t!=`string`?(t.on(`close`,function(){a.end()}),t.pipe(a)):a.end()}getAgent(e){let t=new URL(e);return this._getAgent(t)}getAgentDispatcher(e){let t=new URL(e),n=s.getProxyUrl(t);if(n&&n.hostname)return this._getProxyAgentDispatcher(t,n)}_prepareRequest(e,t,n){let r={};r.parsedUrl=t;let i=r.parsedUrl.protocol===`https:`;r.httpModule=i?o:a;let s=i?443:80;if(r.options={},r.options.host=r.parsedUrl.hostname,r.options.port=r.parsedUrl.port?parseInt(r.parsedUrl.port):s,r.options.path=(r.parsedUrl.pathname||``)+(r.parsedUrl.search||``),r.options.method=e,r.options.headers=this._mergeHeaders(n),this.userAgent!=null&&(r.options.headers[`user-agent`]=this.userAgent),r.options.agent=this._getAgent(r.parsedUrl),this.handlers)for(let e of this.handlers)e.prepareRequest(r.options);return r}_mergeHeaders(e){return this.requestOptions&&this.requestOptions.headers?Object.assign({},x(this.requestOptions.headers),x(e||{})):x(e||{})}_getExistingOrDefaultHeader(e,t,n){let r;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[t];e&&(r=typeof e==`number`?e.toString():e)}let i=e[t];return i===void 0?r===void 0?n:r:typeof i==`number`?i.toString():i}_getExistingOrDefaultContentTypeHeader(e,t){let n;if(this.requestOptions&&this.requestOptions.headers){let e=x(this.requestOptions.headers)[d.ContentType];e&&(n=typeof e==`number`?String(e):Array.isArray(e)?e.join(`, `):e)}let r=e[d.ContentType];return r===void 0?n===void 0?t:n:typeof r==`number`?String(r):Array.isArray(r)?r.join(`, `):r}_getAgent(e){let t,n=s.getProxyUrl(e),r=n&&n.hostname;if(this._keepAlive&&r&&(t=this._proxyAgent),r||(t=this._agent),t)return t;let i=e.protocol===`https:`,l=100;if(this.requestOptions&&(l=this.requestOptions.maxSockets||a.globalAgent.maxSockets),n&&n.hostname){let e={maxSockets:l,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(n.username||n.password)&&{proxyAuth:`${n.username}:${n.password}`}),{host:n.hostname,port:n.port})},r,a=n.protocol===`https:`;r=i?a?c.httpsOverHttps:c.httpsOverHttp:a?c.httpOverHttps:c.httpOverHttp,t=r(e),this._proxyAgent=t}if(!t){let e={keepAlive:this._keepAlive,maxSockets:l};t=i?new o.Agent(e):new a.Agent(e),this._agent=t}return i&&this._ignoreSslError&&(t.options=Object.assign(t.options||{},{rejectUnauthorized:!1})),t}_getProxyAgentDispatcher(e,t){let n;if(this._keepAlive&&(n=this._proxyAgentDispatcher),n)return n;let r=e.protocol===`https:`;return n=new l.ProxyAgent(Object.assign({uri:t.href,pipelining:this._keepAlive?1:0},(t.username||t.password)&&{token:`Basic ${Buffer.from(`${t.username}:${t.password}`).toString(`base64`)}`})),this._proxyAgentDispatcher=n,r&&this._ignoreSslError&&(n.options=Object.assign(n.options.requestTls||{},{rejectUnauthorized:!1})),n}_getUserAgentWithOrchestrationId(e){let t=e||`actions/http-client`,n=process.env.ACTIONS_ORCHESTRATION_ID;return n?`${t} actions_orchestration_id/${n.replace(/[^a-z0-9_.-]/gi,`_`)}`:t}_performExponentialBackoff(e){return i(this,void 0,void 0,function*(){e=Math.min(10,e);let t=5*2**e;return new Promise(e=>setTimeout(()=>e(),t))})}_processResponse(e,t){return i(this,void 0,void 0,function*(){return new Promise((n,r)=>i(this,void 0,void 0,function*(){let i=e.message.statusCode||0,a={statusCode:i,result:null,headers:{}};i===u.NotFound&&n(a);function o(e,t){if(typeof t==`string`){let e=new Date(t);if(!isNaN(e.valueOf()))return e}return t}let s,c;try{c=yield e.readBody(),c&&c.length>0&&(s=t&&t.deserializeDates?JSON.parse(c,o):JSON.parse(c),a.result=s),a.headers=e.message.headers}catch{}if(i>299){let e;e=s&&s.message?s.message:c&&c.length>0?c:`Failed request: (${i})`;let t=new v(e,i);t.result=a.result,r(t)}else n(a)}))})}};let x=e=>Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{})}))(),1),Sn=w(),Cn=function(e,t,n,r){function i(e){return e instanceof n?e:new n(function(t){t(e)})}return new(n||=Promise)(function(n,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function s(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){e.done?n(e.value):i(e.value).then(o,s)}c((r=r.apply(e,t||[])).next())})};function wn(e,t){if(!e&&!t.auth)throw Error(`Parameter token or opts.auth is required`);if(e&&t.auth)throw Error(`Parameters token and opts.auth may not both be specified`);return typeof t.auth==`string`?t.auth:`token ${e}`}function Tn(e){return new xn.HttpClient().getAgent(e)}function En(e){return new xn.HttpClient().getAgentDispatcher(e)}function Dn(e){let t=En(e);return(e,n)=>Cn(this,void 0,void 0,function*(){return(0,Sn.fetch)(e,Object.assign(Object.assign({},n),{dispatcher:t}))})}function On(){return process.env.GITHUB_API_URL||`https://api.github.com`}function kn(){return typeof navigator==`object`&&`userAgent`in navigator?navigator.userAgent:typeof process==`object`&&process.version!==void 0?`Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`:``}function An(e,t,n,r){if(typeof n!=`function`)throw Error(`method for before hook must be a function`);return r||={},Array.isArray(t)?t.reverse().reduce((t,n)=>An.bind(null,e,n,t,r),n)():Promise.resolve().then(()=>e.registry[t]?e.registry[t].reduce((e,t)=>t.hook.bind(null,e,r),n)():n(r))}function jn(e,t,n,r){let i=r;e.registry[n]||(e.registry[n]=[]),t===`before`&&(r=(e,t)=>Promise.resolve().then(i.bind(null,t)).then(e.bind(null,t))),t===`after`&&(r=(e,t)=>{let n;return Promise.resolve().then(e.bind(null,t)).then(e=>(n=e,i(n,t))).then(()=>n)}),t===`error`&&(r=(e,t)=>Promise.resolve().then(e.bind(null,t)).catch(e=>i(e,t))),e.registry[n].push({hook:r,orig:i})}function Mn(e,t,n){if(!e.registry[t])return;let r=e.registry[t].map(e=>e.orig).indexOf(n);r!==-1&&e.registry[t].splice(r,1)}const Nn=Function.bind,Pn=Nn.bind(Nn);function Fn(e,t,n){let r=Pn(Mn,null).apply(null,n?[t,n]:[t]);e.api={remove:r},e.remove=r,[`before`,`error`,`after`,`wrap`].forEach(r=>{let i=n?[t,r,n]:[t,r];e[r]=e.api[r]=Pn(jn,null).apply(null,i)})}function In(){let e=Symbol(`Singular`),t={registry:{}},n=An.bind(null,t,e);return Fn(n,t,e),n}function Ln(){let e={registry:{}},t=An.bind(null,e);return Fn(t,e),t}var Rn={Singular:In,Collection:Ln},zn=`octokit-endpoint.js/0.0.0-development ${kn()}`,Bn={method:`GET`,baseUrl:`https://api.github.com`,headers:{accept:`application/vnd.github.v3+json`,"user-agent":zn},mediaType:{format:``}};function Vn(e){return e?Object.keys(e).reduce((t,n)=>(t[n.toLowerCase()]=e[n],t),{}):{}}function Hn(e){if(typeof e!=`object`||!e||Object.prototype.toString.call(e)!==`[object Object]`)return!1;let t=Object.getPrototypeOf(e);if(t===null)return!0;let n=Object.prototype.hasOwnProperty.call(t,`constructor`)&&t.constructor;return typeof n==`function`&&n instanceof n&&Function.prototype.call(n)===Function.prototype.call(e)}function Un(e,t){let n=Object.assign({},e);return Object.keys(t).forEach(r=>{Hn(t[r])&&r in e?n[r]=Un(e[r],t[r]):Object.assign(n,{[r]:t[r]})}),n}function Wn(e){for(let t in e)e[t]===void 0&&delete e[t];return e}function Gn(e,t,n){if(typeof t==`string`){let[e,r]=t.split(` `);n=Object.assign(r?{method:e,url:r}:{url:e},n)}else n=Object.assign({},t);n.headers=Vn(n.headers),Wn(n),Wn(n.headers);let r=Un(e||{},n);return n.url===`/graphql`&&(e&&e.mediaType.previews?.length&&(r.mediaType.previews=e.mediaType.previews.filter(e=>!r.mediaType.previews.includes(e)).concat(r.mediaType.previews)),r.mediaType.previews=(r.mediaType.previews||[]).map(e=>e.replace(/-preview/,``))),r}function Kn(e,t){let n=/\?/.test(e)?`&`:`?`,r=Object.keys(t);return r.length===0?e:e+n+r.map(e=>e===`q`?`q=`+t.q.split(`+`).map(encodeURIComponent).join(`+`):`${e}=${encodeURIComponent(t[e])}`).join(`&`)}var qn=/\{[^{}}]+\}/g;function Jn(e){return e.replace(/(?:^\W+)|(?:(?e.concat(t),[]):[]}function Xn(e,t){let n={__proto__:null};for(let r of Object.keys(e))t.indexOf(r)===-1&&(n[r]=e[r]);return n}function Zn(e){return e.split(/(%[0-9A-Fa-f]{2})/g).map(function(e){return/%[0-9A-Fa-f]/.test(e)||(e=encodeURI(e).replace(/%5B/g,`[`).replace(/%5D/g,`]`)),e}).join(``)}function Qn(e){return encodeURIComponent(e).replace(/[!'()*]/g,function(e){return`%`+e.charCodeAt(0).toString(16).toUpperCase()})}function $n(e,t,n){return t=e===`+`||e===`#`?Zn(t):Qn(t),n?Qn(n)+`=`+t:t}function er(e){return e!=null}function tr(e){return e===`;`||e===`&`||e===`?`}function nr(e,t,n,r){var i=e[n],a=[];if(er(i)&&i!==``)if(typeof i==`string`||typeof i==`number`||typeof i==`boolean`)i=i.toString(),r&&r!==`*`&&(i=i.substring(0,parseInt(r,10))),a.push($n(t,i,tr(t)?n:``));else if(r===`*`)Array.isArray(i)?i.filter(er).forEach(function(e){a.push($n(t,e,tr(t)?n:``))}):Object.keys(i).forEach(function(e){er(i[e])&&a.push($n(t,i[e],e))});else{let e=[];Array.isArray(i)?i.filter(er).forEach(function(n){e.push($n(t,n))}):Object.keys(i).forEach(function(n){er(i[n])&&(e.push(Qn(n)),e.push($n(t,i[n].toString())))}),tr(t)?a.push(Qn(n)+`=`+e.join(`,`)):e.length!==0&&a.push(e.join(`,`))}else t===`;`?er(i)&&a.push(Qn(n)):i===``&&(t===`&`||t===`?`)?a.push(Qn(n)+`=`):i===``&&a.push(``);return a}function rr(e){return{expand:ir.bind(null,e)}}function ir(e,t){var n=[`+`,`#`,`.`,`/`,`;`,`?`,`&`];return e=e.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g,function(e,r,i){if(r){let e=``,i=[];if(n.indexOf(r.charAt(0))!==-1&&(e=r.charAt(0),r=r.substr(1)),r.split(/,/g).forEach(function(n){var r=/([^:\*]*)(?::(\d+)|(\*))?/.exec(n);i.push(nr(t,e,r[1],r[2]||r[3]))}),e&&e!==`+`){var a=`,`;return e===`?`?a=`&`:e!==`#`&&(a=e),(i.length===0?``:e)+i.join(a)}else return i.join(`,`)}else return Zn(i)}),e===`/`?e:e.replace(/\/$/,``)}function ar(e){let t=e.method.toUpperCase(),n=(e.url||`/`).replace(/:([a-z]\w+)/g,`{$1}`),r=Object.assign({},e.headers),i,a=Xn(e,[`method`,`baseUrl`,`url`,`headers`,`request`,`mediaType`]),o=Yn(n);n=rr(n).expand(a),/^http/.test(n)||(n=e.baseUrl+n);let s=Xn(a,Object.keys(e).filter(e=>o.includes(e)).concat(`baseUrl`));return/application\/octet-stream/i.test(r.accept)||(e.mediaType.format&&(r.accept=r.accept.split(/,/).map(t=>t.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/,`application/vnd$1$2.${e.mediaType.format}`)).join(`,`)),n.endsWith(`/graphql`)&&e.mediaType.previews?.length&&(r.accept=(r.accept.match(/(?`application/vnd.github.${t}-preview${e.mediaType.format?`.${e.mediaType.format}`:`+json`}`).join(`,`))),[`GET`,`HEAD`].includes(t)?n=Kn(n,s):`data`in s?i=s.data:Object.keys(s).length&&(i=s),!r[`content-type`]&&i!==void 0&&(r[`content-type`]=`application/json; charset=utf-8`),[`PATCH`,`PUT`].includes(t)&&i===void 0&&(i=``),Object.assign({method:t,url:n,headers:r},i===void 0?null:{body:i},e.request?{request:e.request}:null)}function or(e,t,n){return ar(Gn(e,t,n))}function sr(e,t){let n=Gn(e,t),r=or.bind(null,n);return Object.assign(r,{DEFAULTS:n,defaults:sr.bind(null,n),merge:Gn.bind(null,n),parse:ar})}var cr=sr(null,Bn),lr=T(((e,t)=>{let n=function(){};n.prototype=Object.create(null);let r=/; *([!#$%&'*+.^\w`|~-]+)=("(?:[\v\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\v\u0020-\u00ff])*"|[!#$%&'*+.^\w`|~-]+) */gu,i=/\\([\v\u0020-\u00ff])/gu,a=/^[!#$%&'*+.^\w|~-]+\/[!#$%&'*+.^\w|~-]+$/u,o={type:``,parameters:new n};Object.freeze(o.parameters),Object.freeze(o);function s(e){if(typeof e!=`string`)throw TypeError(`argument header is required and must be a string`);let t=e.indexOf(`;`),o=t===-1?e.trim():e.slice(0,t).trim();if(a.test(o)===!1)throw TypeError(`invalid media type`);let s={type:o.toLowerCase(),parameters:new n};if(t===-1)return s;let c,l,u;for(r.lastIndex=t;l=r.exec(e);){if(l.index!==t)throw TypeError(`invalid parameter format`);t+=l[0].length,c=l[1].toLowerCase(),u=l[2],u[0]===`"`&&(u=u.slice(1,u.length-1),i.test(u)&&(u=u.replace(i,`$1`))),s.parameters[c]=u}if(t!==e.length)throw TypeError(`invalid parameter format`);return s}function c(e){if(typeof e!=`string`)return o;let t=e.indexOf(`;`),s=t===-1?e.trim():e.slice(0,t).trim();if(a.test(s)===!1)return o;let c={type:s.toLowerCase(),parameters:new n};if(t===-1)return c;let l,u,d;for(r.lastIndex=t;u=r.exec(e);){if(u.index!==t)return o;t+=u[0].length,l=u[1].toLowerCase(),d=u[2],d[0]===`"`&&(d=d.slice(1,d.length-1),i.test(d)&&(d=d.replace(i,`$1`))),c.parameters[l]=d}return t===e.length?c:o}t.exports.default={parse:s,safeParse:c},t.exports.parse=s,t.exports.safeParse=c,t.exports.defaultContentType=o}))(),ur=class extends Error{name;status;request;response;constructor(e,t,n){super(e,{cause:n.cause}),this.name=`HttpError`,this.status=Number.parseInt(t),Number.isNaN(this.status)&&(this.status=0),`response`in n&&(this.response=n.response);let r=Object.assign({},n.request);n.request.headers.authorization&&(r.headers=Object.assign({},n.request.headers,{authorization:n.request.headers.authorization.replace(/(?``;async function hr(e){let t=e.request?.fetch||globalThis.fetch;if(!t)throw Error(`fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing`);let n=e.request?.log||console,r=e.request?.parseSuccessResponseBody!==!1,i=pr(e.body)||Array.isArray(e.body)?JSON.stringify(e.body):e.body,a=Object.fromEntries(Object.entries(e.headers).map(([e,t])=>[e,String(t)])),o;try{o=await t(e.url,{method:e.method,body:i,redirect:e.request?.redirect,headers:a,signal:e.request?.signal,...e.body&&{duplex:`half`}})}catch(t){let n=`Unknown Error`;if(t instanceof Error){if(t.name===`AbortError`)throw t.status=500,t;n=t.message,t.name===`TypeError`&&`cause`in t&&(t.cause instanceof Error?n=t.cause.message:typeof t.cause==`string`&&(n=t.cause))}let r=new ur(n,500,{request:e});throw r.cause=t,r}let s=o.status,c=o.url,l={};for(let[e,t]of o.headers)l[e]=t;let u={url:c,status:s,headers:l,data:``};if(`deprecation`in l){let t=l.link&&l.link.match(/<([^<>]+)>; rel="deprecation"/),r=t&&t.pop();n.warn(`[@octokit/request] "${e.method} ${e.url}" is deprecated. It is scheduled to be removed on ${l.sunset}${r?`. See ${r}`:``}`)}if(s===204||s===205)return u;if(e.method===`HEAD`){if(s<400)return u;throw new ur(o.statusText,s,{response:u,request:e})}if(s===304)throw u.data=await gr(o),new ur(`Not modified`,s,{response:u,request:e});if(s>=400)throw u.data=await gr(o),new ur(vr(u.data),s,{response:u,request:e});return u.data=r?await gr(o):o.body,u}async function gr(e){let t=e.headers.get(`content-type`);if(!t)return e.text().catch(mr);let n=(0,lr.safeParse)(t);if(_r(n)){let t=``;try{return t=await e.text(),JSON.parse(t)}catch{return t}}else if(n.type.startsWith(`text/`)||n.parameters.charset?.toLowerCase()===`utf-8`)return e.text().catch(mr);else return e.arrayBuffer().catch(()=>new ArrayBuffer(0))}function _r(e){return e.type===`application/json`||e.type===`application/scim+json`}function vr(e){if(typeof e==`string`)return e;if(e instanceof ArrayBuffer)return`Unknown error`;if(`message`in e){let t=`documentation_url`in e?` - ${e.documentation_url}`:``;return Array.isArray(e.errors)?`${e.message}: ${e.errors.map(e=>JSON.stringify(e)).join(`, `)}${t}`:`${e.message}${t}`}return`Unknown error: ${JSON.stringify(e)}`}function yr(e,t){let n=e.defaults(t);return Object.assign(function(e,t){let r=n.merge(e,t);if(!r.request||!r.request.hook)return hr(n.parse(r));let i=(e,t)=>hr(n.parse(n.merge(e,t)));return Object.assign(i,{endpoint:n,defaults:yr.bind(null,n)}),r.request.hook(i,r)},{endpoint:n,defaults:yr.bind(null,n)})}var br=yr(cr,fr),xr=`0.0.0-development`;function Sr(e){return`Request failed due to following response errors: `+e.errors.map(e=>` - ${e.message}`).join(` -`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${kn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${kn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Rn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new yn;const ii=On(),ai={baseUrl:ii,request:{agent:Tn(ii),fetch:Dn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=wn(e,n);return r&&(n.auth=r),n}const ci=new yn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(N(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=W.join(ki(),he.randomUUID()),yield S(W.dirname(t)),j(`Downloading ${e}`),j(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(U.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(j(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw j(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=ye.promisify(Oe.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,U.createWriteStream(t)),j(`download complete`),l=!0,t}finally{if(!l){j(`download failed`);try{yield s(t)}catch(e){j(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),j(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),j(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`pwsh`,!1);if(i){let e=[`-NoLogo`,`-NoProfile`,`-NonInteractive`,`-ExecutionPolicy`,`Unrestricted`,`-Command`,[`$ErrorActionPreference = 'Stop' ;`,`try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ;`,`try { [System.IO.Compression.ZipFile]::ExtractToDirectory('${n}', '${r}', $true) }`,`catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath '${n}' -DestinationPath '${r}' -Force } else { throw $_ } } ;`].join(` `)];j(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);j(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=pe.arch(),j(`Caching tool ${t} ${n} ${r}`),j(`source dir: ${e}`),!U.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of U.readdirSync(e))yield b(W.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=pe.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=W.join(Oi(),e,t,n);j(`checking cache: ${i}`),U.existsSync(i)&&U.existsSync(`${i}.complete`)?(j(`Found tool in cache ${e} ${t} ${n}`),r=i):j(`not found`)}return r}function Si(e,t){let n=[];t||=pe.arch();let r=W.join(Oi(),e);if(U.existsSync(r)){let e=U.readdirSync(r);for(let i of e)if(Ei(i)){let e=W.join(r,i,t||``);U.existsSync(e)&&U.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=W.join(ki(),he.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=W.join(Oi(),e,Y.clean(t)||t,n||``);j(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${W.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;U.writeFileSync(r,``),j(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;j(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return j(`explicit? ${n}`),n}function Di(e,t){let n=``;j(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return j(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ve(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ve(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=B.join(t,`auth.json`);await G.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await G.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=H.platform,t=H.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=ne){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(H.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=fe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=M(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Ce.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=fe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>H.platform===`win32`?`${e}.exe`:e,n=fe.join(e,t(`bun`));try{await Ce.symlink(n,fe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};H.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}function Gi(e,t){let n={...e};for(let[e,r]of Object.entries(t)){let t=n[e];typeof r==`object`&&r&&!Array.isArray(r)&&typeof t==`object`&&t&&!Array.isArray(t)?n[e]=Gi(t,r):n[e]=r}return n}async function Ki(e,t,n){let r=JSON.parse(e);await G.mkdir(t,{recursive:!0});let i=B.join(t,`oh-my-opencode.json`),a={};try{let e=await G.readFile(i,`utf8`),t=JSON.parse(e);typeof t==`object`&&t&&!Array.isArray(t)&&(a=t)}catch{}let o=Gi(a,r);await G.writeFile(i,JSON.stringify(o,null,2)),n.info(`Wrote oMo config`,{path:i,keyCount:Object.keys(r).length})}async function qi(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 OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u,kimiForCoding:d});let f=``,p=[`oh-my-opencode@${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-opencode 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=M(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-opencode install failed: ${n}`}}}const Ji=`opencode`,Yi=`1.2.9`;function Xi(){let e=Ee.platform(),t=Ee.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 Zi(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function Qi(e,t,n,r){if(H.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 $i(e,t,n,r,i=Yi){let a=Xi(),o=n.find(Ji,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){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:M(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}): ${M(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=Zi(e,t),o=await r.downloadTool(a);if(!await Qi(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,Ji,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function ta(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const na={restoreCache:async(e,t,n)=>se(e,t,n),saveCache:async(e,t)=>D(e,t)};function ra(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ce}-${t}-oc-${n}-omo-${r}`}function ia(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ce}-${t}-oc-${n}-omo-${r}-`]}async function aa(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=na}=e,l=ra({os:n,opencodeVersion:r,omoVersion:i}),u=ia({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:M(e)}),{hit:!1,restoredKey:null}}}async function oa(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=na}=e,l=ra({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:M(e)}),!1)}}const sa=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function ca(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(sa.includes(e))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 la(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function ua(){return{exec:x,getExecOutput:c}}function da(){return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:m(`app-id`)||null,privateKey:m(`private-key`)||null,opencodeConfig:m(`opencode-config`)||null,omoConfig:m(`omo-config`)||null}}async function fa(){let e=Date.now(),n=A({component:`setup`}),r=la(),o=ua();try{let s=da(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${M(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await ta(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:M(e)}),u=Yi}let d=m(`omo-version`).trim(),f=d.length>0?d:P,h=H.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=V(h,`opencode`),v=V(h,`bun`),y=V(De(),`.config`,`opencode`),b=a(),x=await aa({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await $i(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${M(e)}`),null}let E=!1;try{await Fi(n,r,o,t,ne),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:M(e)})}if(E){if(s.omoConfig!=null)try{await Ki(s.omoConfig,y,n)}catch(e){n.warning(`Failed to write omo-config, continuing without custom config`,{error:M(e)})}let e=m(`omo-providers`).trim(),t=ca(e.length>0?e:oe),r=await qi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let te={autoupdate:!1};if(s.opencodeConfig!=null){let e=JSON.parse(s.opencodeConfig);if(typeof e!=`object`||!e||Array.isArray(e))return _(`opencode-config must be a JSON object`),null;Object.assign(te,e)}p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(te)),x.hit||await oa({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),z(`opencode-path`,C.path),z(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let D=li(c),re=await Hi(D,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(D,re.botLogin,n,o);let O=V(i(),`opencode`),k=await Mi(l,O,n);z(`auth-json-path`,k),n.info(`auth.json populated`,{path:k});let A=H.env.GITHUB_REPOSITORY??`unknown/unknown`,j=H.env.GITHUB_REF_NAME??`main`,N=a(),ie=ee({agentIdentity:`github`,repo:A,ref:j,os:N}),F=ae({agentIdentity:`github`,repo:A,ref:j,os:N}),I=`miss`;try{let e=await se([O],ie,[...F]);e==null?n.info(`No cache found`):(I=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){I=`corrupted`,n.warning(`Cache restore failed`,{error:M(e)})}z(`cache-status`,I),z(`storage-path`,O);let L=Date.now()-e,R={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:re.authenticated,omoInstalled:w,omoError:T,cacheStatus:I,toolsCacheStatus:S,duration:L};return n.info(`Setup complete`,{duration:L}),R}catch(e){let t=M(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function pa(e){return{success:!0,data:e}}function ma(e){return{success:!1,error:e}}const ha=[`OWNER`,`MEMBER`,`COLLABORATOR`];function ga(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` -`),appendMode:!0};case`pull_request_review_comment`:return{directive:_a(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function _a(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` -`)}function va(e,t){let{directive:n,appendMode:r}=ga(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` -`)}function ya(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a}=e,o=[];if(o.push(`# Agent Context +`)}var Cr=class extends Error{constructor(e,t,n){super(Sr(n)),this.request=e,this.headers=t,this.response=n,this.errors=n.errors,this.data=n.data,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}name=`GraphqlResponseError`;errors;data},wr=[`method`,`baseUrl`,`url`,`headers`,`request`,`query`,`mediaType`,`operationName`],Tr=[`query`,`method`,`url`],Er=/\/api\/v3\/?$/;function Dr(e,t,n){if(n){if(typeof t==`string`&&`query`in n)return Promise.reject(Error(`[@octokit/graphql] "query" cannot be used as variable name`));for(let e in n)if(Tr.includes(e))return Promise.reject(Error(`[@octokit/graphql] "${e}" cannot be used as variable name`))}let r=typeof t==`string`?Object.assign({query:t},n):t,i=Object.keys(r).reduce((e,t)=>wr.includes(t)?(e[t]=r[t],e):(e.variables||={},e.variables[t]=r[t],e),{}),a=r.baseUrl||e.endpoint.DEFAULTS.baseUrl;return Er.test(a)&&(i.url=a.replace(Er,`/api/graphql`)),e(i).then(e=>{if(e.data.errors){let t={};for(let n of Object.keys(e.headers))t[n]=e.headers[n];throw new Cr(i,t,e.data)}return e.data.data})}function Or(e,t){let n=e.defaults(t);return Object.assign((e,t)=>Dr(n,e,t),{defaults:Or.bind(null,n),endpoint:n.endpoint})}Or(br,{headers:{"user-agent":`octokit-graphql.js/${xr} ${kn()}`},method:`POST`,url:`/graphql`});function kr(e){return Or(e,{method:`POST`,url:`/graphql`})}var Ar=`(?:[a-zA-Z0-9_-]+)`,jr=`\\.`,Mr=RegExp(`^${Ar}${jr}${Ar}${jr}${Ar}$`),Nr=Mr.test.bind(Mr);async function Pr(e){let t=Nr(e),n=e.startsWith(`v1.`)||e.startsWith(`ghs_`),r=e.startsWith(`ghu_`);return{type:`token`,token:e,tokenType:t?`app`:n?`installation`:r?`user-to-server`:`oauth`}}function Fr(e){return e.split(/\./).length===3?`bearer ${e}`:`token ${e}`}async function Ir(e,t,n,r){let i=t.endpoint.merge(n,r);return i.headers.authorization=Fr(e),t(i)}var Lr=function(e){if(!e)throw Error(`[@octokit/auth-token] No token passed to createTokenAuth`);if(typeof e!=`string`)throw Error(`[@octokit/auth-token] Token passed to createTokenAuth is not a string`);return e=e.replace(/^(token|bearer) +/i,``),Object.assign(Pr.bind(null,e),{hook:Ir.bind(null,e)})};const Rr=`7.0.6`,zr=()=>{},Br=console.warn.bind(console),Vr=console.error.bind(console);function Hr(e={}){return typeof e.debug!=`function`&&(e.debug=zr),typeof e.info!=`function`&&(e.info=zr),typeof e.warn!=`function`&&(e.warn=Br),typeof e.error!=`function`&&(e.error=Vr),e}const Ur=`octokit-core.js/${Rr} ${kn()}`;var Wr=class{static VERSION=Rr;static defaults(e){return class extends this{constructor(...t){let n=t[0]||{};if(typeof e==`function`){super(e(n));return}super(Object.assign({},e,n,n.userAgent&&e.userAgent?{userAgent:`${n.userAgent} ${e.userAgent}`}:null))}}}static plugins=[];static plugin(...e){let t=this.plugins;return class extends this{static plugins=t.concat(e.filter(e=>!t.includes(e)))}}constructor(e={}){let t=new Rn.Collection,n={baseUrl:br.endpoint.DEFAULTS.baseUrl,headers:{},request:Object.assign({},e.request,{hook:t.bind(null,`request`)}),mediaType:{previews:[],format:``}};if(n.headers[`user-agent`]=e.userAgent?`${e.userAgent} ${Ur}`:Ur,e.baseUrl&&(n.baseUrl=e.baseUrl),e.previews&&(n.mediaType.previews=e.previews),e.timeZone&&(n.headers[`time-zone`]=e.timeZone),this.request=br.defaults(n),this.graphql=kr(this.request).defaults(n),this.log=Hr(e.log),this.hook=t,e.authStrategy){let{authStrategy:n,...r}=e,i=n(Object.assign({request:this.request,log:this.log,octokit:this,octokitOptions:r},e.auth));t.wrap(`request`,i.hook),this.auth=i}else if(!e.auth)this.auth=async()=>({type:`unauthenticated`});else{let n=Lr(e.auth);t.wrap(`request`,n.hook),this.auth=n}let r=this.constructor;for(let t=0;t({async next(){if(!s)return{done:!0};try{let e=$r(await i({method:a,url:s,headers:o}));if(s=((e.headers.link||``).match(/<([^<>]+)>;\s*rel="next"/)||[])[1],!s&&`total_commits`in e.data){let t=new URL(e.url),n=t.searchParams,r=parseInt(n.get(`page`)||`1`,10);r*parseInt(n.get(`per_page`)||`250`,10){if(i.done)return t;let a=!1;function o(){a=!0}return t=t.concat(r?r(i.value,o):i.value.data),a?t:ni(e,t,n,r)})}Object.assign(ti,{iterator:ei});function ri(e){return{paginate:Object.assign(ti.bind(null,e),{iterator:ei.bind(null,e)})}}ri.VERSION=Qr,new yn;const ii=On(),ai={baseUrl:ii,request:{agent:Tn(ii),fetch:Dn(ii)}},oi=Wr.plugin(Xr,ri).defaults(ai);function si(e,t){let n=Object.assign({},t||{}),r=wn(e,n);return r&&(n.auth=r),n}const ci=new yn;function li(e,t,...n){return new(oi.plugin(...n))(si(e,t))}var Y=e(re(),1),ui=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())})},di=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 ui(this,void 0,void 0,function*(){let n=1;for(;nsetTimeout(t,e*1e3))})}},X=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())})},fi=class extends Error{constructor(e){super(`Unexpected HTTP response: ${e}`),this.httpStatusCode=e,Object.setPrototypeOf(this,new.target.prototype)}};const pi=process.platform===`win32`;process.platform;function mi(e,t,n,r){return X(this,void 0,void 0,function*(){return t||=W.join(ki(),he.randomUUID()),yield S(W.dirname(t)),M(`Downloading ${e}`),M(`Destination ${t}`),yield new di(3,Ai(`TEST_DOWNLOAD_TOOL_RETRY_MIN_SECONDS`,10),Ai(`TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS`,20)).execute(()=>X(this,void 0,void 0,function*(){return yield hi(e,t||``,n,r)}),e=>!(e instanceof fi&&e.httpStatusCode&&e.httpStatusCode<500&&e.httpStatusCode!==408&&e.httpStatusCode!==429))})}function hi(e,t,n,r){return X(this,void 0,void 0,function*(){if(U.existsSync(t))throw Error(`Destination file path ${t} already exists`);let i=new u(`actions/tool-cache`,[],{allowRetries:!1});n&&(M(`set auth`),r===void 0&&(r={}),r.authorization=n);let a=yield i.get(e,r);if(a.message.statusCode!==200){let t=new fi(a.message.statusCode);throw M(`Failed to download from "${e}". Code(${a.message.statusCode}) Message(${a.message.statusMessage})`),t}let o=ye.promisify(Oe.pipeline),c=Ai(`TEST_DOWNLOAD_TOOL_RESPONSE_MESSAGE_FACTORY`,()=>a.message)(),l=!1;try{return yield o(c,U.createWriteStream(t)),M(`download complete`),l=!0,t}finally{if(!l){M(`download failed`);try{yield s(t)}catch(e){M(`Failed to delete '${t}'. ${e.message}`)}}}})}function gi(e,t){return X(this,arguments,void 0,function*(e,t,n=`xz`){if(!e)throw Error(`parameter 'file' is required`);t=yield Ci(t),M(`Checking tar --version`);let r=``;yield x(`tar --version`,[],{ignoreReturnCode:!0,silent:!0,listeners:{stdout:e=>r+=e.toString(),stderr:e=>r+=e.toString()}}),M(r.trim());let i=r.toUpperCase().includes(`GNU TAR`),a;a=n instanceof Array?n:[n],l()&&!n.includes(`v`)&&a.push(`-v`);let o=t,s=e;return pi&&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 x(`tar`,a),t})}function _i(e,t){return X(this,void 0,void 0,function*(){if(!e)throw Error(`parameter 'file' is required`);return t=yield Ci(t),pi?yield vi(e,t):yield yi(e,t),t})}function vi(e,t){return X(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 d(`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(` `)];M(`Using pwsh at path: ${i}`),yield x(`"${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 d(`powershell`,!0);M(`Using powershell at path: ${t}`),yield x(`"${t}"`,e)}})}function yi(e,t){return X(this,void 0,void 0,function*(){let n=yield d(`unzip`,!0),r=[e];l()||r.unshift(`-q`),r.unshift(`-o`),yield x(`"${n}"`,r,{cwd:t})})}function bi(e,t,n,r){return X(this,void 0,void 0,function*(){if(n=Y.clean(n)||n,r||=pe.arch(),M(`Caching tool ${t} ${n} ${r}`),M(`source dir: ${e}`),!U.statSync(e).isDirectory())throw Error(`sourceDir is not a directory`);let i=yield wi(t,n,r);for(let t of U.readdirSync(e))yield b(W.join(e,t),i,{recursive:!0});return Ti(t,n,r),i})}function xi(e,t,n){if(!e)throw Error(`toolName parameter is required`);if(!t)throw Error(`versionSpec parameter is required`);n||=pe.arch(),Ei(t)||(t=Di(Si(e,n),t));let r=``;if(t){t=Y.clean(t)||``;let i=W.join(Oi(),e,t,n);M(`checking cache: ${i}`),U.existsSync(i)&&U.existsSync(`${i}.complete`)?(M(`Found tool in cache ${e} ${t} ${n}`),r=i):M(`not found`)}return r}function Si(e,t){let n=[];t||=pe.arch();let r=W.join(Oi(),e);if(U.existsSync(r)){let e=U.readdirSync(r);for(let i of e)if(Ei(i)){let e=W.join(r,i,t||``);U.existsSync(e)&&U.existsSync(`${e}.complete`)&&n.push(i)}}return n}function Ci(e){return X(this,void 0,void 0,function*(){return e||=W.join(ki(),he.randomUUID()),yield S(e),e})}function wi(e,t,n){return X(this,void 0,void 0,function*(){let r=W.join(Oi(),e,Y.clean(t)||t,n||``);M(`destination ${r}`);let i=`${r}.complete`;return yield s(r),yield s(i),yield S(r),r})}function Ti(e,t,n){let r=`${W.join(Oi(),e,Y.clean(t)||t,n||``)}.complete`;U.writeFileSync(r,``),M(`finished caching tool`)}function Ei(e){let t=Y.clean(e)||``;M(`isExplicit: ${t}`);let n=Y.valid(t)!=null;return M(`explicit? ${n}`),n}function Di(e,t){let n=``;M(`evaluating ${e.length} versions`),e=e.sort((e,t)=>Y.gt(e,t)?1:-1);for(let r=e.length-1;r>=0;r--){let i=e[r];if(Y.satisfies(i,t)){n=i;break}}return M(n?`matched: ${n}`:`match not found`),n}function Oi(){let e=process.env.RUNNER_TOOL_CACHE||``;return ve(e,`Expected RUNNER_TOOL_CACHE to be defined`),e}function ki(){let e=process.env.RUNNER_TEMP||``;return ve(e,`Expected RUNNER_TEMP to be defined`),e}function Ai(e,t){let n=global[e];return n===void 0?t:n}function ji(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 Mi(e,t,n){let r=B.join(t,`auth.json`);await G.mkdir(t,{recursive:!0});let i=JSON.stringify(e,null,2);return await G.writeFile(r,i,{mode:384}),n.info(`Populated auth.json`,{path:r,providers:Object.keys(e).length}),r}function Ni(){let e=H.platform,t=H.arch;return{os:{darwin:`darwin`,linux:`linux`,win32:`windows`}[e]??`linux`,arch:{arm64:`aarch64`,x64:`x64`}[t]??`x64`,ext:`.zip`}}function Pi(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 Fi(e,t,n,r,i=te){let a=Ni(),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 Li(o),{path:o,version:i,cached:!0};e.info(`Downloading Bun`,{version:i});let s=Pi(i,a);try{let o=await t.downloadTool(s);if(H.platform!==`win32`&&!await Ri(o,e,n))throw Error(`Downloaded Bun archive appears corrupted`);e.info(`Extracting Bun`);let c=await Ii(await t.extractZip(o),t),l=fe.dirname(c);e.info(`Caching Bun`);let u=await t.cacheDir(l,`bun`,i,a.arch);return r(u),await Li(u),e.info(`Bun installed`,{version:i,path:u}),{path:u,version:i,cached:!1}}catch(e){let t=N(e);throw Error(`Failed to install Bun ${i}: ${t}`)}}async function Ii(e,t){for(let n of await Ce.readdir(e,{withFileTypes:!0})){let{name:r}=n,i=fe.join(e,r);if(n.isFile()){if(r===`bun`||r===`bun.exe`)return i;if(/^bun.*\.zip/.test(r))return Ii(await t.extractZip(i),t)}if(r.startsWith(`bun`)&&n.isDirectory())return Ii(i,t)}throw Error(`Could not find executable: bun`)}async function Li(e){let t=e=>H.platform===`win32`?`${e}.exe`:e,n=fe.join(e,t(`bun`));try{await Ce.symlink(n,fe.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 Ri(e,t,n){try{let{stdout:r}=await n.getExecOutput(`file`,[e],{silent:!0}),i=r.includes(`Zip archive`)||r.includes(`ZIP`);return i||t.warning(`Bun download validation failed`,{output:r.trim()}),i}catch{return t.debug(`Could not validate Bun download (file command unavailable)`),!0}}function zi(e){return{debug:t=>e.debug(t),info:t=>e.info(t),warn:t=>e.warning(t),error:t=>e.error(t)}}function Bi(e){let{token:t,logger:n}=e;return n.debug(`Creating GitHub client with token`),li(t,{log:zi(n)})}async function Vi(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 Hi(e,t,n,r){let i=t??n,a=t==null?n.length>0?`github-token`:`none`:`app-token`;if(i.length===0)return r.warning(`No GitHub token available`),{authenticated:!1,method:`none`,botLogin:null};H.env.GH_TOKEN=i,r.info(`Configured authentication`,{method:a});let o=null;return e!=null&&(o=await Vi(e,r)),{authenticated:!0,method:a,botLogin:o}}async function Ui(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 Wi(e,t,n,r){let i=await Ui(`user.name`,r),a=await Ui(`user.email`,r);if(i!=null&&a!=null){n.info(`Git identity already configured`,{name:i,email:a});return}if(t==null)throw Error(`Cannot configure Git identity: no authenticated GitHub user`);let o=null;if(a==null){let r=await Xe(e,t,n);if(r==null)throw Error(`Cannot configure Git identity: failed to look up user ID for '${t}'`);o=String(r.id)}i??await r.exec(`git`,[`config`,`--global`,`user.name`,t],void 0);let s=`${o}+${t}@users.noreply.github.com`;a??await r.exec(`git`,[`config`,`--global`,`user.email`,s],void 0),n.info(`Configured git identity`,{name:i??t,email:a??s})}const Gi=new Set([`__proto__`,`prototype`,`constructor`]);function Ki(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function qi(e,t){let n=Object.create(null);for(let[t,r]of Object.entries(e))Gi.has(t)||(n[t]=r);for(let[e,r]of Object.entries(t)){if(Gi.has(e))continue;let t=n[e];Ki(r)&&Ki(t)?n[e]=qi(t,r):n[e]=r}return n}async function Ji(e,t,n){let r=JSON.parse(e);if(!Ki(r))throw Error(`omo-config must be a JSON object (non-null, non-array)`);let i=r;await G.mkdir(t,{recursive:!0});let a=B.join(t,`oh-my-opencode.json`),o={};try{let e=await G.readFile(a,`utf8`),t=JSON.parse(e);typeof t==`object`&&t&&!Array.isArray(t)&&(o=t)}catch(e){n.debug(`Using empty base oMo config`,{path:a,error:String(e)})}let s=qi(o,i);await G.writeFile(a,JSON.stringify(s,null,2)),n.info(`Wrote oMo config`,{path:a,keyCount:Object.keys(i).length})}async function Yi(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 OpenCode plugin`,{version:e,claude:a,copilot:o,gemini:s,openai:c,opencodeZen:l,zaiCodingPlan:u,kimiForCoding:d});let f=``,p=[`oh-my-opencode@${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-opencode 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=N(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-opencode install failed: ${n}`}}}const Xi=`opencode`,Zi=`1.2.9`;function Qi(){let e=Ee.platform(),t=Ee.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 $i(e,t){return`https://github.com/anomalyco/opencode/releases/download/${e.startsWith(`v`)?e:`v${e}`}/${`opencode-${t.os}-${t.arch}${t.ext}`}`}async function ea(e,t,n,r){if(H.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=Zi){let a=Qi(),o=n.find(Xi,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 na(e,a,t,n,r)}catch(n){t.warning(`Primary version install failed, trying fallback`,{requestedVersion:e,fallbackVersion:i,error:N(n)})}if(e!==i)try{let e=await na(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}): ${N(t)}`)}throw Error(`Failed to install OpenCode version ${e}`)}async function na(e,t,n,r,i){n.info(`Downloading OpenCode`,{version:e});let a=$i(e,t),o=await r.downloadTool(a);if(!await ea(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,Xi,e,t.arch);return n.info(`OpenCode installed`,{version:e,path:c}),{path:c,version:e,cached:!1}}async function ra(e){let t=await fetch(`https://api.github.com/repos/anomalyco/opencode/releases/latest`);if(!t.ok)throw Error(`Failed to fetch latest OpenCode version: ${t.statusText}`);let n=(await t.json()).tag_name.replace(/^v/,``);return e.info(`Latest OpenCode version`,{version:n}),n}const ia={restoreCache:async(e,t,n)=>se(e,t,n),saveCache:async(e,t)=>O(e,t)};function aa(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return`${ce}-${t}-oc-${n}-omo-${r}`}function oa(e){let{os:t,opencodeVersion:n,omoVersion:r}=e;return[`${ce}-${t}-oc-${n}-omo-${r}-`]}async function sa(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ia}=e,l=aa({os:n,opencodeVersion:r,omoVersion:i}),u=oa({os:n,opencodeVersion:r,omoVersion:i}),d=[a,o,s];t.info(`Restoring tools cache`,{primaryKey:l,restoreKeys:[...u],paths:d});try{let e=await c.restoreCache(d,l,[...u]);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:N(e)}),{hit:!1,restoredKey:null}}}async function ca(e){let{logger:t,os:n,opencodeVersion:r,omoVersion:i,toolCachePath:a,bunCachePath:o,omoConfigPath:s,cacheAdapter:c=ia}=e,l=aa({os:n,opencodeVersion:r,omoVersion:i}),u=[a,o,s];t.info(`Saving tools cache`,{saveKey:l,paths:u});try{return await c.saveCache(u,l),t.info(`Tools cache saved`,{saveKey:l}),!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:N(e)}),!1)}}const la=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function ua(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(la.includes(e))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 da(){return{find:xi,downloadTool:mi,extractTar:gi,extractZip:_i,cacheDir:bi}}function fa(){return{exec:x,getExecOutput:c}}function pa(){let e=m(`app-id`).trim(),t=m(`private-key`).trim(),n=m(`opencode-config`).trim(),r=m(`omo-config`).trim();return{opencodeVersion:m(`opencode-version`)||`latest`,authJson:m(`auth-json`,{required:!0}),appId:e.length>0?e:null,privateKey:t.length>0?t:null,opencodeConfig:n.length>0?n:null,omoConfig:r.length>0?r:null}}async function ma(){let e=Date.now(),n=j({component:`setup`}),r=da(),o=fa();try{let s=pa(),c=m(`github-token`,{required:!0});n.info(`Starting setup`,{version:s.opencodeVersion});let l;try{l=ji(s.authJson)}catch(e){return _(`Invalid auth-json: ${N(e)}`),null}let u=s.opencodeVersion;if(u===`latest`)try{u=await ra(n)}catch(e){n.warning(`Failed to get latest version, using fallback`,{error:N(e)}),u=Zi}let d=m(`omo-version`).trim(),f=d.length>0?d:P,h=H.env.RUNNER_TOOL_CACHE??`/opt/hostedtoolcache`,g=V(h,`opencode`),v=V(h,`bun`),y=V(De(),`.config`,`opencode`),b=a(),x=await sa({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),S=x.hit?`hit`:`miss`,C,w=!1,T=null;if(x.hit){let e=r.find(`opencode`,u);e.length>0?(C={path:e,version:u,cached:!0},n.info(`Tools cache hit, using cached OpenCode CLI`,{version:u,omoVersion:f})):n.warning(`Tools cache hit but binary not found in tool-cache, falling through to install`,{requestedVersion:u,restoredKey:x.restoredKey})}if(C==null)try{C=await ta(u,n,r,o)}catch(e){return _(`Failed to install OpenCode: ${N(e)}`),null}let E=!1;try{await Fi(n,r,o,t,te),E=!0}catch(e){n.warning(`Bun installation failed, oMo will be unavailable`,{error:N(e)})}if(E){if(s.omoConfig!=null)try{await Ji(s.omoConfig,y,n)}catch(e){n.warning(`Failed to write omo-config, continuing without custom config`,{error:N(e)})}let e=m(`omo-providers`).trim(),t=ua(e.length>0?e:oe),r=await Yi(f,{logger:n,execAdapter:o},t);r.installed?(n.info(`oMo installed`,{version:r.version}),w=!0):n.warning(`oMo installation failed, continuing without oMo`,{error:r.error??`unknown error`}),T=r.error}let ee={autoupdate:!1};if(s.opencodeConfig!=null){let e;try{e=JSON.parse(s.opencodeConfig)}catch{return _(`opencode-config must be valid JSON`),null}if(typeof e!=`object`||!e||Array.isArray(e))return _(`opencode-config must be a JSON object`),null;Object.assign(ee,e)}p(`OPENCODE_CONFIG_CONTENT`,JSON.stringify(ee)),x.hit||await ca({logger:n,os:b,opencodeVersion:u,omoVersion:f,toolCachePath:g,bunCachePath:v,omoConfigPath:y}),t(C.path),z(`opencode-path`,C.path),z(`opencode-version`,C.version),n.info(`OpenCode ready`,{version:C.version,cached:C.cached});let O=li(c),ne=await Hi(O,null,c,n);p(`GH_TOKEN`,c),n.info(`GitHub CLI configured`),await Wi(O,ne.botLogin,n,o);let k=V(i(),`opencode`),A=await Mi(l,k,n);z(`auth-json-path`,A),n.info(`auth.json populated`,{path:A});let j=H.env.GITHUB_REPOSITORY??`unknown/unknown`,M=H.env.GITHUB_REF_NAME??`main`,re=a(),ie=D({agentIdentity:`github`,repo:j,ref:M,os:re}),F=ae({agentIdentity:`github`,repo:j,ref:M,os:re}),I=`miss`;try{let e=await se([k],ie,[...F]);e==null?n.info(`No cache found`):(I=`hit`,n.info(`Cache restored`,{key:e}))}catch(e){I=`corrupted`,n.warning(`Cache restore failed`,{error:N(e)})}z(`cache-status`,I),z(`storage-path`,k);let L=Date.now()-e,R={opencodePath:C.path,opencodeVersion:C.version,ghAuthenticated:ne.authenticated,omoInstalled:w,omoError:T,cacheStatus:I,toolsCacheStatus:S,duration:L};return n.info(`Setup complete`,{duration:L}),R}catch(e){let t=N(e);return n.error(`Setup failed`,{error:t}),_(t),null}}function ha(e){return{success:!0,data:e}}function ga(e){return{success:!1,error:e}}const _a=[`OWNER`,`MEMBER`,`COLLABORATOR`];function va(e,t){switch(e.eventType){case`issue_comment`:return{directive:`Respond to the comment above. Post your response as a single comment on this thread.`,appendMode:!0};case`discussion_comment`:return{directive:`Respond to the discussion comment above. Post your response as a single comment.`,appendMode:!0};case`issues`:return e.action===`opened`?{directive:`Triage this issue: summarize, reproduce if possible, propose next steps. Post your response as a single comment.`,appendMode:!0}:{directive:`Respond to the mention in this issue. Post your response as a single comment.`,appendMode:!0};case`pull_request`:return{directive:[`Review this pull request for code quality, potential bugs, and improvements.`,"If you are a requested reviewer, submit a review via `gh pr review` with your full response (including Run Summary) in the --body.",`Include the Run Summary in the review body. Do not post a separate comment.`,`If the author is a collaborator, prioritize actionable feedback over style nits.`].join(` +`),appendMode:!0};case`pull_request_review_comment`:return{directive:ya(e),appendMode:!0};case`schedule`:case`workflow_dispatch`:return{directive:t??``,appendMode:!1};default:return{directive:`Execute the requested operation.`,appendMode:!0}}}function ya(e){let t=e.target,n=[`Respond to the review comment.`,``];return t?.path!=null&&n.push(`**File:** \`${t.path}\``),t?.line!=null&&n.push(`**Line:** ${t.line}`),t?.commitId!=null&&n.push(`**Commit:** \`${t.commitId}\``),t?.diffHunk!=null&&t.diffHunk.length>0&&n.push(``,`**Diff Context:**`,"```diff",t.diffHunk,"```"),n.join(` +`)}function ba(e,t){let{directive:n,appendMode:r}=va(e,t),i=[`## Task`,``];return r?(i.push(n),t!=null&&t.trim().length>0&&i.push(``,`**Additional Instructions:**`,t.trim())):i.push(n),i.push(``),i.join(` +`)}function xa(e,t){let{context:n,customPrompt:r,cacheStatus:i,sessionContext:a}=e,o=[];if(o.push(`# Agent Context You are the Fro Bot Agent running in a non-interactive CI environment (GitHub Actions). @@ -149,7 +149,7 @@ Execute the requested operation for repository ${n.repo}. Follow all instruction `):o.push(`## Task Respond to the trigger comment above. Follow all instructions and requirements listed in this prompt. -`):o.push(va(e.triggerContext,r)),e.triggerContext!=null){let t=e.triggerContext.eventType;(t===`pull_request`||t===`pull_request_review_comment`)&&o.push(Ca(n))}if(o.push(` +`):o.push(ba(e.triggerContext,r)),e.triggerContext!=null){let t=e.triggerContext.eventType;(t===`pull_request`||t===`pull_request_review_comment`)&&o.push(Ta(n))}if(o.push(` ## Environment - **Repository:** ${n.repo} - **Branch/Ref:** ${n.ref} @@ -167,7 +167,7 @@ Respond to the trigger comment above. Follow all instructions and requirements l \`\`\` ${n.commentBody} \`\`\` -`),a!=null&&o.push(xa(a)),n.diffContext!=null&&o.push(Sa(n.diffContext)),n.hydratedContext!=null&&o.push(Ie(n.hydratedContext)),o.push(`## Session Management (REQUIRED) +`),a!=null&&o.push(Ca(a)),n.diffContext!=null&&o.push(wa(n.diffContext)),n.hydratedContext!=null&&o.push(Ie(n.hydratedContext)),o.push(`## Session Management (REQUIRED) Before investigating any issue: 1. Use \`session_search\` to find relevant prior sessions for this repository @@ -178,7 +178,7 @@ Before completing: 1. Ensure your session contains a summary of work done 2. Include key decisions, findings, and outcomes 3. This summary will be searchable in future agent runs -`),n.issueNumber!=null&&o.push(ba(n,i,e.sessionId));let s=n.issueNumber??``,c=n.issueNumber!=null;o.push(`## GitHub Operations (Use gh CLI) +`),n.issueNumber!=null&&o.push(Sa(n,i,e.sessionId));let s=n.issueNumber??``,c=n.issueNumber!=null;o.push(`## GitHub Operations (Use gh CLI) The \`gh\` CLI is pre-authenticated. Use it for all GitHub operations. ${c?` @@ -215,7 +215,7 @@ gh api repos/${n.repo}/issues --jq '.[].title' gh api repos/${n.repo}/pulls/${s}/files --jq '.[].filename' \`\`\` `);let l=o.join(` -`);return t.debug(`Built agent prompt`,{length:l.length,hasCustom:r!=null,hasSessionContext:a!=null}),l}function ba(e,t,n){let r=e.issueNumber??``;return`## Response Protocol (REQUIRED) +`);return t.debug(`Built agent prompt`,{length:l.length,hasCustom:r!=null,hasSessionContext:a!=null}),l}function Sa(e,t,n){let r=e.issueNumber??``;return`## Response Protocol (REQUIRED) You MUST post exactly ONE comment or review per invocation. All of your output — your response content AND the Run Summary — goes into that single artifact. @@ -251,12 +251,12 @@ Every response you post — regardless of channel (issue, PR, discussion, review \`\`\` -`}function xa(e){let t=[`## Prior Session Context`];if(e.recentSessions.length>0){t.push(``),t.push(`### Recent Sessions`),t.push(`| ID | Title | Updated | Messages | Agents |`),t.push(`|----|-------|---------|----------|--------|`);for(let n of e.recentSessions.slice(0,5)){let e=new Date(n.updatedAt).toISOString().split(`T`)[0],r=n.agents.join(`, `)||`N/A`,i=n.title||`Untitled`;t.push(`| ${n.id} | ${i} | ${e} | ${n.messageCount} | ${r} |`)}t.push(``),t.push("Use `session_read` to review any of these sessions in detail.")}if(e.priorWorkContext.length>0){t.push(``),t.push(`### Relevant Prior Work`),t.push(``),t.push(`The following sessions contain content related to this issue:`),t.push(``);for(let n of e.priorWorkContext.slice(0,3)){t.push(`**Session ${n.sessionId}:**`),t.push("```markdown");for(let e of n.matches.slice(0,2))t.push(`- ${e.excerpt}`);t.push("```"),t.push(``)}t.push("Use `session_read` to review full context before starting new investigation.")}return t.push(``),t.join(` -`)}function Sa(e){let t=[`## Pull Request Diff Summary`];if(t.push(``),t.push(`- **Changed Files:** ${e.changedFiles}`),t.push(`- **Additions:** +${e.additions}`),t.push(`- **Deletions:** -${e.deletions}`),e.truncated&&t.push(`- **Note:** Diff was truncated due to size limits`),e.files.length>0){t.push(``),t.push(`### Changed Files`),t.push(`| File | Status | +/- |`),t.push(`|------|--------|-----|`);for(let n of e.files.slice(0,20))t.push(`| \`${n.filename}\` | ${n.status} | +${n.additions}/-${n.deletions} |`);e.files.length>20&&t.push(`| ... | | +${e.files.length-20} more files |`)}return t.push(``),t.join(` -`)}function Ca(e){let t=[`## Output Contract`,``];return t.push(`- Review action: approve/request-changes if confident; otherwise comment-only`),t.push(`- Requested reviewer: ${e.isRequestedReviewer?`yes`:`no`}`),e.authorAssociation!=null&&t.push(`- Author association: ${e.authorAssociation}`),t.push(``),t.join(` -`)}function wa(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function Ta(e,t,n,r,i){let a=_n(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=vn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function Ea(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(wa(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(on(a),a=``)}else if(e.type===`tool`){let t=e.state;if(t.status===`completed`){let n=e.tool,r=t.input,i=t.title;an(n,i),n.toLowerCase()===`bash`&&Ta(String(r.command??r.cmd??``),String(t.output),l,u,()=>{d++})}}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error;r.error(`Session error`,{error:e});let t=typeof e==`string`?e:String(e);f=fn(e)?pn(t,s??void 0):mn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(on(a),a=``))}return a.length>0&&on(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}async function Da(e,t,n,r,i,a=E,o){let s=Date.now(),c=0;for(;!r.aborted;){if(await en(500),r.aborted)return{completed:!1,error:`Aborted`};if(o?.sessionError==null)c=0;else{if(c++,c>=3)return i.error(`Session error persisted through grace period`,{sessionId:t,error:o.sessionError,graceCycles:c}),{completed:!1,error:`Session error: ${o.sessionError}`};continue}if(o?.sessionIdle===!0)return i.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let l=Date.now()-s;if(a>0&&l>=a)return i.warning(`Poll timeout reached`,{elapsedMs:l,maxPollTimeMs:a}),{completed:!1,error:`Poll timeout after ${l}ms`};try{let r=((await e.session.status({query:{directory:n}})).data??{})[t];if(r==null)i.debug(`Session status not found in poll response`,{sessionId:t});else if(r.type===`idle`)return i.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else i.debug(`Session status`,{sessionId:t,type:r.type});if(o!=null&&!o.firstMeaningfulEventReceived){let e=Date.now()-s;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:M(e)})}}return{completed:!1,error:`Aborted`}}async function Oa(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}const ka=5e3;function Aa(e){return e==null?!1:Object.values(e.omoProviders).some(e=>e!==`no`)}function ja(e){if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!Aa(e))return{providerID:re.providerID,modelID:re.modelID}}async function Ma(e,t,n,r,i,a,o){let s=a?.agent??R,c=new AbortController,l={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},u=await e.event.subscribe(),d={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},f=Ea(u.stream,t,c.signal,o,l).then(e=>{d=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&o.debug(`Event stream error`,{error:e.message})}),p=async()=>{c.abort(),await Oa(f)},m=[{type:`text`,text:n}];r!=null&&r.length>0&&(m.push(...r),o.info(`Including file attachments in prompt`,{count:r.length}));let h=ja(a),g={parts:m};h!=null&&(g.model=h),s!==R&&(g.agent=s),o.debug(`Sending prompt to OpenCode`,{sessionId:t});try{let n=await e.session.promptAsync({path:{id:t},body:g,query:{directory:i}});if(n.error!=null){o.error(`OpenCode prompt failed`,{error:String(n.error)}),await p();let e=fn(n.error)?pn(String(n.error),d.model??void 0):d.llmError;return{success:!1,error:String(n.error),llmError:e,shouldRetry:e!=null,eventStreamResult:d}}let r=a?.timeoutMs??E,s=await Da(e,t,i,c.signal,o,r,l);if(await p(),!s.completed){let e=s.error??`Session did not reach idle state`;return o.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:d.llmError,shouldRetry:d.llmError!=null,eventStreamResult:d}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:d}}finally{c.abort(),await Oa(f)}}async function Na(e,t){try{let{client:n,server:r}=await $t({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),pa({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),ma(Error(`Server bootstrap failed: ${n}`))}}async function Pa(e,t,n,r){let i=Date.now(),a=new AbortController,o=n?.timeoutMs??E,s=null,c=!1,l=r==null,u=null;o>0&&(s=setTimeout(()=>{c=!0,t.warning(`Execution timeout reached`,{timeoutMs:o}),a.abort()},o)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??R,hasModelOverride:n?.model!=null,timeoutMs:o});try{let s;if(r==null){let e=await $t({signal:a.signal});s=e.client,u=e.server,t.debug(`OpenCode server started`,{url:u.url})}else s=r.client,t.debug(`Reusing external OpenCode server`,{url:r.server.url});let l=await s.session.create();if(l.data==null||l.error!=null){let e=l.error==null?`No data returned`:String(l.error);throw Error(`Failed to create session: ${e}`)}let d=l.data.id;t.debug(`Session created`,{sessionId:d});let f=ya({...e,sessionId:d},t),p=v();if(h()){let e=le(),n=xe.createHash(`sha256`).update(f).digest(`hex`),r=B.join(e,`prompt-${d}-${n.slice(0,8)}.txt`);try{await G.mkdir(e,{recursive:!0}),await G.writeFile(r,f,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let m=null,g=null,_=null,y=[],b=[],x=0,S=null,C=null;for(let r=1;r<=3;r++){if(c)return{success:!1,exitCode:130,duration:Date.now()-i,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C};let a=o-(Date.now()-i);if(o>0&&a<=ka&&r>1){t.warning(`Insufficient time remaining for retry`,{remainingMs:a,requiredMs:ka,attempt:r});break}let l=r===1?f:`The previous request was interrupted by a network error (fetch failed). +`}function Ca(e){let t=[`## Prior Session Context`];if(e.recentSessions.length>0){t.push(``),t.push(`### Recent Sessions`),t.push(`| ID | Title | Updated | Messages | Agents |`),t.push(`|----|-------|---------|----------|--------|`);for(let n of e.recentSessions.slice(0,5)){let e=new Date(n.updatedAt).toISOString().split(`T`)[0],r=n.agents.join(`, `)||`N/A`,i=n.title||`Untitled`;t.push(`| ${n.id} | ${i} | ${e} | ${n.messageCount} | ${r} |`)}t.push(``),t.push("Use `session_read` to review any of these sessions in detail.")}if(e.priorWorkContext.length>0){t.push(``),t.push(`### Relevant Prior Work`),t.push(``),t.push(`The following sessions contain content related to this issue:`),t.push(``);for(let n of e.priorWorkContext.slice(0,3)){t.push(`**Session ${n.sessionId}:**`),t.push("```markdown");for(let e of n.matches.slice(0,2))t.push(`- ${e.excerpt}`);t.push("```"),t.push(``)}t.push("Use `session_read` to review full context before starting new investigation.")}return t.push(``),t.join(` +`)}function wa(e){let t=[`## Pull Request Diff Summary`];if(t.push(``),t.push(`- **Changed Files:** ${e.changedFiles}`),t.push(`- **Additions:** +${e.additions}`),t.push(`- **Deletions:** -${e.deletions}`),e.truncated&&t.push(`- **Note:** Diff was truncated due to size limits`),e.files.length>0){t.push(``),t.push(`### Changed Files`),t.push(`| File | Status | +/- |`),t.push(`|------|--------|-----|`);for(let n of e.files.slice(0,20))t.push(`| \`${n.filename}\` | ${n.status} | +${n.additions}/-${n.deletions} |`);e.files.length>20&&t.push(`| ... | | +${e.files.length-20} more files |`)}return t.push(``),t.join(` +`)}function Ta(e){let t=[`## Output Contract`,``];return t.push(`- Review action: approve/request-changes if confident; otherwise comment-only`),t.push(`- Requested reviewer: ${e.isRequestedReviewer?`yes`:`no`}`),e.authorAssociation!=null&&t.push(`- Author association: ${e.authorAssociation}`),t.push(``),t.join(` +`)}function Ea(e,t){t.debug(`Server event`,{eventType:e.type,properties:e.properties})}function Da(e,t,n,r,i){let a=_n(t);if(e.includes(`gh pr create`)){let e=a.filter(e=>e.includes(`/pull/`)&&!e.includes(`#`));for(let t of e)n.includes(t)||n.push(t)}if(e.includes(`git commit`)){let e=vn(t);for(let t of e)r.includes(t)||r.push(t)}(e.includes(`gh issue comment`)||e.includes(`gh pr comment`))&&a.some(e=>e.includes(`#issuecomment`))&&i()}async function Oa(e,t,n,r,i){let a=``,o=null,s=null,c=null,l=[],u=[],d=0,f=null;for await(let p of e){if(n.aborted)break;if(Ea(p,r),p.type===`message.part.updated`){let e=p.properties.part;if(e.sessionID!==t)continue;if(i!=null&&(i.firstMeaningfulEventReceived=!0),e.type===`text`&&`text`in e&&typeof e.text==`string`){a=e.text;let t=`time`in e?e.time?.end:void 0;t!=null&&Number.isFinite(t)&&(on(a),a=``)}else if(e.type===`tool`){let t=e.state;if(t.status===`completed`){let n=e.tool,r=t.input,i=t.title;an(n,i),n.toLowerCase()===`bash`&&Da(String(r.command??r.cmd??``),String(t.output),l,u,()=>{d++})}}}else if(p.type===`message.updated`){let e=p.properties.info;e.sessionID===t&&e.role===`assistant`&&e.tokens!=null&&(i!=null&&(i.firstMeaningfulEventReceived=!0),o={input:e.tokens.input??0,output:e.tokens.output??0,reasoning:e.tokens.reasoning??0,cache:{read:e.tokens.cache?.read??0,write:e.tokens.cache?.write??0}},s=e.modelID??null,c=e.cost??null,r.debug(`Token usage received`,{tokens:o,model:s,cost:c}))}else if(p.type===`session.error`){if(p.properties.sessionID===t){let e=p.properties.error;r.error(`Session error`,{error:e});let t=typeof e==`string`?e:String(e);f=fn(e)?pn(t,s??void 0):mn(t),i!=null&&(i.sessionError=t)}}else p.type===`session.idle`&&p.properties.sessionID===t&&(i!=null&&(i.sessionIdle=!0),a.length>0&&(on(a),a=``))}return a.length>0&&on(a),{tokens:o,model:s,cost:c,prsCreated:l,commitsCreated:u,commentsPosted:d,llmError:f}}async function ka(e,t,n,r,i,a=E,o){let s=Date.now(),c=0;for(;!r.aborted;){if(await en(500),r.aborted)return{completed:!1,error:`Aborted`};if(o?.sessionError==null)c=0;else{if(c++,c>=3)return i.error(`Session error persisted through grace period`,{sessionId:t,error:o.sessionError,graceCycles:c}),{completed:!1,error:`Session error: ${o.sessionError}`};continue}if(o?.sessionIdle===!0)return i.debug(`Session idle detected via event stream`,{sessionId:t}),{completed:!0,error:null};let l=Date.now()-s;if(a>0&&l>=a)return i.warning(`Poll timeout reached`,{elapsedMs:l,maxPollTimeMs:a}),{completed:!1,error:`Poll timeout after ${l}ms`};try{let r=((await e.session.status({query:{directory:n}})).data??{})[t];if(r==null)i.debug(`Session status not found in poll response`,{sessionId:t});else if(r.type===`idle`)return i.debug(`Session idle detected via polling`,{sessionId:t}),{completed:!0,error:null};else i.debug(`Session status`,{sessionId:t,type:r.type});if(o!=null&&!o.firstMeaningfulEventReceived){let e=Date.now()-s;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:N(e)})}}return{completed:!1,error:`Aborted`}}async function Aa(e,t=2e3){await Promise.race([e,new Promise(e=>{setTimeout(e,t)})])}const ja=5e3;function Ma(e){return e==null?!1:Object.values(e.omoProviders).some(e=>e!==`no`)}function Na(e){if(e?.model!=null)return{providerID:e.model.providerID,modelID:e.model.modelID};if(!Ma(e))return{providerID:ne.providerID,modelID:ne.modelID}}async function Pa(e,t,n,r,i,a,o){let s=a?.agent??R,c=new AbortController,l={firstMeaningfulEventReceived:!1,sessionIdle:!1,sessionError:null},u=await e.event.subscribe(),d={tokens:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null},f=Oa(u.stream,t,c.signal,o,l).then(e=>{d=e}).catch(e=>{e instanceof Error&&e.name!==`AbortError`&&o.debug(`Event stream error`,{error:e.message})}),p=async()=>{c.abort(),await Aa(f)},m=[{type:`text`,text:n}];r!=null&&r.length>0&&(m.push(...r),o.info(`Including file attachments in prompt`,{count:r.length}));let h=Na(a),g={parts:m};h!=null&&(g.model=h),s!==R&&(g.agent=s),o.debug(`Sending prompt to OpenCode`,{sessionId:t});try{let n=await e.session.promptAsync({path:{id:t},body:g,query:{directory:i}});if(n.error!=null){o.error(`OpenCode prompt failed`,{error:String(n.error)}),await p();let e=fn(n.error)?pn(String(n.error),d.model??void 0):d.llmError;return{success:!1,error:String(n.error),llmError:e,shouldRetry:e!=null,eventStreamResult:d}}let r=a?.timeoutMs??E,s=await ka(e,t,i,c.signal,o,r,l);if(await p(),!s.completed){let e=s.error??`Session did not reach idle state`;return o.error(`Session completion polling failed`,{error:e,sessionId:t}),{success:!1,error:e,llmError:d.llmError,shouldRetry:d.llmError!=null,eventStreamResult:d}}return{success:!0,error:null,llmError:null,shouldRetry:!1,eventStreamResult:d}}finally{c.abort(),await Aa(f)}}async function Fa(e,t){try{let{client:n,server:r}=await $t({signal:e});return t.debug(`OpenCode server bootstrapped`,{url:r.url}),ha({client:n,server:r,shutdown:()=>{r.close()}})}catch(e){let n=e instanceof Error?e.message:String(e);return t.warning(`Failed to bootstrap OpenCode server`,{error:n}),ga(Error(`Server bootstrap failed: ${n}`))}}async function Ia(e,t,n,r){let i=Date.now(),a=new AbortController,o=n?.timeoutMs??E,s=null,c=!1,l=r==null,u=null;o>0&&(s=setTimeout(()=>{c=!0,t.warning(`Execution timeout reached`,{timeoutMs:o}),a.abort()},o)),t.info(`Executing OpenCode agent (SDK mode)`,{agent:n?.agent??R,hasModelOverride:n?.model!=null,timeoutMs:o});try{let s;if(r==null){let e=await $t({signal:a.signal});s=e.client,u=e.server,t.debug(`OpenCode server started`,{url:u.url})}else s=r.client,t.debug(`Reusing external OpenCode server`,{url:r.server.url});let l=await s.session.create();if(l.data==null||l.error!=null){let e=l.error==null?`No data returned`:String(l.error);throw Error(`Failed to create session: ${e}`)}let d=l.data.id;t.debug(`Session created`,{sessionId:d});let f=xa({...e,sessionId:d},t),p=v();if(h()){let e=le(),n=xe.createHash(`sha256`).update(f).digest(`hex`),r=B.join(e,`prompt-${d}-${n.slice(0,8)}.txt`);try{await G.mkdir(e,{recursive:!0}),await G.writeFile(r,f,`utf8`),t.info(`Prompt artifact written`,{hash:n,path:r})}catch(e){t.warning(`Failed to write prompt artifact`,{error:e instanceof Error?e.message:String(e),path:r})}}let m=null,g=null,_=null,y=[],b=[],x=0,S=null,C=null;for(let r=1;r<=3;r++){if(c)return{success:!1,exitCode:130,duration:Date.now()-i,sessionId:d,error:`Execution timed out after ${o}ms`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C};let a=o-(Date.now()-i);if(o>0&&a<=ja&&r>1){t.warning(`Insufficient time remaining for retry`,{remainingMs:a,requiredMs:ja,attempt:r});break}let l=r===1?f:`The previous request was interrupted by a network error (fetch failed). Please continue where you left off. If you were in the middle of a task, resume it. -If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void 0;t.debug(`Sending prompt`,{attempt:r,isRetry:r>1});try{let e=await Ma(s,d,l,u,p,n,t);if(e.success){let{eventStreamResult:n}=e;m=n.tokens,g=n.model,_=n.cost,y=[...n.prsCreated],b=[...n.commitsCreated],x=n.commentsPosted;let a=Date.now()-i;return t.info(`OpenCode execution completed`,{sessionId:d,durationMs:a,attempts:r}),{success:!0,exitCode:0,duration:a,sessionId:d,error:null,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:null}}if(S=e.error,C=e.llmError,!e.shouldRetry||r>=3){e.shouldRetry&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:e.error});break}t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:e.error,delayMs:ka,sessionId:d}),await en(ka)}catch(e){let n=M(e);t.error(`Prompt attempt failed with exception`,{attempt:r,error:n}),S=n;let i=fn(e)?pn(n):null;if(C=i,i==null||r>=3){i!=null&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:n});break}t.warning(`LLM fetch error detected (exception), retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:n,delayMs:ka,sessionId:d}),await en(ka)}}return{success:!1,exitCode:1,duration:Date.now()-i,sessionId:d,error:S??`Unknown error`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C}}catch(e){let n=Date.now()-i,r=M(e);return t.error(`OpenCode execution failed`,{error:r,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:fn(e)?pn(r):null}}finally{s!=null&&clearTimeout(s),a.abort(),l&&u?.close()}}async function Fa(e,t){let n=e??`opencode`;try{let e=``;await x(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function Ia(e){let{logger:n,opencodeVersion:r}=e,i=H.env.OPENCODE_PATH??null,a=await Fa(i,n);if(a.available&&a.version!=null)return n.info(`OpenCode already available`,{version:a.version}),{path:i??`opencode`,version:a.version,didSetup:!1};n.info(`OpenCode not found, running auto-setup`,{requestedVersion:r});let o=await fa();if(o==null)throw Error(`Auto-setup failed: runSetup returned null`);return t(o.opencodePath),H.env.OPENCODE_PATH=o.opencodePath,n.info(`Auto-setup completed`,{version:o.opencodeVersion,path:o.opencodePath}),{path:o.opencodePath,version:o.opencodeVersion,didSetup:!0}}const La=`agent: working`;async function Ra(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await Ue(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function za(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await Ke(e,t.repo,La,`fcf2e1`,`Agent is currently working on this`,n)&&await qe(e,t.repo,t.issueNumber,[La],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function Ba(e,t,n){await Promise.all([Ra(e,t,n),za(e,t,n)])}async function Va(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await We(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Ge(e,t.repo,t.commentId,r.id,n)}async function Ha(e,t,n,r){t.commentId!=null&&await Ue(e,t.repo,t.commentId,n,r)}async function Ua(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await Va(e,t,n),await Ha(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:M(e)})}}async function Wa(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await Va(e,t,n),await Ha(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:M(e)})}}async function Ga(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Je(e,t.repo,t.issueNumber,La,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function Ka(e,t,n,r){n?await Ua(e,t,r):await Wa(e,t,r),await Ga(e,t,r)}const qa={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 Ja(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function Ya(e){let t=[],n=new Set;return Ja(qa.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Ja(qa.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Ja(qa.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&gn(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),qa.htmlImage.lastIndex=0,t}function Xa(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 Za={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`]},Qa=[`github.com`,`githubusercontent.com`];async function $a(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(!Qa.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=be.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=Xa(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await G.mkdtemp(B.join(Te.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=B.join(p,m);return await G.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:M(t)}),null}}async function eo(e,t,n=Za,r){return Promise.all(e.map(async(e,i)=>$a(e,i,t,n,r)))}async function to(e,t){for(let n of e)try{await G.unlink(n);let e=B.dirname(n);await G.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:M(e)})}}function no(e){return e.map(e=>({type:`file`,mime:e.mime,url:Se(e.tempPath).toString(),filename:e.filename}))}function ro(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 io(e,t,n,r){return{processed:n,skipped:r,modifiedBody:ro(e,t,n),fileParts:no(n),tempFiles:n.map(e=>e.tempPath)}}function ao(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function oo(e,t=Za,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 (${ao(o.sizeBytes)} > ${ao(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 (${ao(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!so(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 so(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}const co=``;function lo(e,t){return t==null?!1:e===t||e===`${t}[bot]`}function uo(e,t,n){return lo(e,n)&&t.includes(co)}async function fo(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:M(e)}),null}}async function po(e,t,n,r){let i=[],a=1;for(;a<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:a});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;i.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:uo(t,e.body??``,n)})}if(r.length<100)break;a++}catch(e){r.warning(`Failed to fetch comments page`,{target:t,page:a,error:M(e)});break}return i}async function mo(e,t,n,r){try{let i=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` +If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void 0;t.debug(`Sending prompt`,{attempt:r,isRetry:r>1});try{let e=await Pa(s,d,l,u,p,n,t);if(e.success){let{eventStreamResult:n}=e;m=n.tokens,g=n.model,_=n.cost,y=[...n.prsCreated],b=[...n.commitsCreated],x=n.commentsPosted;let a=Date.now()-i;return t.info(`OpenCode execution completed`,{sessionId:d,durationMs:a,attempts:r}),{success:!0,exitCode:0,duration:a,sessionId:d,error:null,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:null}}if(S=e.error,C=e.llmError,!e.shouldRetry||r>=3){e.shouldRetry&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:e.error});break}t.warning(`LLM fetch error detected, retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:e.error,delayMs:ja,sessionId:d}),await en(ja)}catch(e){let n=N(e);t.error(`Prompt attempt failed with exception`,{attempt:r,error:n}),S=n;let i=fn(e)?pn(n):null;if(C=i,i==null||r>=3){i!=null&&r>=3&&t.warning(`LLM fetch error: max retries exhausted`,{attempts:r,error:n});break}t.warning(`LLM fetch error detected (exception), retrying with continuation prompt`,{attempt:r,maxAttempts:3,error:n,delayMs:ja,sessionId:d}),await en(ja)}}return{success:!1,exitCode:1,duration:Date.now()-i,sessionId:d,error:S??`Unknown error`,tokenUsage:m,model:g,cost:_,prsCreated:y,commitsCreated:b,commentsPosted:x,llmError:C}}catch(e){let n=Date.now()-i,r=N(e);return t.error(`OpenCode execution failed`,{error:r,durationMs:n}),{success:!1,exitCode:1,duration:n,sessionId:null,error:r,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:fn(e)?pn(r):null}}finally{s!=null&&clearTimeout(s),a.abort(),l&&u?.close()}}async function La(e,t){let n=e??`opencode`;try{let e=``;await x(n,[`--version`],{listeners:{stdout:t=>{e+=t.toString()}},silent:!0});let r=/(\d+\.\d+\.\d+)/.exec(e)?.[1]??null;return t.debug(`OpenCode version verified`,{version:r}),{available:!0,version:r}}catch{return t.debug(`OpenCode not available, will attempt auto-setup`),{available:!1,version:null}}}async function Ra(e){let{logger:n,opencodeVersion:r}=e,i=H.env.OPENCODE_PATH??null,a=await La(i,n);if(a.available&&a.version!=null)return n.info(`OpenCode already available`,{version:a.version}),{path:i??`opencode`,version:a.version,didSetup:!1};n.info(`OpenCode not found, running auto-setup`,{requestedVersion:r});let o=await ma();if(o==null)throw Error(`Auto-setup failed: runSetup returned null`);return t(o.opencodePath),H.env.OPENCODE_PATH=o.opencodePath,n.info(`Auto-setup completed`,{version:o.opencodeVersion,path:o.opencodePath}),{path:o.opencodePath,version:o.opencodeVersion,didSetup:!0}}const za=`agent: working`;async function Ba(e,t,n){return t.commentId==null?(n.debug(`No comment ID, skipping eyes reaction`),!1):await Ue(e,t.repo,t.commentId,`eyes`,n)==null?!1:(n.info(`Added eyes reaction`,{commentId:t.commentId}),!0)}async function Va(e,t,n){return t.issueNumber==null?(n.debug(`No issue number, skipping working label`),!1):await Ke(e,t.repo,za,`fcf2e1`,`Agent is currently working on this`,n)&&await qe(e,t.repo,t.issueNumber,[za],n)?(n.info(`Added working label`,{issueNumber:t.issueNumber}),!0):!1}async function Ha(e,t,n){await Promise.all([Ba(e,t,n),Va(e,t,n)])}async function Ua(e,t,n){if(t.commentId==null||t.botLogin==null)return;let r=(await We(e,t.repo,t.commentId,n)).find(e=>e.content===`eyes`&&e.userLogin===t.botLogin);r!=null&&await Ge(e,t.repo,t.commentId,r.id,n)}async function Wa(e,t,n,r){t.commentId!=null&&await Ue(e,t.repo,t.commentId,n,r)}async function Ga(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await Ua(e,t,n),await Wa(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:N(e)})}}async function Ka(e,t,n){if(t.commentId==null||t.botLogin==null){n.debug(`Missing comment ID or bot login, skipping reaction update`);return}try{await Ua(e,t,n),await Wa(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:N(e)})}}async function qa(e,t,n){if(t.issueNumber==null){n.debug(`No issue number, skipping label removal`);return}await Je(e,t.repo,t.issueNumber,za,n)&&n.info(`Removed working label`,{issueNumber:t.issueNumber})}async function Ja(e,t,n,r){n?await Ga(e,t,r):await Ka(e,t,r),await qa(e,t,r)}const Ya={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 Xa(e,t,n){e.lastIndex=0;let r=e.exec(t);for(;r!=null;)n(r),r=e.exec(t);e.lastIndex=0}function Za(e){let t=[],n=new Set;return Xa(Ya.markdownImage,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`image`}))}),Xa(Ya.markdownLink,e,e=>{let r=e[2],i=e[1],a=e[0];r!=null&&i!=null&&!n.has(r)&&gn(r)&&(n.add(r),t.push({url:r,originalMarkdown:a,altText:i,type:`file`}))}),Xa(Ya.htmlImage,e,e=>{let r=e[1],i=e[0];if(r!=null&&!n.has(r)&&gn(r)){n.add(r);let e=/alt=["']([^"']*)["']/i.exec(i);t.push({url:r,originalMarkdown:i,altText:e?.[1]??``,type:`image`})}}),Ya.htmlImage.lastIndex=0,t}function Qa(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 $a={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`]},eo=[`github.com`,`githubusercontent.com`];async function to(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(!eo.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=be.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=Qa(e.url,e.altText,t),d=l.split(`;`)[0],f=d==null?`application/octet-stream`:d.trim(),p=await G.mkdtemp(B.join(Te.tmpdir(),`fro-bot-attachments-`)),m=u.trim().length>0?u:`attachment_${t+1}`,h=B.join(p,m);return await G.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:N(t)}),null}}async function no(e,t,n=$a,r){return Promise.all(e.map(async(e,i)=>to(e,i,t,n,r)))}async function ro(e,t){for(let n of e)try{await G.unlink(n);let e=B.dirname(n);await G.rmdir(e).catch(()=>{})}catch(e){t.debug(`Failed to cleanup temp file`,{path:n,error:N(e)})}}function io(e){return e.map(e=>({type:`file`,mime:e.mime,url:Se(e.tempPath).toString(),filename:e.filename}))}function ao(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 oo(e,t,n,r){return{processed:n,skipped:r,modifiedBody:ao(e,t,n),fileParts:io(n),tempFiles:n.map(e=>e.tempPath)}}function so(e){if(e<0||!Number.isFinite(e))throw Error(`Invalid bytes value: ${e}`);return e<1024?`${e}B`:e<1024*1024?`${(e/1024).toFixed(1)}KB`:`${(e/(1024*1024)).toFixed(1)}MB`}function co(e,t=$a,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 (${so(o.sizeBytes)} > ${so(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 (${so(t.maxTotalSizeBytes)})`}),n.debug(`Attachment skipped: total size exceeded`,{url:o.url});continue}if(!lo(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 lo(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}const uo=``;function fo(e,t){return t==null?!1:e===t||e===`${t}[bot]`}function po(e,t,n){return fo(e,n)&&t.includes(uo)}async function mo(e,t,n){try{if(t.type===`pr`){let{data:n}=await e.rest.pulls.get({owner:t.owner,repo:t.repo,pull_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}let{data:n}=await e.rest.issues.get({owner:t.owner,repo:t.repo,issue_number:t.number});return{title:n.title,body:n.body??``,author:n.user?.login??`unknown`}}catch(e){return n.warning(`Failed to fetch issue/PR`,{target:t,error:N(e)}),null}}async function ho(e,t,n,r){let i=[],a=1;for(;a<=50;)try{let{data:r}=await e.rest.issues.listComments({owner:t.owner,repo:t.repo,issue_number:t.number,per_page:100,page:a});if(r.length===0)break;for(let e of r){let t=e.user?.login??`unknown`;i.push({id:e.id,body:e.body??``,author:t,authorAssociation:e.author_association??`NONE`,createdAt:e.created_at,updatedAt:e.updated_at,isBot:po(t,e.body??``,n)})}if(r.length<100)break;a++}catch(e){r.warning(`Failed to fetch comments page`,{target:t,page:a,error:N(e)});break}return i}async function go(e,t,n,r){try{let i=[],a=null,o=null,s=``,c=``,l=`unknown`,u=0;for(;u<50;){let d=(await e.graphql(` query GetDiscussion($owner: String!, $repo: String!, $number: Int!, $after: String) { repository(owner: $owner, name: $repo) { discussion(number: $number) { @@ -280,7 +280,7 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void } } } -`,{owner:t.owner,repo:t.repo,number:t.number,after:a})).repository.discussion;if(d==null)return r.debug(`Discussion not found`,{target:t}),null;u===0&&(o=d.id,s=d.title,c=d.body,l=d.author?.login??`unknown`);for(let e of d.comments.nodes){let t=e.author?.login??`unknown`;i.push({id:e.id,body:e.body,author:t,authorAssociation:`NONE`,createdAt:e.createdAt,updatedAt:e.updatedAt,isBot:uo(t,e.body,n)})}if(!d.comments.pageInfo.hasNextPage)break;a=d.comments.pageInfo.endCursor,u++}return{type:`discussion`,number:t.number,title:s,body:c,author:l,comments:i,discussionId:o??void 0}}catch(e){return r.warning(`Failed to fetch discussion`,{target:t,error:M(e)}),null}}async function ho(e,t,n,r){if(t.type===`discussion`)return mo(e,t,n,r);let i=await fo(e,t,r);if(i==null)return null;let a=await po(e,t,n,r);return{type:t.type,number:t.number,title:i.title,body:i.body,author:i.author,comments:a}}function go(e,t){let n=e.comments.filter(e=>lo(e.author,t)&&e.body.includes(co));return n.length===0?null:n.at(-1)??null}async function _o(e,t,n,r){try{let{data:i}=await e.rest.issues.createComment({owner:t.owner,repo:t.repo,issue_number:t.number,body:n});return r.debug(`Created issue comment`,{commentId:i.id,target:t}),{commentId:i.id,created:!0,updated:!1,url:i.html_url}}catch(e){return r.warning(`Failed to create issue comment`,{target:t,error:M(e)}),null}}async function vo(e,t,n,r,i){try{let{data:a}=await e.rest.issues.updateComment({owner:t.owner,repo:t.repo,comment_id:n,body:r});return i.debug(`Updated issue comment`,{commentId:a.id,target:t}),{commentId:a.id,created:!1,updated:!0,url:a.html_url}}catch(e){return i.warning(`Failed to update issue comment`,{target:t,commentId:n,error:M(e)}),null}}async function yo(e,t,n,r){try{let i=(await e.graphql(` +`,{owner:t.owner,repo:t.repo,number:t.number,after:a})).repository.discussion;if(d==null)return r.debug(`Discussion not found`,{target:t}),null;u===0&&(o=d.id,s=d.title,c=d.body,l=d.author?.login??`unknown`);for(let e of d.comments.nodes){let t=e.author?.login??`unknown`;i.push({id:e.id,body:e.body,author:t,authorAssociation:`NONE`,createdAt:e.createdAt,updatedAt:e.updatedAt,isBot:po(t,e.body,n)})}if(!d.comments.pageInfo.hasNextPage)break;a=d.comments.pageInfo.endCursor,u++}return{type:`discussion`,number:t.number,title:s,body:c,author:l,comments:i,discussionId:o??void 0}}catch(e){return r.warning(`Failed to fetch discussion`,{target:t,error:N(e)}),null}}async function _o(e,t,n,r){if(t.type===`discussion`)return go(e,t,n,r);let i=await mo(e,t,r);if(i==null)return null;let a=await ho(e,t,n,r);return{type:t.type,number:t.number,title:i.title,body:i.body,author:i.author,comments:a}}function vo(e,t){let n=e.comments.filter(e=>fo(e.author,t)&&e.body.includes(uo));return n.length===0?null:n.at(-1)??null}async function yo(e,t,n,r){try{let{data:i}=await e.rest.issues.createComment({owner:t.owner,repo:t.repo,issue_number:t.number,body:n});return r.debug(`Created issue comment`,{commentId:i.id,target:t}),{commentId:i.id,created:!0,updated:!1,url:i.html_url}}catch(e){return r.warning(`Failed to create issue comment`,{target:t,error:N(e)}),null}}async function bo(e,t,n,r,i){try{let{data:a}=await e.rest.issues.updateComment({owner:t.owner,repo:t.repo,comment_id:n,body:r});return i.debug(`Updated issue comment`,{commentId:a.id,target:t}),{commentId:a.id,created:!1,updated:!0,url:a.html_url}}catch(e){return i.warning(`Failed to update issue comment`,{target:t,commentId:n,error:N(e)}),null}}async function xo(e,t,n,r){try{let i=(await e.graphql(` query GetDiscussionId($owner: String!, $repo: String!, $number: Int!) { repository(owner: $owner, name: $repo) { discussion(number: $number) { @@ -301,7 +301,7 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void } } } -`,{owner:t.owner,repo:t.repo,number:t.number})).repository.discussion;if(i==null)return r.warning(`Discussion not found`,{target:t}),null;if(n.updateExisting===!0&&n.botLogin!=null){let i=await ho(e,t,n.botLogin,r);if(i!=null){let t=go(i,n.botLogin);if(t!=null&&typeof t.id==`string`){let i=await e.graphql(` +`,{owner:t.owner,repo:t.repo,number:t.number})).repository.discussion;if(i==null)return r.warning(`Discussion not found`,{target:t}),null;if(n.updateExisting===!0&&n.botLogin!=null){let i=await _o(e,t,n.botLogin,r);if(i!=null){let t=vo(i,n.botLogin);if(t!=null&&typeof t.id==`string`){let i=await e.graphql(` mutation UpdateDiscussionComment($commentId: ID!, $body: String!) { updateDiscussionComment(input: {commentId: $commentId, body: $body}) { comment { id url } @@ -313,6 +313,6 @@ If you had completed the task, confirm the completion.`,u=r===1?e.fileParts:void comment { id url } } } -`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:M(e)}),null}}async function bo(e,t,n,r){if(t.type===`discussion`)return yo(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await ho(e,t,n.botLogin,r);if(i!=null){let a=go(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return vo(e,t,a.id,n.body,r)}}return _o(e,t,n.body,r)}function xo(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function So(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function Co(e){let t=ci,n=xo(t.eventName),r=So(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function wo(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function To(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function Eo(e){let t=e.trim(),n=t.indexOf(`/`);if(n===-1)throw Error(`Invalid model format: "${e}". Expected "provider/model" (e.g., "anthropic/claude-sonnet-4-20250514")`);let r=t.slice(0,n).trim(),i=t.slice(n+1).trim();if(r.length===0)throw Error(`Invalid model format: "${e}". Provider cannot be empty.`);if(i.length===0)throw Error(`Invalid model format: "${e}". Model ID cannot be empty.`);return{providerID:r,modelID:i}}function Do(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Oo=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function ko(e){let t=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),n=`no`,r=`no`,i=`no`,a=`no`,o=`no`,s=`no`,c=`no`;for(let e of t){if(!Oo.includes(e))throw Error(`Invalid omo-providers value: "${e}". Valid values: ${Oo.join(`, `)}`);switch(e){case`claude`:n=`yes`;break;case`claude-max20`:n=`max20`;break;case`copilot`:r=`yes`;break;case`gemini`:i=`yes`;break;case`openai`:a=`yes`;break;case`opencode-zen`:o=`yes`;break;case`zai-coding-plan`:s=`yes`;break;case`kimi-for-coding`:c=`yes`;break}}return{claude:n,copilot:r,gemini:i,openai:a,opencodeZen:o,zaiCodingPlan:s,kimiForCoding:c}}function Ao(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return ma(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return ma(Error(`auth-json is required but was not provided`));wo(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?To(i,`session-retention`):O,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:R,p=m(`model`).trim(),h=p.length>0?Eo(p):null,g=m(`timeout`).trim(),_=g.length>0?Do(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:k,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:P,C=m(`omo-providers`).trim(),w=ko(C.length>0?C:oe),T=m(`opencode-config`).trim(),ee=T.length>0?T:null;return ee!=null&&wo(ee,`opencode-config`),pa({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:w,opencodeConfig:ee})}catch(e){return ma(e instanceof Error?e:Error(String(e)))}}function jo(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Mo(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function No(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(F.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,jo(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Mo(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(F.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&F.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&F.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(F.addHeading(`Token Usage`,3),F.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&F.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&F.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(F.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&F.addList([...c.prsCreated]),c.commitsCreated.length>0&&F.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&F.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){F.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;F.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await F.write(),t.debug(`Wrote job summary`)}catch(e){let r=M(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Po(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function Fo(e){z(`session-id`,e.sessionId??``),z(`cache-status`,e.cacheStatus),z(`duration`,e.duration)}function Io(e){let t=B.resolve(e);return t.endsWith(B.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function Lo(e){return typeof e==`boolean`?e:null}function Ro(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function zo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Ro(e.diffs)}}function Bo(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function Vo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Ho(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:Vo(e.time),summary:zo(e.summary),share:Bo(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Uo(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Ro(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Wo(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:Lo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function Go(e){return Z(e)?Q(e.role)===`assistant`?Wo(e):Uo(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Ko(e){let t=Go(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(Yo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function qo(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Jo(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function Yo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=qo(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:Lo(e.synthetic)??void 0,ignored:Lo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Jo(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Xo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Ho):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function Zo(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Ko)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function Qo(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Ho);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function $o(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function es(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function ts(e,t,n){let r=Io(t),i=await es(e,n);for(let e of i){if(Io(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Io(t)===r)return e}return null}async function ns(e,t,n){return Xo(e,t,n)}async function rs(e,t,n){return Zo(e,t,n)}async function is(e,t,n){return $o(e,t,n)}async function as(e,t,n,r){return Qo(e,t,n,r)}const os={maxSessions:50,maxAgeDays:30};async function ss(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await ts(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await ns(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await is(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:M(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function cs(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await ns(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await rs(e,t.id,r),i=ls(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ls(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function us(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ds(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await cs(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ds(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ds(e,t,n,r,i){let a=await rs(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=fs(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function fs(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function ps(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` -`)}async function ms(e,t,n,r){let i=ps(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:i}]}});if(t.error!=null){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}r.info(`Session summary written via SDK`,{sessionId:e})}catch(t){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:M(t)})}}const hs=/^[0-9a-f]{40}$/i;function gs(){return{exec:x,getExecOutput:c}}async function _s(e){let{workspacePath:t,logger:n,execAdapter:r=gs()}=e,i=B.join(t,`.git`),a=B.join(i,`opencode`);try{let e=(await G.readFile(a,`utf8`)).trim();if(e.length>0){if(hs.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:M(e)})}try{if((await G.stat(i)).isDirectory()===!1){let e=await G.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=B.resolve(t,n[1]),a=B.join(i,`opencode`)}}catch{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 G.writeFile(a,s,`utf8`),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){n.warning(`Failed to cache project ID (continuing)`,{error:M(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:M(e)}}}const vs={botLogin:null,requireMention:!0,allowedAssociations:ha,skipDraftPRs:!0,promptInput:null};function ys(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${bs(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function bs(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function xs(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${bs(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function Ss(e,t){return t.includes(e)}function Cs(e){return e.endsWith(`[bot]`)}function ws(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=ys(e,t);return{hasMention:n,command:n?xs(e,t):null}}function Ts(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Cs(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},i=e.comment.body,a=e.comment.id,{hasMention:o,command:s}=ws(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Es(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Cs(e.comment.author)},r={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:e.comment.body??e.discussion.body??null,locked:e.discussion.locked},i=e.comment.body??null,a=e.comment.id,{hasMention:o,command:s}=ws(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Ds(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Os(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:Cs(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=ws(e.issue.body??``,t);return{author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,action:e.action}}const ks=[`opened`,`edited`];function As(e){return ks.includes(e)}function js(e,t,n){let r=e.action;return r==null||!As(r)?(n.debug(`Skipping unsupported issues action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${r}' is not supported (only 'opened' and 'edited')`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):r===`edited`&&!e.hasMention?(n.debug(`Skipping issues.edited without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}):e.target?.locked===!0?(n.debug(`Skipping locked issue`),{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}):{shouldSkip:!1}}function Ms(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:Cs(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft},{hasMention:i,command:a}=ws(e.pullRequest.body??``,t);return{author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,action:e.action}}const Ns=[`opened`,`synchronize`,`reopened`];function Ps(e){return Ns.includes(e)}function Fs(e,t,n){let r=e.action;return r==null||!Ps(r)?(n.debug(`Skipping unsupported pull_request action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${r}' is not supported`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.skipDraftPRs&&e.target?.isDraft===!0?(n.debug(`Skipping draft PR`),{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}):e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):{shouldSkip:!1}}function Is(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Cs(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=ws(e.comment.body,t);return{author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,action:e.action}}function Ls(e,t,n){let r=n?.trim()??``;return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Rs(e,t){return(e.promptInput?.trim()??``)===``?(t.debug(`Skipping schedule event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}):{shouldSkip:!1}}function zs(e,t){return(e.commentBody?.trim()??``)===``?(t.debug(`Skipping workflow_dispatch event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}):{shouldSkip:!1}}function Bs(e,t,n,r){let{targetLabel:i,actionLabel:a}=r;return e.action===`created`?e.target?.locked===!0?(n.debug(`Skipping locked ${i}`),{shouldSkip:!0,reason:`issue_locked`,message:`${i} is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping ${a} without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created ${a} action`,{action:e.action}),{shouldSkip:!0,reason:`action_not_created`,message:`${a} action is '${e.action}', not 'created'`})}function Vs(e,t,n){return Bs(e,t,n,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function Hs(e,t,n){return Bs(e,t,n,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}function Us(e,t,n){let r=e.action;return r===`created`?e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!Ss(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping review comment without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created review comment action`,{action:r}),{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${r}' is not supported (only 'created')`})}function Ws(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e.eventName}`};switch(e.eventType){case`issue_comment`:return Vs(e,t,n);case`discussion_comment`:return Hs(e,t,n);case`issues`:return js(e,t,n);case`pull_request`:return Fs(e,t,n);case`pull_request_review_comment`:return Us(e,t,n);case`schedule`:return Rs(t,n);case`workflow_dispatch`:return zs(e,n);default:return{shouldSkip:!1}}}function Gs(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:{let n=Ts(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`discussion_comment`:{let n=Es(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`workflow_dispatch`:{let t=Ds(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`issues`:{let n=Os(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request`:{let n=Ms(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request_review_comment`:{let n=Is(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`schedule`:{let t=Ls(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null}}}function Ks(e,t,n={}){let r={...vs,...n},i=Gs(e,r.botLogin,r.promptInput);t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Ws(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function qs(){let e=Date.now(),t=A({phase:`bootstrap`}),n=null,i=!1,o=0,s=null,c=null,l=null,u=null,d=Po();d.start(),f(L.SHOULD_SAVE_CACHE,`false`),f(L.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let p=Ao();if(!p.success)return _(`Invalid inputs: ${p.error.message}`),1;let m=p.data,h=A({phase:`main`});h.info(`Action inputs parsed`,{sessionRetention:m.sessionRetention,s3Backup:m.s3Backup,hasGithubToken:m.githubToken.length>0,hasPrompt:m.prompt!=null,agent:m.agent,hasModelOverride:m.model!=null,timeoutMs:m.timeoutMs});let g=await Ia({logger:h,opencodeVersion:m.opencodeVersion});g.didSetup?h.info(`OpenCode auto-setup completed`,{version:g.version}):h.info(`OpenCode already available`,{version:g.version}),f(L.OPENCODE_VERSION,g.version),l=g.version;let b=A({phase:`context`}),x=Co(b);s=Bi({token:m.githubToken,logger:b});let S=await Vi(s,b),C=A({phase:`trigger`}),w=Ks(x,C,{botLogin:S,requireMention:!0,promptInput:m.prompt});if(!w.shouldProcess)return C.info(`Skipping event`,{reason:w.skipReason,message:w.skipMessage}),Fo({sessionId:null,cacheStatus:`miss`,duration:Date.now()-e}),0;C.info(`Event routed for processing`,{eventType:w.context.eventType,hasMention:w.context.hasMention,command:w.context.command?.action??null}),f(L.SHOULD_SAVE_CACHE,`true`);let T=await et({logger:b,octokit:s,triggerContext:w.context,botLogin:S});n={repo:T.repo,commentId:T.commentId,issueNumber:T.issueNumber,issueType:T.issueType,botLogin:S};let E=A({phase:`acknowledgment`});await Ba(s,n,E);let ee={agentIdentity:`github`,repo:te(),ref:de(),os:a()},D=A({phase:`cache`}),ne=v(),re=B.join(ne,`.git`,`opencode`),O=await ie({components:ee,logger:D,storagePath:y(),authPath:r(),projectIdPath:re,opencodeVersion:g.version}),k=O.corrupted?`corrupted`:O.hit?`hit`:`miss`;d.setCacheStatus(k),h.info(`Cache restore completed`,{cacheStatus:k,key:O.key});let j=await _s({workspacePath:ne,logger:D});j.source===`error`?D.warning(`Failed to generate project ID (continuing)`,{error:j.error}):D.debug(`Project ID ready`,{projectId:j.projectId,source:j.source});let M=A({phase:`server-bootstrap`}),N=await Na(new AbortController().signal,M);if(!N.success)return _(`OpenCode server bootstrap failed: ${N.error.message}`),1;u=N.data,M.info(`SDK server bootstrapped successfully`);let P=A({phase:`session`}),ae=Io(ne),oe=await cs(u.client,ae,{limit:10},P);P.debug(`Listed recent sessions`,{count:oe.length});let F=T.issueTitle??T.repo,I=await us(F,u.client,ae,{limit:5},P);P.debug(`Searched prior sessions`,{query:F,resultCount:I.length});for(let e of I)d.addSessionUsed(e.sessionId);let se=A({phase:`attachments`}),R=T.commentBody??``,ce=Ya(R);if(ce.length>0){se.info(`Processing attachments`,{count:ce.length});let{validated:e,skipped:t}=oo(await eo(ce,m.githubToken,void 0,se),void 0,se);(e.length>0||t.length>0)&&(c=io(R,ce,e,t),se.info(`Attachments processed`,{processed:e.length,skipped:t.length}))}let le={context:T,customPrompt:m.prompt,cacheStatus:k,sessionContext:{recentSessions:oe,priorWorkContext:I},triggerContext:w.context,fileParts:c?.fileParts},ue=H.env.SKIP_AGENT_EXECUTION===`true`,z,fe=Date.now();if(ue)h.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),z={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let e=await Pa(le,A({phase:`execution`}),{agent:m.agent,model:m.model,timeoutMs:m.timeoutMs,omoProviders:m.omoProviders},u??void 0),t=e.sessionId;if(t==null){let e=await as(u.client,ae,fe,P);e!=null&&(t=e.session.id,P.debug(`Identified session from execution`,{sessionId:t}))}z={...e,sessionId:t}}z.sessionId!=null&&f(L.SESSION_ID,z.sessionId),i=z.success,z.sessionId!=null&&d.addSessionCreated(z.sessionId),z.tokenUsage!=null&&d.setTokenUsage(z.tokenUsage,z.model,z.cost);for(let e of z.prsCreated)d.addPRCreated(e);for(let e of z.commitsCreated)d.addCommitCreated(e);for(let e=0;e0&&n.owner.length>0&&n.repo.length>0){let e=ln(z.llmError),t=A({phase:`error-comment`}),r=await bo(s,n,{body:e},t);r==null?t.warning(`Failed to post LLM error comment`):(t.info(`Posted LLM error comment`,{commentUrl:r.url}),d.incrementComments())}else h.warning(`Cannot post error comment: missing target context`);o=0}}catch(n){o=1;let r=Date.now()-e,i=n instanceof Error?n.name:`UnknownError`,a=n instanceof Error?n.message:String(n);d.recordError(i,a,!1),d.end(),Fo({sessionId:null,cacheStatus:`miss`,duration:r}),n instanceof Error?(t.error(`Agent failed`,{error:n.message}),_(n.message)):(t.error(`Agent failed with unknown error`),_(`An unknown error occurred`))}finally{try{if(c!=null){let e=A({phase:`attachment-cleanup`});await to(c.tempFiles,e)}if(n!=null&&s!=null){let e=A({phase:`cleanup`});await Ka(s,n,i,e)}let e=A({phase:`prune`}),t=v();if(u!=null){let n=Io(t),r=await ss(u.client,n,os,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let o={agentIdentity:`github`,repo:te(),ref:de(),os:a()},d=A({phase:`cache-save`}),p=B.join(t,`.git`,`opencode`);await I({components:o,runId:ue(),logger:d,storagePath:y(),authPath:r(),projectIdPath:p,opencodeVersion:l})&&f(L.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(u!=null)try{u.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}return o}await qs().then(e=>{H.exit(e)});export{}; \ No newline at end of file +`,{discussionId:i.id,body:n.body});return r.debug(`Created discussion comment`,{discussionId:i.id}),{commentId:a.addDiscussionComment.comment.id,created:!0,updated:!1,url:a.addDiscussionComment.comment.url}}catch(e){return r.warning(`Failed to post discussion comment`,{target:t,error:N(e)}),null}}async function So(e,t,n,r){if(t.type===`discussion`)return xo(e,t,n,r);if(n.updateExisting===!0&&n.botLogin!=null){let i=await _o(e,t,n.botLogin,r);if(i!=null){let a=vo(i,n.botLogin);if(a!=null&&typeof a.id==`number`)return bo(e,t,a.id,n.body,r)}}return yo(e,t,n.body,r)}function Co(e){switch(e){case`issue_comment`:return`issue_comment`;case`discussion`:case`discussion_comment`:return`discussion_comment`;case`workflow_dispatch`:return`workflow_dispatch`;case`issues`:return`issues`;case`pull_request`:return`pull_request`;case`pull_request_review_comment`:return`pull_request_review_comment`;case`schedule`:return`schedule`;default:return`unsupported`}}function wo(e,t){switch(e){case`issue_comment`:{let e=t;return{type:`issue_comment`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,isPullRequest:e.issue.pull_request!=null},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`discussion_comment`:{let e=t;return{type:`discussion_comment`,action:e.action,discussion:{number:e.discussion.number,title:e.discussion.title,body:e.discussion.body??null,locked:e.discussion.locked??!1},comment:{id:e.comment.id,body:e.comment.body??null,author:e.comment.user.login,authorAssociation:e.comment.author_association??`NONE`}}}case`issues`:{let e=t;return{type:`issues`,action:e.action,issue:{number:e.issue.number,title:e.issue.title,body:e.issue.body??null,locked:e.issue.locked??!1,authorAssociation:e.issue.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request`:{let e=t;return{type:`pull_request`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,body:e.pull_request.body??null,locked:e.pull_request.locked??!1,draft:e.pull_request.draft??!1,authorAssociation:e.pull_request.author_association??`NONE`},sender:{login:e.sender.login}}}case`pull_request_review_comment`:{let e=t;return{type:`pull_request_review_comment`,action:e.action,pullRequest:{number:e.pull_request.number,title:e.pull_request.title,locked:e.pull_request.locked??!1},comment:{id:e.comment.id,body:e.comment.body,author:e.comment.user.login,authorAssociation:e.comment.author_association,path:e.comment.path,line:e.comment.line??null,diffHunk:e.comment.diff_hunk,commitId:e.comment.commit_id}}}case`workflow_dispatch`:return{type:`workflow_dispatch`,inputs:{prompt:t.inputs?.prompt??void 0}};case`schedule`:return{type:`schedule`,schedule:t.schedule??void 0};case`unsupported`:return{type:`unsupported`}}}function To(e){let t=ci,n=Co(t.eventName),r=wo(n,t.payload);return e.debug(`Parsed GitHub context`,{eventName:t.eventName,eventType:n,repo:`${t.repo.owner}/${t.repo.repo}`}),{eventName:t.eventName,eventType:n,repo:t.repo,ref:t.ref,sha:t.sha,runId:t.runId,actor:t.actor,payload:t.payload,event:r}}function Eo(e,t){try{JSON.parse(e)}catch{throw Error(`${t} must be valid JSON`)}}function Do(e,t){let n=e.trim();if(!/^\d+$/.test(n))throw Error(`${t} must be a positive integer, received: ${e}`);let r=Number.parseInt(n,10);if(r===0)throw Error(`${t} must be a positive integer, received: ${e}`);return r}function Oo(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 ko(e){let t=e.trim();if(!/^\d+$/.test(t))throw Error(`timeout must be a non-negative integer, received: ${e}`);let n=Number.parseInt(t,10);if(Number.isNaN(n)||n<0)throw Error(`timeout must be a non-negative integer, received: ${e}`);return n}const Ao=[`claude`,`claude-max20`,`copilot`,`gemini`,`openai`,`opencode-zen`,`zai-coding-plan`,`kimi-for-coding`];function jo(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(!Ao.includes(e))throw Error(`Invalid omo-providers value: "${e}". Valid values: ${Ao.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 Mo(){try{let e=m(`github-token`,{required:!0}).trim();if(e.length===0)return ga(Error(`github-token is required but was not provided`));let t=m(`auth-json`,{required:!0}).trim();if(t.length===0)return ga(Error(`auth-json is required but was not provided`));Eo(t,`auth-json`);let n=m(`prompt`).trim(),r=n.length>0?n:null,i=m(`session-retention`).trim(),a=i.length>0?Do(i,`session-retention`):k,o=m(`s3-backup`).trim().toLowerCase()===`true`,s=m(`s3-bucket`).trim(),c=s.length>0?s:null,l=m(`aws-region`).trim(),u=l.length>0?l:null,d=m(`agent`).trim(),f=d.length>0?d:R,p=m(`model`).trim(),h=p.length>0?Oo(p):null,g=m(`timeout`).trim(),_=g.length>0?ko(g):E,v=m(`opencode-version`).trim(),y=v.length>0?v:A,b=m(`skip-cache`).trim().toLowerCase()===`true`,x=m(`omo-version`).trim(),S=x.length>0?x:P,C=m(`omo-providers`).trim(),w=jo(C.length>0?C:oe),T=m(`opencode-config`).trim(),D=T.length>0?T:null;if(D!=null){Eo(D,`opencode-config`);let e=JSON.parse(D);if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Input 'opencode-config' must be a JSON object`)}return ha({githubToken:e,authJson:t,prompt:r,sessionRetention:a,s3Backup:o,s3Bucket:c,awsRegion:u,agent:f,model:h,timeoutMs:_,opencodeVersion:y,skipCache:b,omoVersion:S,omoProviders:w,opencodeConfig:D})}catch(e){return ga(e instanceof Error?e:Error(String(e)))}}function No(e){switch(e){case`hit`:return`✅ hit`;case`miss`:return`🆕 miss`;case`corrupted`:return`⚠️ corrupted (clean start)`}}function Po(e){let t=Math.round(e/1e3);return t<60?`${t}s`:`${Math.floor(t/60)}m ${t%60}s`}async function Fo(e,t){let{eventType:r,repo:i,ref:a,runId:o,runUrl:s,metrics:c,agent:l}=e;try{if(F.addHeading(`Fro Bot Agent Run`,2).addTable([[{data:`Field`,header:!0},{data:`Value`,header:!0}],[`Event`,r],[`Repository`,i],[`Ref`,a],[`Run ID`,`[${o}](${s})`],[`Agent`,l],[`Cache Status`,No(c.cacheStatus)],[`Duration`,c.duration==null?`N/A`:Po(c.duration)]]),(c.sessionsUsed.length>0||c.sessionsCreated.length>0)&&(F.addHeading(`Sessions`,3),c.sessionsUsed.length>0&&F.addRaw(`**Used:** ${c.sessionsUsed.join(`, `)}\n`),c.sessionsCreated.length>0&&F.addRaw(`**Created:** ${c.sessionsCreated.join(`, `)}\n`)),c.tokenUsage!=null&&(F.addHeading(`Token Usage`,3),F.addTable([[{data:`Metric`,header:!0},{data:`Count`,header:!0}],[`Input`,c.tokenUsage.input.toLocaleString()],[`Output`,c.tokenUsage.output.toLocaleString()],[`Reasoning`,c.tokenUsage.reasoning.toLocaleString()],[`Cache Read`,c.tokenUsage.cache.read.toLocaleString()],[`Cache Write`,c.tokenUsage.cache.write.toLocaleString()]]),c.model!=null&&F.addRaw(`**Model:** ${c.model}\n`),c.cost!=null&&F.addRaw(`**Cost:** $${c.cost.toFixed(4)}\n`)),(c.prsCreated.length>0||c.commitsCreated.length>0||c.commentsPosted>0)&&(F.addHeading(`Created Artifacts`,3),c.prsCreated.length>0&&F.addList([...c.prsCreated]),c.commitsCreated.length>0&&F.addList(c.commitsCreated.map(e=>`Commit \`${e.slice(0,7)}\``)),c.commentsPosted>0&&F.addRaw(`**Comments Posted:** ${c.commentsPosted}\n`)),c.errors.length>0){F.addHeading(`Errors`,3);for(let e of c.errors){let t=e.recoverable?`🔄 Recovered`:`❌ Failed`;F.addRaw(`- **${e.type}** (${t}): ${e.message}\n`)}}await F.write(),t.debug(`Wrote job summary`)}catch(e){let r=N(e);t.warning(`Failed to write job summary`,{error:r}),n(`Failed to write job summary: ${r}`)}}function Io(){let e=0,t=null,n=`miss`,r=[],i=[],a=[],o=[],s=0,c=null,l=null,u=null,d=[];return{start(){e=Date.now()},end(){t=Date.now()},setCacheStatus(e){n=e},addSessionUsed(e){r.includes(e)||r.push(e)},addSessionCreated(e){i.includes(e)||i.push(e)},addPRCreated(e){a.includes(e)||a.push(e)},addCommitCreated(e){o.includes(e)||o.push(e)},incrementComments(){s++},setTokenUsage(e,t,n){c=e,l=t,u=n},recordError(e,t,n){d.push({timestamp:new Date().toISOString(),type:e,message:t,recoverable:n})},getMetrics(){let f=t==null?Date.now()-e:t-e;return Object.freeze({startTime:e,endTime:t,duration:f,cacheStatus:n,sessionsUsed:Object.freeze([...r]),sessionsCreated:Object.freeze([...i]),prsCreated:Object.freeze([...a]),commitsCreated:Object.freeze([...o]),commentsPosted:s,tokenUsage:c,model:l,cost:u,errors:Object.freeze([...d])})}}}function Lo(e){z(`session-id`,e.sessionId??``),z(`cache-status`,e.cacheStatus),z(`duration`,e.duration)}function Ro(e){let t=B.resolve(e);return t.endsWith(B.sep)&&t.length>1?t.slice(0,-1):t}function Z(e){return typeof e==`object`&&!!e}function Q(e){return typeof e==`string`?e:null}function $(e){return typeof e==`number`?e:null}function zo(e){return typeof e==`boolean`?e:null}function Bo(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!Z(n))continue;let e=Q(n.file)??``,r=$(n.additions)??0,i=$(n.deletions)??0;t.push({file:e,additions:r,deletions:i})}return t}function Vo(e){if(Z(e))return{additions:$(e.additions)??0,deletions:$(e.deletions)??0,files:$(e.files)??0,diffs:Bo(e.diffs)}}function Ho(e){if(!Z(e))return;let t=Q(e.url);if(t!=null)return{url:t}}function Uo(e){return Z(e)?{created:$(e.created)??0,updated:$(e.updated)??0,compacting:$(e.compacting)??void 0,archived:$(e.archived)??void 0}:{created:0,updated:0}}function Wo(e){return Z(e)?{id:Q(e.id)??``,version:Q(e.version)??``,projectID:Q(e.projectID)??Q(e.projectId)??``,directory:Q(e.directory)??``,parentID:Q(e.parentID)??Q(e.parentId)??void 0,title:Q(e.title)??``,time:Uo(e.time),summary:Vo(e.summary),share:Ho(e.share),permission:Z(e.permission)?{rules:Array.isArray(e.permission.rules)?e.permission.rules:[]}:void 0,revert:Z(e.revert)?{messageID:Q(e.revert.messageID)??Q(e.revert.messageId)??``,partID:Q(e.revert.partID)??Q(e.revert.partId)??void 0,snapshot:Q(e.revert.snapshot)??void 0,diff:Q(e.revert.diff)??void 0}:void 0}:{id:``,version:``,projectID:``,directory:``,title:``,time:{created:0,updated:0}}}function Go(e){let t=Z(e.model)?e.model:null,n=Q(t?.providerID)??Q(t?.providerId)??Q(e.providerID)??Q(e.providerId)??``,r=Q(t?.modelID)??Q(t?.modelId)??Q(e.modelID)??Q(e.modelId)??``,i=Z(e.summary)?{title:Q(e.summary.title)??void 0,body:Q(e.summary.body)??void 0,diffs:Bo(e.summary.diffs)??[]}:void 0;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`user`,time:{created:$(Z(e.time)?e.time.created:null)??0},summary:i,agent:Q(e.agent)??``,model:{providerID:n,modelID:r},system:Q(e.system)??void 0,tools:Z(e.tools)?e.tools:void 0,variant:Q(e.variant)??void 0}}function Ko(e){let t=Z(e.time)?e.time:null,n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null,i=Z(e.path)?e.path:null;return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,role:`assistant`,time:{created:$(t?.created)??0,completed:$(t?.completed)??void 0},parentID:Q(e.parentID)??Q(e.parentId)??``,modelID:Q(e.modelID)??Q(e.modelId)??``,providerID:Q(e.providerID)??Q(e.providerId)??``,mode:Q(e.mode)??``,agent:Q(e.agent)??``,path:{cwd:Q(i?.cwd)??``,root:Q(i?.root)??``},summary:zo(e.summary)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}},finish:Q(e.finish)??void 0,error:Z(e.error)?{name:Q(e.error.name)??``,message:Q(e.error.message)??``}:void 0}}function qo(e){return Z(e)?Q(e.role)===`assistant`?Ko(e):Go(e):{id:``,sessionID:``,role:`user`,time:{created:0},agent:``,model:{providerID:``,modelID:``}}}function Jo(e){let t=qo(e);if(!Z(e))return t;let n=Array.isArray(e.parts)?e.parts.map(Zo):void 0;return n==null||n.length===0?t:{...t,parts:n}}function Yo(e){return{id:Q(e.id)??``,sessionID:Q(e.sessionID)??Q(e.sessionId)??``,messageID:Q(e.messageID)??Q(e.messageId)??``}}function Xo(e){let t=Q(e.status)??`pending`;if(t===`completed`){let t=Z(e.time)?e.time:null;return{status:`completed`,input:Z(e.input)?e.input:{},output:Q(e.output)??``,title:Q(e.title)??``,metadata:Z(e.metadata)?e.metadata:{},time:{start:$(t?.start)??0,end:$(t?.end)??0,compacted:$(t?.compacted)??void 0},attachments:void 0}}if(t===`running`){let t=Z(e.time)?e.time:null;return{status:`running`,input:Z(e.input)?e.input:{},time:{start:$(t?.start)??0}}}if(t===`error`){let t=Z(e.time)?e.time:null;return{status:`error`,input:Z(e.input)?e.input:{},error:Q(e.error)??``,time:{start:$(t?.start)??0,end:$(t?.end)??0}}}return{status:`pending`}}function Zo(e){if(!Z(e))return{id:``,sessionID:``,messageID:``,type:`text`,text:``};let t=Yo(e);switch(Q(e.type)){case`text`:return{...t,type:`text`,text:Q(e.text)??``,synthetic:zo(e.synthetic)??void 0,ignored:zo(e.ignored)??void 0,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0,metadata:Z(e.metadata)?e.metadata:void 0};case`tool`:{let n=Z(e.state)?e.state:{status:`pending`};return{...t,type:`tool`,callID:Q(e.callID)??Q(e.callId)??``,tool:Q(e.tool)??``,state:Xo(n),metadata:Z(e.metadata)?e.metadata:void 0}}case`reasoning`:return{...t,type:`reasoning`,reasoning:Q(e.reasoning)??``,time:Z(e.time)?{start:$(e.time.start)??0,end:$(e.time.end)??void 0}:void 0};case`step-finish`:{let n=Z(e.tokens)?e.tokens:null,r=Z(n?.cache)?n?.cache:null;return{...t,type:`step-finish`,reason:Q(e.reason)??``,snapshot:Q(e.snapshot)??void 0,cost:$(e.cost)??0,tokens:{input:$(n?.input)??0,output:$(n?.output)??0,reasoning:$(n?.reasoning)??0,cache:{read:$(r?.read)??0,write:$(r?.write)??0}}}}default:return{...t,type:`text`,text:Q(e.text)??``}}}async function Qo(e,t,n){let r=await e.session.list({query:{directory:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?r.data.map(Wo):[]:(n.warning(`SDK session list failed`,{error:String(r.error)}),[])}async function $o(e,t,n){let r=await e.session.messages({path:{id:t}});return r.error==null&&r.data!=null?Array.isArray(r.data)?[...r.data.map(Jo)].sort((e,t)=>e.time.created-t.time.created):[]:(n.warning(`SDK session messages failed`,{error:String(r.error)}),[])}async function es(e,t,n,r){let i=await e.session.list({query:{directory:t,start:n,roots:!0,limit:10}});if(i.error!=null||i.data==null)return r.warning(`SDK session list failed`,{error:String(i.error)}),null;if(!Array.isArray(i.data)||i.data.length===0)return null;let a=i.data.map(Wo);if(a.length===0)return null;let o=a.reduce((e,t)=>t.time.created>e.time.created?t:e);return{projectID:o.projectID,session:o}}async function ts(e,t,n){let r=await e.session.delete({path:{id:t}});return r.error==null?(n.debug(`Deleted session via SDK`,{sessionID:t}),0):(n.warning(`SDK session delete failed`,{sessionID:t,error:String(r.error)}),0)}async function ns(e,t){let n=await e.project.list();if(n.error!=null||n.data==null)return t.warning(`SDK project list failed`,{error:String(n.error)}),[];if(!Array.isArray(n.data))return[];let r=[];for(let e of n.data){if(!Z(e))continue;let t=Q(e.id),n=Q(e.worktree),i=Q(e.path);t==null||n==null||i==null||r.push({id:t,worktree:n,path:i})}return r}async function rs(e,t,n){let r=Ro(t),i=await ns(e,n);for(let e of i){if(Ro(e.worktree)===r)return e;let t=Q(e.path);if(t!=null&&Ro(t)===r)return e}return null}async function is(e,t,n){return Qo(e,t,n)}async function as(e,t,n){return $o(e,t,n)}async function os(e,t,n){return ts(e,t,n)}async function ss(e,t,n,r){return es(e,t,n,r)}const cs={maxSessions:50,maxAgeDays:30};async function ls(e,t,n,r){let{maxSessions:i,maxAgeDays:a}=n;if(r.info(`Starting session pruning`,{workspacePath:t,maxSessions:i,maxAgeDays:a}),await rs(e,t,r)==null)return r.debug(`No project found for pruning`,{workspacePath:t}),{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let o=await is(e,t,r),s=o.filter(e=>e.parentID==null);if(s.length===0)return{prunedCount:0,prunedSessionIds:[],remainingCount:0,freedBytes:0};let c=[...s].sort((e,t)=>t.time.updated-e.time.updated),l=new Date;l.setDate(l.getDate()-a);let u=l.getTime(),d=new Set;for(let e of c)e.time.updated>=u&&d.add(e.id);for(let e=0;e!d.has(e.id)),p=new Set;for(let e of f){p.add(e.id);for(let t of o)t.parentID===e.id&&p.add(t.id)}if(p.size===0)return r.info(`No sessions to prune`),{prunedCount:0,prunedSessionIds:[],remainingCount:s.length,freedBytes:0};let m=0,h=[];for(let t of p)try{let n=await os(e,t,r);m+=n,h.push(t),r.debug(`Pruned session`,{sessionId:t,bytes:n})}catch(e){r.warning(`Failed to prune session`,{sessionId:t,error:N(e)})}let g=s.length-f.length;return r.info(`Session pruning complete`,{prunedCount:h.length,remainingCount:g,freedBytes:m}),{prunedCount:h.length,prunedSessionIds:h,remainingCount:g,freedBytes:m}}async function us(e,t,n,r){let{limit:i,fromDate:a,toDate:o}=n;r.debug(`Listing sessions`,{directory:t,limit:i});let s=[...(await is(e,t,r)).filter(e=>!(e.parentID!=null||a!=null&&e.time.createdo.getTime()))].sort((e,t)=>t.time.updated-e.time.updated),c=[],l=i==null?s:s.slice(0,i);for(let t of l){let n=await as(e,t.id,r),i=ds(n);c.push({id:t.id,projectID:t.projectID,directory:t.directory,title:t.title,createdAt:t.time.created,updatedAt:t.time.updated,messageCount:n.length,agents:i,isChild:!1})}return r.info(`Listed sessions`,{count:c.length,directory:t}),c}function ds(e){let t=new Set;for(let n of e)n.agent!=null&&t.add(n.agent);return[...t]}async function fs(e,t,n,r,i){let{limit:a=20,caseSensitive:o=!1,sessionId:s}=r;i.debug(`Searching sessions`,{query:e,directory:n,limit:a,caseSensitive:o});let c=o?e:e.toLowerCase(),l=[],u=0;if(s!=null){let e=await ps(t,s,c,o,i);return e.length>0&&l.push({sessionId:s,matches:e.slice(0,a)}),l}let d=await us(t,n,{},i);for(let e of d){if(u>=a)break;let n=await ps(t,e.id,c,o,i);if(n.length>0){let t=a-u;l.push({sessionId:e.id,matches:n.slice(0,t)}),u+=Math.min(n.length,t)}}return i.info(`Session search complete`,{query:e,resultCount:l.length,totalMatches:u}),l}async function ps(e,t,n,r,i){let a=await as(e,t,i),o=[];for(let e of a){let t=e.parts??[];for(let i of t){let t=ms(i);if(t==null)continue;let a=r?t:t.toLowerCase();if(a.includes(n)){let r=a.indexOf(n),s=Math.max(0,r-50),c=Math.min(t.length,r+n.length+50),l=t.slice(s,c);o.push({messageId:e.id,partId:i.id,excerpt:`...${l}...`,role:e.role,agent:e.agent})}}}return o}function ms(e){switch(e.type){case`text`:return e.text;case`reasoning`:return e.reasoning;case`tool`:return e.state.status===`completed`?`${e.tool}: ${e.state.output}`:null;case`step-finish`:return null}}function hs(e){let t=[`--- Fro Bot Run Summary ---`,`Event: ${e.eventType}`,`Repo: ${e.repo}`,`Ref: ${e.ref}`,`Run ID: ${e.runId}`,`Cache: ${e.cacheStatus}`,`Duration: ${e.duration}s`];return e.sessionIds.length>0&&t.push(`Sessions used: ${e.sessionIds.join(`, `)}`),e.createdPRs.length>0&&t.push(`PRs created: ${e.createdPRs.join(`, `)}`),e.createdCommits.length>0&&t.push(`Commits: ${e.createdCommits.join(`, `)}`),e.tokenUsage!=null&&t.push(`Tokens: ${e.tokenUsage.input} in / ${e.tokenUsage.output} out`),t.join(` +`)}async function gs(e,t,n,r){let i=hs(t);try{let t=await n.session.prompt({path:{id:e},body:{noReply:!0,parts:[{type:`text`,text:i}]}});if(t.error!=null){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:String(t.error)});return}r.info(`Session summary written via SDK`,{sessionId:e})}catch(t){r.warning(`SDK prompt writeback failed`,{sessionId:e,error:N(t)})}}const _s=/^[0-9a-f]{40}$/i;function vs(){return{exec:x,getExecOutput:c}}async function ys(e){let{workspacePath:t,logger:n,execAdapter:r=vs()}=e,i=B.join(t,`.git`),a=B.join(i,`opencode`);try{let e=(await G.readFile(a,`utf8`)).trim();if(e.length>0){if(_s.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:N(e)})}try{if((await G.stat(i)).isDirectory()===!1){let e=await G.readFile(i,`utf8`),n=/^gitdir: (.+)$/m.exec(e);if(n==null)return{projectId:null,source:`error`,error:`Invalid .git file format`};i=B.resolve(t,n[1]),a=B.join(i,`opencode`)}}catch{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 G.writeFile(a,s,`utf8`),n.info(`Project ID generated and cached`,{projectId:s,source:`generated`})}catch(e){n.warning(`Failed to cache project ID (continuing)`,{error:N(e)})}return{projectId:s,source:`generated`}}catch(e){return{projectId:null,source:`error`,error:N(e)}}}const bs={botLogin:null,requireMention:!0,allowedAssociations:_a,skipDraftPRs:!0,promptInput:null};function xs(e,t){if(t.length===0)return!1;let n=t.replace(/\[bot\]$/i,``);return n.length===0?!1:new RegExp(String.raw`@${Ss(n)}(?:\[bot\])?(?:$|[^\w])`,`i`).test(e)}function Ss(e){return e.replaceAll(/[.*+?^${}()|[\]\\]/g,String.raw`\$&`)}function Cs(e,t){if(t.length===0)return null;let n=t.replace(/\[bot\]$/i,``);if(n.length===0)return null;let r=new RegExp(String.raw`@${Ss(n)}(?:\[bot\])?\s*(.*)`,`is`).exec(e)?.[1];if(r==null)return null;let i=r.trim();if(i.length===0)return{raw:``,action:null,args:``};let a=i.split(/\s+/),o=a[0]??``;return{raw:i,action:o===``?null:o,args:a.slice(1).join(` `)}}function ws(e,t){return t.includes(e)}function Ts(e){return e.endsWith(`[bot]`)}function Es(e,t){if(t==null||t===``||e==null)return{hasMention:!1,command:null};let n=xs(e,t);return{hasMention:n,command:n?Cs(e,t):null}}function Ds(e,t){if(e.type!==`issue_comment`)throw Error(`Event type must be issue_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Ts(e.comment.author)},r={kind:e.issue.isPullRequest?`pr`:`issue`,number:e.issue.number,title:e.issue.title,body:e.comment.body??null,locked:e.issue.locked},i=e.comment.body,a=e.comment.id,{hasMention:o,command:s}=Es(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function Os(e,t){if(e.type!==`discussion_comment`)throw Error(`Event type must be discussion_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Ts(e.comment.author)},r={kind:`discussion`,number:e.discussion.number,title:e.discussion.title,body:e.comment.body??e.discussion.body??null,locked:e.discussion.locked},i=e.comment.body??null,a=e.comment.id,{hasMention:o,command:s}=Es(i,t);return{author:n,target:r,commentBody:i,commentId:a,hasMention:o,command:s,action:e.action}}function ks(e,t,n){if(e.type!==`workflow_dispatch`)throw Error(`Event type must be workflow_dispatch`);let r=(n??e.inputs?.prompt??``).trim();return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Manual workflow dispatch`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function As(e,t){if(e.type!==`issues`)throw Error(`Event type must be issues`);let n={login:e.sender.login,association:e.issue.authorAssociation,isBot:Ts(e.sender.login)},r={kind:`issue`,number:e.issue.number,title:e.issue.title,body:e.issue.body,locked:e.issue.locked},{hasMention:i,command:a}=Es(e.issue.body??``,t);return{author:n,target:r,commentBody:e.issue.body,commentId:null,hasMention:i,command:a,action:e.action}}const js=[`opened`,`edited`];function Ms(e){return js.includes(e)}function Ns(e,t,n){let r=e.action;return r==null||!Ms(r)?(n.debug(`Skipping unsupported issues action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Issues action '${r}' is not supported (only 'opened' and 'edited')`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Issues from bots (${e.author.login}) are not processed`}):e.author!=null&&!ws(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):r===`edited`&&!e.hasMention?(n.debug(`Skipping issues.edited without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Issue edit does not mention the bot`}):e.target?.locked===!0?(n.debug(`Skipping locked issue`),{shouldSkip:!0,reason:`issue_locked`,message:`Issue is locked`}):{shouldSkip:!1}}function Ps(e,t){if(e.type!==`pull_request`)throw Error(`Event type must be pull_request`);let n={login:e.sender.login,association:e.pullRequest.authorAssociation,isBot:Ts(e.sender.login)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.pullRequest.body,locked:e.pullRequest.locked,isDraft:e.pullRequest.draft},{hasMention:i,command:a}=Es(e.pullRequest.body??``,t);return{author:n,target:r,commentBody:e.pullRequest.body,commentId:null,hasMention:i,command:a,action:e.action}}const Fs=[`opened`,`synchronize`,`reopened`];function Is(e){return Fs.includes(e)}function Ls(e,t,n){let r=e.action;return r==null||!Is(r)?(n.debug(`Skipping unsupported pull_request action`,{action:r}),{shouldSkip:!0,reason:`action_not_supported`,message:`Pull request action '${r}' is not supported`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Pull requests from bots (${e.author.login}) are not processed`}):e.author!=null&&!ws(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.skipDraftPRs&&e.target?.isDraft===!0?(n.debug(`Skipping draft PR`),{shouldSkip:!0,reason:`draft_pr`,message:`Pull request is a draft`}):e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):{shouldSkip:!1}}function Rs(e,t){if(e.type!==`pull_request_review_comment`)throw Error(`Event type must be pull_request_review_comment`);let n={login:e.comment.author,association:e.comment.authorAssociation,isBot:Ts(e.comment.author)},r={kind:`pr`,number:e.pullRequest.number,title:e.pullRequest.title,body:e.comment.body,locked:e.pullRequest.locked,path:e.comment.path,line:e.comment.line??void 0,diffHunk:e.comment.diffHunk,commitId:e.comment.commitId},{hasMention:i,command:a}=Es(e.comment.body,t);return{author:n,target:r,commentBody:e.comment.body,commentId:e.comment.id,hasMention:i,command:a,action:e.action}}function zs(e,t,n){let r=n?.trim()??``;return{author:{login:t,association:`OWNER`,isBot:!1},target:{kind:`manual`,number:0,title:`Scheduled workflow`,body:r===``?null:r,locked:!1},commentBody:r===``?null:r,commentId:null,hasMention:!1,command:null,action:null}}function Bs(e,t){return(e.promptInput?.trim()??``)===``?(t.debug(`Skipping schedule event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Schedule trigger requires prompt input`}):{shouldSkip:!1}}function Vs(e,t){return(e.commentBody?.trim()??``)===``?(t.debug(`Skipping workflow_dispatch event without prompt input`),{shouldSkip:!0,reason:`prompt_required`,message:`Workflow dispatch requires prompt input`}):{shouldSkip:!1}}function Hs(e,t,n,r){let{targetLabel:i,actionLabel:a}=r;return e.action===`created`?e.target?.locked===!0?(n.debug(`Skipping locked ${i}`),{shouldSkip:!0,reason:`issue_locked`,message:`${i} is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!ws(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping ${a} without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created ${a} action`,{action:e.action}),{shouldSkip:!0,reason:`action_not_created`,message:`${a} action is '${e.action}', not 'created'`})}function Us(e,t,n){return Hs(e,t,n,{targetLabel:`Issue or PR`,actionLabel:`Comment`})}function Ws(e,t,n){return Hs(e,t,n,{targetLabel:`Discussion`,actionLabel:`Discussion comment`})}function Gs(e,t,n){let r=e.action;return r===`created`?e.target?.locked===!0?(n.debug(`Skipping locked pull request`),{shouldSkip:!0,reason:`issue_locked`,message:`Pull request is locked`}):e.author!=null&&e.author.isBot?(n.debug(`Skipping bot actor`,{bot:e.author.login}),{shouldSkip:!0,reason:`self_comment`,message:`Review comments from bots (${e.author.login}) are not processed`}):e.author!=null&&!ws(e.author.association,t.allowedAssociations)?(n.debug(`Skipping unauthorized author`,{association:e.author.association,allowed:t.allowedAssociations}),{shouldSkip:!0,reason:`unauthorized_author`,message:`Author association '${e.author.association}' is not authorized`}):t.requireMention&&!e.hasMention?(n.debug(`Skipping review comment without bot mention`),{shouldSkip:!0,reason:`no_mention`,message:`Review comment does not mention the bot`}):{shouldSkip:!1}:(n.debug(`Skipping non-created review comment action`,{action:r}),{shouldSkip:!0,reason:`action_not_created`,message:`Review comment action '${r}' is not supported (only 'created')`})}function Ks(e,t,n){if(e.eventType===`unsupported`)return n.debug(`Skipping unsupported event`,{eventName:e.eventName}),{shouldSkip:!0,reason:`unsupported_event`,message:`Unsupported event type: ${e.eventName}`};switch(e.eventType){case`issue_comment`:return Us(e,t,n);case`discussion_comment`:return Ws(e,t,n);case`issues`:return Ns(e,t,n);case`pull_request`:return Ls(e,t,n);case`pull_request_review_comment`:return Gs(e,t,n);case`schedule`:return Bs(t,n);case`workflow_dispatch`:return Vs(e,n);default:return{shouldSkip:!1}}}function qs(e,t,n){let r={eventType:e.eventType,eventName:e.eventName,repo:e.repo,ref:e.ref,sha:e.sha,runId:e.runId,actor:e.actor,raw:e};switch(e.eventType){case`issue_comment`:{let n=Ds(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`discussion_comment`:{let n=Os(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`workflow_dispatch`:{let t=ks(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`issues`:{let n=As(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request`:{let n=Ps(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`pull_request_review_comment`:{let n=Rs(e.event,t);return{...r,action:n.action,author:n.author,target:n.target,commentBody:n.commentBody,commentId:n.commentId,hasMention:n.hasMention,command:n.command}}case`schedule`:{let t=zs(e.event,e.actor,n);return{...r,action:t.action,author:t.author,target:t.target,commentBody:t.commentBody,commentId:t.commentId,hasMention:t.hasMention,command:t.command}}case`unsupported`:return{...r,action:null,author:null,target:null,commentBody:null,commentId:null,hasMention:!1,command:null}}}function Js(e,t,n={}){let r={...bs,...n},i=qs(e,r.botLogin,r.promptInput);t.debug(`Routing event`,{eventName:e.eventName,eventType:e.eventType,hasMention:i.hasMention});let a=Ks(i,r,t);return a.shouldSkip?{shouldProcess:!1,skipReason:a.reason,skipMessage:a.message,context:i}:{shouldProcess:!0,context:i}}async function Ys(){let e=Date.now(),t=j({phase:`bootstrap`}),n=null,i=!1,o=0,s=null,c=null,l=null,u=null,d=Io();d.start(),f(L.SHOULD_SAVE_CACHE,`false`),f(L.CACHE_SAVED,`false`);try{t.info(`Starting Fro Bot Agent`);let p=Mo();if(!p.success)return _(`Invalid inputs: ${p.error.message}`),1;let m=p.data,h=j({phase:`main`});h.info(`Action inputs parsed`,{sessionRetention:m.sessionRetention,s3Backup:m.s3Backup,hasGithubToken:m.githubToken.length>0,hasPrompt:m.prompt!=null,agent:m.agent,hasModelOverride:m.model!=null,timeoutMs:m.timeoutMs});let g=await Ra({logger:h,opencodeVersion:m.opencodeVersion});g.didSetup?h.info(`OpenCode auto-setup completed`,{version:g.version}):h.info(`OpenCode already available`,{version:g.version}),f(L.OPENCODE_VERSION,g.version),l=g.version;let b=j({phase:`context`}),x=To(b);s=Bi({token:m.githubToken,logger:b});let S=await Vi(s,b),C=j({phase:`trigger`}),w=Js(x,C,{botLogin:S,requireMention:!0,promptInput:m.prompt});if(!w.shouldProcess)return C.info(`Skipping event`,{reason:w.skipReason,message:w.skipMessage}),Lo({sessionId:null,cacheStatus:`miss`,duration:Date.now()-e}),0;C.info(`Event routed for processing`,{eventType:w.context.eventType,hasMention:w.context.hasMention,command:w.context.command?.action??null}),f(L.SHOULD_SAVE_CACHE,`true`);let T=await et({logger:b,octokit:s,triggerContext:w.context,botLogin:S});n={repo:T.repo,commentId:T.commentId,issueNumber:T.issueNumber,issueType:T.issueType,botLogin:S};let E=j({phase:`acknowledgment`});await Ha(s,n,E);let D={agentIdentity:`github`,repo:ee(),ref:de(),os:a()},O=j({phase:`cache`}),te=v(),ne=B.join(te,`.git`,`opencode`),k=await ie({components:D,logger:O,storagePath:y(),authPath:r(),projectIdPath:ne,opencodeVersion:g.version}),A=k.corrupted?`corrupted`:k.hit?`hit`:`miss`;d.setCacheStatus(A),h.info(`Cache restore completed`,{cacheStatus:A,key:k.key});let M=await ys({workspacePath:te,logger:O});M.source===`error`?O.warning(`Failed to generate project ID (continuing)`,{error:M.error}):O.debug(`Project ID ready`,{projectId:M.projectId,source:M.source});let N=j({phase:`server-bootstrap`}),re=await Fa(new AbortController().signal,N);if(!re.success)return _(`OpenCode server bootstrap failed: ${re.error.message}`),1;u=re.data,N.info(`SDK server bootstrapped successfully`);let P=j({phase:`session`}),ae=Ro(te),oe=await us(u.client,ae,{limit:10},P);P.debug(`Listed recent sessions`,{count:oe.length});let F=T.issueTitle??T.repo,I=await fs(F,u.client,ae,{limit:5},P);P.debug(`Searched prior sessions`,{query:F,resultCount:I.length});for(let e of I)d.addSessionUsed(e.sessionId);let se=j({phase:`attachments`}),R=T.commentBody??``,ce=Za(R);if(ce.length>0){se.info(`Processing attachments`,{count:ce.length});let{validated:e,skipped:t}=co(await no(ce,m.githubToken,void 0,se),void 0,se);(e.length>0||t.length>0)&&(c=oo(R,ce,e,t),se.info(`Attachments processed`,{processed:e.length,skipped:t.length}))}let le={context:T,customPrompt:m.prompt,cacheStatus:A,sessionContext:{recentSessions:oe,priorWorkContext:I},triggerContext:w.context,fileParts:c?.fileParts},ue=H.env.SKIP_AGENT_EXECUTION===`true`,z,fe=Date.now();if(ue)h.info(`Skipping agent execution (SKIP_AGENT_EXECUTION=true)`),z={success:!0,exitCode:0,sessionId:null,error:null,tokenUsage:null,model:null,cost:null,prsCreated:[],commitsCreated:[],commentsPosted:0,llmError:null};else{let e=await Ia(le,j({phase:`execution`}),{agent:m.agent,model:m.model,timeoutMs:m.timeoutMs,omoProviders:m.omoProviders},u??void 0),t=e.sessionId;if(t==null){let e=await ss(u.client,ae,fe,P);e!=null&&(t=e.session.id,P.debug(`Identified session from execution`,{sessionId:t}))}z={...e,sessionId:t}}z.sessionId!=null&&f(L.SESSION_ID,z.sessionId),i=z.success,z.sessionId!=null&&d.addSessionCreated(z.sessionId),z.tokenUsage!=null&&d.setTokenUsage(z.tokenUsage,z.model,z.cost);for(let e of z.prsCreated)d.addPRCreated(e);for(let e of z.commitsCreated)d.addCommitCreated(e);for(let e=0;e0&&n.owner.length>0&&n.repo.length>0){let e=ln(z.llmError),t=j({phase:`error-comment`}),r=await So(s,n,{body:e},t);r==null?t.warning(`Failed to post LLM error comment`):(t.info(`Posted LLM error comment`,{commentUrl:r.url}),d.incrementComments())}else h.warning(`Cannot post error comment: missing target context`);o=0}}catch(n){o=1;let r=Date.now()-e,i=n instanceof Error?n.name:`UnknownError`,a=n instanceof Error?n.message:String(n);d.recordError(i,a,!1),d.end(),Lo({sessionId:null,cacheStatus:`miss`,duration:r}),n instanceof Error?(t.error(`Agent failed`,{error:n.message}),_(n.message)):(t.error(`Agent failed with unknown error`),_(`An unknown error occurred`))}finally{try{if(c!=null){let e=j({phase:`attachment-cleanup`});await ro(c.tempFiles,e)}if(n!=null&&s!=null){let e=j({phase:`cleanup`});await Ja(s,n,i,e)}let e=j({phase:`prune`}),t=v();if(u!=null){let n=Ro(t),r=await ls(u.client,n,cs,e);r.prunedCount>0&&e.info(`Pruned old sessions`,{pruned:r.prunedCount,remaining:r.remainingCount})}let o={agentIdentity:`github`,repo:ee(),ref:de(),os:a()},d=j({phase:`cache-save`}),p=B.join(t,`.git`,`opencode`);await I({components:o,runId:ue(),logger:d,storagePath:y(),authPath:r(),projectIdPath:p,opencodeVersion:l})&&f(L.CACHE_SAVED,`true`)}catch(e){t.warning(`Cleanup failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}finally{if(u!=null)try{u.shutdown()}catch(e){t.warning(`Server shutdown failed (non-fatal)`,{error:e instanceof Error?e.message:String(e)})}}}return o}await Ys().then(e=>{H.exit(e)});export{}; \ No newline at end of file diff --git a/src/lib/inputs.test.ts b/src/lib/inputs.test.ts index fdf178ef..fe8dd227 100644 --- a/src/lib/inputs.test.ts +++ b/src/lib/inputs.test.ts @@ -375,6 +375,63 @@ describe('parseActionInputs', () => { expect(!result.success && result.error.message).toContain('opencode-config') expect(!result.success && result.error.message).toContain('valid JSON') }) + + it('returns error when opencode-config is JSON null literal', () => { + const mockGetInput = core.getInput as ReturnType + + mockGetInput.mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghp_test123', + 'auth-json': '{"anthropic":{"type":"api","key":"sk-ant-test"}}', + 'opencode-config': 'null', + } + return inputs[name] ?? '' + }) + + const result = parseActionInputs() + + expect(result.success).toBe(false) + expect(!result.success && result.error.message).toContain('opencode-config') + expect(!result.success && result.error.message).toContain('JSON object') + }) + + it('returns error when opencode-config is a JSON array', () => { + const mockGetInput = core.getInput as ReturnType + + mockGetInput.mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghp_test123', + 'auth-json': '{"anthropic":{"type":"api","key":"sk-ant-test"}}', + 'opencode-config': '[1,2,3]', + } + return inputs[name] ?? '' + }) + + const result = parseActionInputs() + + expect(result.success).toBe(false) + expect(!result.success && result.error.message).toContain('opencode-config') + expect(!result.success && result.error.message).toContain('JSON object') + }) + + it('returns error when opencode-config is a JSON string literal', () => { + const mockGetInput = core.getInput as ReturnType + + mockGetInput.mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghp_test123', + 'auth-json': '{"anthropic":{"type":"api","key":"sk-ant-test"}}', + 'opencode-config': '"literal"', + } + return inputs[name] ?? '' + }) + + const result = parseActionInputs() + + expect(result.success).toBe(false) + expect(!result.success && result.error.message).toContain('opencode-config') + expect(!result.success && result.error.message).toContain('JSON object') + }) }) describe('with valid opencode-config', () => { diff --git a/src/lib/inputs.ts b/src/lib/inputs.ts index bfe530fb..de25a841 100644 --- a/src/lib/inputs.ts +++ b/src/lib/inputs.ts @@ -190,6 +190,15 @@ export function parseActionInputs(): Result { // Validate opencode-config is valid JSON if provided if (opencodeConfig != null) { validateJsonString(opencodeConfig, 'opencode-config') + + const parsedOpencodeConfig: unknown = JSON.parse(opencodeConfig) + const isObject = typeof parsedOpencodeConfig === 'object' + const isNull = parsedOpencodeConfig == null + const isArray = Array.isArray(parsedOpencodeConfig) + + if (!isObject || isNull || isArray) { + throw new Error("Input 'opencode-config' must be a JSON object") + } } return ok({ diff --git a/src/lib/setup/omo-config.test.ts b/src/lib/setup/omo-config.test.ts index 47dfbe23..10afcb81 100644 --- a/src/lib/setup/omo-config.test.ts +++ b/src/lib/setup/omo-config.test.ts @@ -43,7 +43,7 @@ describe('deepMerge', () => { expect(result).toEqual({arr: [4, 5]}) }) - it('handles null source gracefully', () => { + it('returns target unchanged when source is empty object', () => { // #given const target = {a: 1} @@ -54,6 +54,23 @@ describe('deepMerge', () => { expect(result).toEqual({a: 1}) }) + it('ignores prototype pollution keys during merge', () => { + // #given + const source = JSON.parse('{"__proto__":{"polluted":true},"constructor":{"prototype":{"oops":true}},"safe":1}') as { + __proto__?: unknown + constructor?: unknown + safe: number + } + + // #when + const result = deepMerge({}, source) + + // #then + expect(result.safe).toBe(1) + expect(Object.prototype).not.toHaveProperty('polluted') + expect(Object.prototype).not.toHaveProperty('oops') + }) + it('does not mutate target or source objects', () => { // #given const target = {a: {x: 1}} @@ -176,6 +193,24 @@ describe('writeOmoConfig', () => { await expect(writeOmoConfig(invalidJson, tmpDir, logger)).rejects.toThrow() }) + it('throws when input JSON is not an object', async () => { + // #given + const jsonNull = 'null' + const jsonArray = '[1,2,3]' + const jsonNumber = '42' + + // #when / #then + await expect(writeOmoConfig(jsonNull, tmpDir, logger)).rejects.toThrow( + 'omo-config must be a JSON object (non-null, non-array)', + ) + await expect(writeOmoConfig(jsonArray, tmpDir, logger)).rejects.toThrow( + 'omo-config must be a JSON object (non-null, non-array)', + ) + await expect(writeOmoConfig(jsonNumber, tmpDir, logger)).rejects.toThrow( + 'omo-config must be a JSON object (non-null, non-array)', + ) + }) + it('logs info after writing config', async () => { // #given const configJson = JSON.stringify({theme: 'dark'}) diff --git a/src/lib/setup/omo-config.ts b/src/lib/setup/omo-config.ts index eab5df38..bd47cd55 100644 --- a/src/lib/setup/omo-config.ts +++ b/src/lib/setup/omo-config.ts @@ -3,6 +3,11 @@ import * as fs from 'node:fs/promises' import * as path from 'node:path' const OMO_CONFIG_FILENAME = 'oh-my-opencode.json' +const UNSAFE_MERGE_KEYS = new Set(['__proto__', 'prototype', 'constructor']) + +function isMergeableObject(value: unknown): value is Record { + return value != null && typeof value === 'object' && !Array.isArray(value) +} /** * Deep-merge two plain objects. @@ -18,20 +23,25 @@ const OMO_CONFIG_FILENAME = 'oh-my-opencode.json' * @returns New merged object */ export function deepMerge(target: Record, source: Record): Record { - const result: Record = {...target} + const result: Record = Object.create(null) as Record + + for (const [key, targetValue] of Object.entries(target)) { + if (UNSAFE_MERGE_KEYS.has(key)) { + continue + } + + result[key] = targetValue + } for (const [key, sourceValue] of Object.entries(source)) { + if (UNSAFE_MERGE_KEYS.has(key)) { + continue + } + const targetValue = result[key] - if ( - sourceValue != null && - typeof sourceValue === 'object' && - !Array.isArray(sourceValue) && - targetValue != null && - typeof targetValue === 'object' && - !Array.isArray(targetValue) - ) { - result[key] = deepMerge(targetValue as Record, sourceValue as Record) + if (isMergeableObject(sourceValue) && isMergeableObject(targetValue)) { + result[key] = deepMerge(targetValue, sourceValue) } else { result[key] = sourceValue } @@ -55,7 +65,12 @@ export function deepMerge(target: Record, source: Record { // Parse user-supplied JSON first — throw early if invalid - const userConfig = JSON.parse(configJson) as Record + const parsedUserConfig: unknown = JSON.parse(configJson) + if (!isMergeableObject(parsedUserConfig)) { + throw new Error('omo-config must be a JSON object (non-null, non-array)') + } + + const userConfig = parsedUserConfig await fs.mkdir(configDir, {recursive: true}) @@ -69,8 +84,9 @@ export async function writeOmoConfig(configJson: string, configDir: string, logg if (parsed != null && typeof parsed === 'object' && !Array.isArray(parsed)) { existingConfig = parsed as Record } - } catch { + } catch (error) { // File absent or corrupt — start from empty base + logger.debug('Using empty base oMo config', {path: filePath, error: String(error)}) } const merged = deepMerge(existingConfig, userConfig) diff --git a/src/lib/setup/setup.test.ts b/src/lib/setup/setup.test.ts index 78bb647e..9a4c8ca8 100644 --- a/src/lib/setup/setup.test.ts +++ b/src/lib/setup/setup.test.ts @@ -272,8 +272,8 @@ describe('setup', () => { ) }) - it('fails when opencode-config is null', async () => { - // #given - user supplies null as opencode-config + it('fails when opencode-config parses to JSON null', async () => { + // #given - user supplies JSON null literal as opencode-config vi.mocked(core.getInput).mockImplementation((name: string) => { const inputs: Record = { 'github-token': 'ghs_test_token', @@ -298,6 +298,59 @@ describe('setup', () => { expect(core.setFailed).toHaveBeenCalledWith('opencode-config must be a JSON object') }) + it('fails with explicit message when opencode-config is invalid JSON', async () => { + // #given - malformed JSON + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{"anthropic": {"api_key": "sk-ant-test"}}', + 'opencode-version': 'latest', + 'opencode-config': '{invalid-json}', + } + return inputs[name] ?? '' + }) + vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') + vi.mocked(exec.getExecOutput).mockResolvedValue({exitCode: 0, stdout: '', stderr: ''}) + vi.mocked(exec.exec).mockResolvedValue(0) + vi.mocked(fs.writeFile).mockResolvedValue() + vi.mocked(fs.mkdir).mockResolvedValue(undefined) + vi.mocked(fs.access).mockRejectedValue(new Error('not found')) + + // #when + const result = await runSetup() + + // #then + expect(result).toBe(null) + expect(core.setFailed).toHaveBeenCalledWith('opencode-config must be valid JSON') + }) + + it('treats whitespace-only opencode-config as not provided', async () => { + // #given + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{"anthropic": {"api_key": "sk-ant-test"}}', + 'opencode-version': 'latest', + 'opencode-config': ' ', + } + return inputs[name] ?? '' + }) + vi.mocked(tc.find).mockReturnValue('/cached/opencode/1.0.300') + vi.mocked(exec.getExecOutput).mockResolvedValue({exitCode: 0, stdout: '', stderr: ''}) + vi.mocked(exec.exec).mockResolvedValue(0) + vi.mocked(fs.writeFile).mockResolvedValue() + vi.mocked(fs.mkdir).mockResolvedValue(undefined) + vi.mocked(fs.access).mockRejectedValue(new Error('not found')) + + // #when + const result = await runSetup() + + // #then + expect(result).not.toBeNull() + expect(core.setFailed).not.toHaveBeenCalled() + expect(core.exportVariable).toHaveBeenCalledWith('OPENCODE_CONFIG_CONTENT', JSON.stringify({autoupdate: false})) + }) + it('fails when opencode-config is an array', async () => { // #given - user supplies array as opencode-config vi.mocked(core.getInput).mockImplementation((name: string) => { @@ -791,6 +844,31 @@ describe('setup', () => { expect(omoConfigCall).toBeUndefined() }) + it('treats whitespace-only omo-config as not provided', async () => { + // #given + vi.mocked(core.getInput).mockImplementation((name: string) => { + const inputs: Record = { + 'github-token': 'ghs_test_token', + 'auth-json': '{"anthropic": {"api_key": "sk-ant-test"}}', + 'opencode-version': 'latest', + 'omo-config': ' ', + } + return inputs[name] ?? '' + }) + + // #when + const result = await runSetup() + + // #then + expect(result).not.toBeNull() + expect(core.warning).not.toHaveBeenCalledWith(expect.stringContaining('omo-config')) + const writeFileCalls = vi.mocked(fs.writeFile).mock.calls + const omoConfigCall = writeFileCalls.find( + ([filePath]) => typeof filePath === 'string' && filePath.includes('oh-my-opencode.json'), + ) + expect(omoConfigCall).toBeUndefined() + }) + it('continues setup and warns when omo-config JSON is invalid', async () => { // #given - invalid JSON in omo-config vi.mocked(core.getInput).mockImplementation((name: string) => { diff --git a/src/lib/setup/setup.ts b/src/lib/setup/setup.ts index 0389c574..b37a8774 100644 --- a/src/lib/setup/setup.ts +++ b/src/lib/setup/setup.ts @@ -109,13 +109,18 @@ function createExecAdapter(): ExecAdapter { * Parse setup action inputs from environment. */ function parseSetupInputs(): SetupInputs { + const appIdRaw = core.getInput('app-id').trim() + const privateKeyRaw = core.getInput('private-key').trim() + const opencodeConfigRaw = core.getInput('opencode-config').trim() + const omoConfigRaw = core.getInput('omo-config').trim() + return { opencodeVersion: core.getInput('opencode-version') || 'latest', authJson: core.getInput('auth-json', {required: true}), - appId: core.getInput('app-id') || null, - privateKey: core.getInput('private-key') || null, - opencodeConfig: core.getInput('opencode-config') || null, - omoConfig: core.getInput('omo-config') || null, + appId: appIdRaw.length > 0 ? appIdRaw : null, + privateKey: privateKeyRaw.length > 0 ? privateKeyRaw : null, + opencodeConfig: opencodeConfigRaw.length > 0 ? opencodeConfigRaw : null, + omoConfig: omoConfigRaw.length > 0 ? omoConfigRaw : null, } } @@ -258,7 +263,14 @@ export async function runSetup(): Promise { const ciConfig: Record = {autoupdate: false} if (inputs.opencodeConfig != null) { - const parsed = JSON.parse(inputs.opencodeConfig) as unknown + let parsed: unknown + try { + parsed = JSON.parse(inputs.opencodeConfig) + } catch { + core.setFailed('opencode-config must be valid JSON') + return null + } + // Validate that the parsed result is a plain object (not null, array, or primitive) if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) { core.setFailed('opencode-config must be a JSON object')