@skyramp/testbot-core 0.13.0-v3.151 → 0.13.0-v3.152
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/VERSION.json +1 -1
- package/dist/main.js +147 -147
- package/dist/post.js +1 -1
- package/package.json +1 -1
package/dist/post.js
CHANGED
|
@@ -332,7 +332,7 @@ ${e.message??""}`));function F_e(e){if(!e.length||!e.every(Kvt))return;let t=e.f
|
|
|
332
332
|
`:e.text??"")}function A5(e){g5({command:e})}function KPe(e){return e.replace(/%/g,"%AZP25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function pRt(e){return KPe(e).replace(/;/g,"%3B").replace(/]/g,"%5D")}function FD(e,t,r){let n=Object.entries(t).map(([s,i])=>`${s}=${pRt(i)}`).join(";");return`##vso[${e}${n?` ${n}`:""}]${KPe(r)}`}function XPe(e){if(!e)return[];let t=e.split(/\r?\n/).filter(r=>r.trim()&&r!==e);return[e,...t].map(r=>FD("task.setsecret",{},r))}function ZPe(e,t=A5){for(let r of XPe(e))t(r)}function fRt(e){return e.replace(/%0D/g,"\r").replace(/%0A/g,`
|
|
333
333
|
`).replace(/%25/g,"%")}function eQe(e){let t=/^::([a-z-]+)(?: [^:]*)?::(.*)$/s.exec(e.replace(/\r?\n$/,""));if(!t)return;let[,r,n]=t,s=fRt(n),i=MD(s);switch(r){case"add-mask":return XPe(s);case"warning":case"error":return[FD("task.logissue",{type:r},i)];case"notice":return[i];case"debug":return i.split(`
|
|
334
334
|
`).map(o=>`##[debug]${o}`);case"group":return[`##[group]${i.split(`
|
|
335
|
-
`)[0]}`];case"endgroup":return["##[endgroup]"];default:return[]}}function ax(e){return e.replace(/\/+$/,"")}function y5(e){let t=new URL(e),r=t.pathname.split("/").filter(Boolean);if(r.length)return decodeURIComponent(r[r.length-1]);if(t.hostname.endsWith(".visualstudio.com"))return t.hostname.split(".")[0];throw new Error(`SYSTEM_COLLECTIONURI "${e}" names no organization`)}var hRt=/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,48}[A-Za-z0-9])?$/,mRt=/[\\/:*?"<>|;#${},+=[\]%\p{Cc}\p{Cf}]/u;function tQe(e){return e.length>0&&e.length<=64&&e===e.trim()&&!mRt.test(e)&&!/[^\S ]/u.test(e)&&!/^[._]/.test(e)&&!e.endsWith(".")}function LD(e){return b5(`${e.namespace}/${e.name}`)}function b5(e){let t=e.indexOf("/"),r=e.lastIndexOf("/"),n=e.slice(0,t),s=e.slice(t+1,r),i=e.slice(r+1);if(t<0||t===r||!hRt.test(n)||!tQe(s)||!tQe(i))throw new Error(`"${e}" is not an Azure DevOps organization/project/repository`);return{organization:n,project:s,name:i}}function rQe(e,t){let r=y5(e);if(r.toLowerCase()!==t.organization.toLowerCase())throw new Error(`${t.organization}/${t.project}/${t.name} is not in ${r}, the Azure DevOps organization this job runs in`)}function nQe(e,t){return rQe(e,t),`${ax(e)}/${encodeURIComponent(t.project)}/_git/${encodeURIComponent(t.name)}`}function E5(e,t){return rQe(e,t),`${ax(e)}/${encodeURIComponent(t.project)}/_apis/git/repositories/${encodeURIComponent(t.name)}`}var gRt="7.1",ox=class extends Error{constructor(r,n){super(r);this.status=n}status};async function w5(e){let t=e.accept??"application/json",r=new URL(e.url);r.searchParams.has("api-version")||r.searchParams.set("api-version",gRt);let n=await(e.fetch??fetch)(r.toString(),{method:e.method??"GET",headers:{Authorization:`Bearer ${e.token}`,Accept:t,...e.body!==void 0?{"Content-Type":"application/json"}:{}},...e.body!==void 0?{body:JSON.stringify(e.body)}:{},redirect:"error",signal:AbortSignal.timeout(3e4)});if(!n.ok){let s=(await n.json().catch(()=>({}))).message;throw new ox(`Azure DevOps answered ${n.status}${typeof s=="string"?`: ${s}`:""}`,n.status)}return t!=="application/json"?Buffer.from(await n.arrayBuffer()):n.status===204?{}:await n.json()}function ARt(e){return`AUTHORIZATION: bearer ${e}`}function sQe(e,t){return{GIT_CONFIG_COUNT:"1",GIT_CONFIG_KEY_0:`http.${ax(e)}/.extraheader`,GIT_CONFIG_VALUE_0:ARt(t)}}var yRt="7.1-preview.1",bRt=".azure-pipelines/skyramp-testbot-v3.yml";function rg(e){return e.GITHUB_ACTIONS!=="true"&&/^true$/i.test(e.TF_BUILD??"")}var ERt={INPUT_PIPELINE:"SKYRAMP_TESTBOT_PIPELINE",INPUT_SKYRAMPRUNID:"SKYRAMP_RUN_ID",INPUT_SKYRAMPAPPORIGIN:"SKYRAMP_APP_ORIGIN",INPUT_SKYRAMPMCPVERSION:"SKYRAMP_MCP_VERSION",INPUT_SKYRAMPMCPSOURCE:"SKYRAMP_MCP_SOURCE",INPUT_SKYRAMPMCPGITHUBREF:"SKYRAMP_MCP_GITHUB_REF",INPUT_SKYRAMPMCPGITHUBTOKEN:"SKYRAMP_MCP_GITHUB_TOKEN",INPUT_USEBEDROCK:"SKYRAMP_USE_BEDROCK",INPUT_AWSREGION:"SKYRAMP_AWS_REGION",INPUT_AWSROLEARN:"SKYRAMP_AWS_ROLE_ARN"};function aQe(e=process.env){if(rg(e))for(let[t,r]of Object.entries(ERt))!e[t]&&e[r]!==void 0&&(e[t]=e[r])}function cQe(e,t={}){let r=d=>{let p=e[d];if(!p)throw new Error(`${d} is not set; the V3 runner handshake needs it`);return p},n=ax(e.SYSTEM_COLLECTIONURI??""),s=()=>y5(r("SYSTEM_COLLECTIONURI")),i=e.SYSTEM_TEAMPROJECT,o=e.BUILD_REPOSITORY_NAME,a=e.BUILD_REPOSITORY_ID?.toLowerCase(),c=e.SYSTEM_ACCESSTOKEN,l=t.mask??(d=>ZPe(d)),u=d=>async()=>{if(!d)throw new Error("The job cannot request an OIDC token: the Testbot step's env must set SYSTEM_OIDCREQUESTURI to $(System.OidcRequestUri).");if(!c)throw new Error("The job cannot request an OIDC token: the Testbot step's env must set SYSTEM_ACCESSTOKEN to $(System.AccessToken).");let p=new URL(d);if(p.protocol!=="https:")throw new Error("SYSTEM_OIDCREQUESTURI is not an https URL");p.searchParams.set("api-version",yRt);let f=await(t.fetch??fetch)(p.toString(),{method:"POST",headers:{Authorization:`Bearer ${c}`,"Content-Type":"application/json",Accept:"application/json"},body:"{}",redirect:"error",signal:AbortSignal.timeout(3e4)});if(!f.ok)throw new Error(`Azure DevOps refused the OIDC token request: ${f.status}`);let h=(await f.json().catch(()=>({}))).oidcToken;if(typeof h!="string"||!h)throw new Error("Azure DevOps's OIDC token response carried no token");return l(h),h};return{runnerPlatform:rg(e)?"azure":void 0,workspace:e.BUILD_SOURCESDIRECTORY||void 0,serverUrl:n,apiUrl:n,repository:a&&i&&o&&n?{id:a,slug:`${s()}/${i}/${o}`}:void 0,runId:e.BUILD_BUILDID||void 0,runAttempt:e.SYSTEM_STAGEATTEMPT||void 0,job:e.SYSTEM_JOBNAME||void 0,execution(){let d=r("SYSTEM_STAGEATTEMPT");if(!/^[1-9][0-9]*$/.test(d))throw new Error(`SYSTEM_STAGEATTEMPT is "${d}", not a positive whole number`);let p=r("SYSTEM_COLLECTIONID").toLowerCase();if(!hE.test(p))throw new Error(`SYSTEM_COLLECTIONID is "${p}", not a GUID`);let f=r("BUILD_REPOSITORY_ID").toLowerCase();if(!hE.test(f))throw new Error(`BUILD_REPOSITORY_ID is "${f}", not a GUID`);let h=[s(),r("SYSTEM_TEAMPROJECT"),r("SYSTEM_DEFINITIONID"),r("BUILD_BUILDID")].map(encodeURIComponent).join("/");return{provider:"azure-devops",repository:{provider:"azure-devops",providerAccountId:p,providerRepositoryId:f},providerRunId:h,providerRunAttempt:Number(d),workflowRef:`${bRt}@${r("BUILD_SOURCEBRANCH")}`}},takeIdToken(){let d=e.SYSTEM_OIDCREQUESTURI;delete e.SYSTEM_OIDCREQUESTURI;let p=u(d);return()=>p()},takeSourceToken(){return delete e.SYSTEM_ACCESSTOKEN,c||void 0},webIdentity(){if(!e.SYSTEM_OIDCREQUESTURI?.trim()||!c)return;let d=u(e.SYSTEM_OIDCREQUESTURI);return{token:()=>d(),runId:e.BUILD_BUILDID}},v3RunsOnly:!0,assumesBedrockRole:!0,namesSourceToMcp:!0,checkSourceName(d){LD(d)},cloneUrl(d){return nQe(n,LD(d))},gitAuthEnv(d){return sQe(n,d)},async pullRequest(d,p,f){let h=await w5({token:await f.token(),url:`${E5(n,LD(d))}/pullrequests/${p}`,fetch:f.fetch}),A=h.status==="completed";return{...typeof h.title=="string"?{title:h.title}:{},...typeof h.description=="string"?{body:h.description}:{},...typeof h.status=="string"?{merged:A}:{},...A&&typeof h.lastMergeCommit?.commitId=="string"?{mergeCommit:h.lastMergeCommit.commitId}:{},...A&&typeof h.lastMergeSourceCommit?.commitId=="string"?{mergedHead:h.lastMergeSourceCommit.commitId}:{}}},async commit(d,p,f){let h;try{h=E5(n,b5(d))}catch{return{lookup:"unknown"}}try{let A=await w5({token:await f.token(),url:`${h}/commits/${encodeURIComponent(p)}`,fetch:f.fetch});return typeof A.commitId=="string"?{sha:A.commitId}:{lookup:"missing"}}catch(A){return{lookup:A instanceof ox&&(A.status===404||A.status===400)?"missing":"unknown"}}}}}ft();var wRt=5e3,C5=/^(?!\.\.?$)[A-Za-z0-9._-]{1,100}$/;function lQe(e){let t=Buffer.from(`x-access-token:${e}`).toString("base64");return Qs(t),`AUTHORIZATION: basic ${t}`}function uQe(e,t={}){let r=c=>{let l=e[c];if(!l)throw new Error(`${c} is not set; the V3 runner handshake needs it`);return l},n=e.GITHUB_REPOSITORY_ID,s=e.GITHUB_REPOSITORY,i=(e.GITHUB_SERVER_URL||"https://github.com").replace(/\/+$/,""),o=(e.GITHUB_API_URL||"https://api.github.com").replace(/\/+$/,""),a=async(c,l)=>l.fetch(c,{headers:{Authorization:`Bearer ${await l.token()}`,Accept:"application/vnd.github+json"},redirect:"error",signal:AbortSignal.timeout(3e4)});return{runnerPlatform:e.GITHUB_ACTIONS==="true"?"github":void 0,workspace:e.GITHUB_WORKSPACE||void 0,serverUrl:i,apiUrl:o,repository:n&&s?{id:n,slug:s}:void 0,runId:e.GITHUB_RUN_ID||void 0,runAttempt:e.GITHUB_RUN_ATTEMPT||void 0,job:e.GITHUB_JOB||void 0,execution(){let c=r("GITHUB_RUN_ATTEMPT");if(!/^[1-9][0-9]*$/.test(c))throw new Error(`GITHUB_RUN_ATTEMPT is "${c}", not a positive whole number`);return{provider:"github",repository:{provider:"github",providerAccountId:r("GITHUB_REPOSITORY_OWNER_ID"),providerRepositoryId:r("GITHUB_REPOSITORY_ID")},providerRunId:r("GITHUB_RUN_ID"),providerRunAttempt:Number(c),workflowRef:r("GITHUB_WORKFLOW_REF")}},takeIdToken(){let c=e.ACTIONS_ID_TOKEN_REQUEST_URL,l=e.ACTIONS_ID_TOKEN_REQUEST_TOKEN;return delete e.ACTIONS_ID_TOKEN_REQUEST_URL,delete e.ACTIONS_ID_TOKEN_REQUEST_TOKEN,async u=>{if(!c||!l)throw new Error("The job cannot request an OIDC token. Give it the `id-token: write` permission.");let d=new URL(c);d.searchParams.set("audience",u);let p=await fetch(d,{headers:{Authorization:`Bearer ${l}`,Accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(3e4)});if(!p.ok)throw new Error(`GitHub refused the OIDC token request: ${p.status}`);let f=(await p.json().catch(()=>({}))).value;if(typeof f!="string"||!f)throw new Error("GitHub's OIDC token response carried no token");return Qs(f),f}},webIdentity(){return!e.ACTIONS_ID_TOKEN_REQUEST_TOKEN?.trim()||!e.ACTIONS_ID_TOKEN_REQUEST_URL?.trim()?void 0:{token:t.getIDToken??(l=>dse(l)),runId:e.GITHUB_RUN_ID}},v3RunsOnly:!1,assumesBedrockRole:!1,namesSourceToMcp:!1,checkSourceName(c){for(let l of[c.namespace,c.name])if(!C5.test(l))throw new Error(`"${l}" is not a repository name`)},cloneUrl(c){return`${i}/${c.namespace}/${c.name}.git`},gitAuthEnv(c){return c?{GIT_CONFIG_COUNT:"1",GIT_CONFIG_KEY_0:`http.${i}/.extraheader`,GIT_CONFIG_VALUE_0:lQe(c)}:{}},async pullRequest({namespace:c,name:l},u,d){if(![c,l].every(h=>C5.test(h)))throw new Error("the repository name is not valid");let p=await a(`${o}/repos/${c}/${l}/pulls/${u}`,d);if(!p.ok)throw new Error(`GitHub answered ${p.status}`);let f=await p.json();return{...typeof f.title=="string"?{title:f.title}:{},...typeof f.body=="string"?{body:f.body}:{},...typeof f.merged=="boolean"?{merged:f.merged}:{},...f.merged===!0&&typeof f.merge_commit_sha=="string"?{mergeCommit:f.merge_commit_sha}:{},...f.merged===!0&&typeof f.head?.sha=="string"?{mergedHead:f.head.sha}:{}}},async commit(c,l,u){let[d,p,...f]=c.split("/");if(f.length||![d,p].every(h=>h!==void 0&&C5.test(h)))return{lookup:"unknown"};try{let h=await a(`${o}/repos/${d}/${p}/commits/${encodeURIComponent(l)}`,u);if(h.status===404||h.status===422)return{lookup:"missing"};if(!h.ok)return{lookup:"unknown"};let A=await h.json();return typeof A.sha=="string"?{sha:A.sha}:{lookup:"missing"}}catch{return{lookup:"unknown"}}},async revokeToken(c,l){let u=await l(`${o}/installation/token`,{method:"DELETE",headers:{Authorization:`Bearer ${c}`,Accept:"application/vnd.github+json"},redirect:"error",signal:AbortSignal.timeout(wRt)});if(!u.ok&&u.status!==401)throw new Error(`GitHub answered ${u.status}`)}}}function Fl(e=process.env){return rg(e)?cQe(e):uQe(e)}var CRt=10*6e4;function pQe(e,t){return e.getTime()-t.getTime()-CRt}var Xdr=10*6e4,SRt=3e4,IRt=3,gE=class extends Error{constructor(r,n,s){super(r);this.status=n;this.code=s}status;code},UD=class extends Error{};function vRt(e){let t;try{t=new URL(e)}catch{throw new Error(`skyrampAppOrigin "${e}" is not a URL`)}if(t.protocol!=="https:"||t.origin!==e.replace(/\/+$/,""))throw new Error(`skyrampAppOrigin must be an https origin, got "${e}"`);return t.origin}function xRt(e,t){if(!hE.test(e))throw new Error(`The ${t} "${e}" is not a uuid`);return e}function RRt(e,t,r){throw t<500&&t!==429?new gE(e,t,r):new UD(e)}async function kRt(e,t,r,n){let s=vRt(e.origin),i;for(let o=1;o<=IRt;o+=1){o>1&&await new Promise(a=>setTimeout(a,(e.retryDelayMs??2e3)*(o-1)));try{let a=await e.idToken(s),c=await(e.fetch??fetch)(new URL(t,s).toString(),{...r(a),redirect:"error",signal:AbortSignal.timeout(SRt)}).catch(l=>{throw new UD(l instanceof Error?l.message:String(l),{cause:l})});return await n(c)}catch(a){if(a instanceof gE)throw a;i=a}}throw i}function TRt(e,t,r,n){return kRt(e,r,i=>({method:t,headers:{Authorization:`Bearer ${i}`,"Content-Type":"application/json",Accept:"application/json"},body:t==="GET"?void 0:JSON.stringify(n)}),async i=>{let o=await i.json().catch(()=>({}));if(i.ok)return o.data;let a=o.error?.fields,c=typeof a?.path=="string"&&typeof a.reason=="string"?` at ${a.path}: ${a.reason}`:"",l=`The Skyramp app refused ${t} ${r}: ${i.status} ${o.error?.code??"no error code"}${c}`;return RRt(l,i.status,o.error?.code)})}var Zdr=10*6e4;var epr=["TRIGGER","AUTHORITATIVE_RELATED_CHANGE"];var tpr=g.object({tests:g.object({placements:g.array(g.unknown()).optional()}).passthrough().optional()}).passthrough(),rpr=g.object({repository:o5,testType:g.nativeEnum(xm),directory:g.string()}).passthrough();var npr=g.object({report:g.object({language:g.string()}).passthrough()}).passthrough();var spr=g.object({environment:g.object({components:g.array(g.unknown()).optional(),dependencies:g.array(g.unknown()).optional()}).passthrough()}).passthrough(),ipr=g.object({name:g.string().min(1),provision:g.literal("existing"),url:g.string().min(1),repository:o5.optional(),revisionUrl:g.string().min(1).optional()}).passthrough(),opr=g.object({name:g.string().min(1),url:g.string().nullable(),versionUrl:g.string().nullable(),notes:g.string().nullable()}).passthrough();var apr=new Set(["TRIGGER","AUTHORITATIVE_RELATED_CHANGE","MANUAL_OVERRIDE"]);async function fQe(e,t){return xRt(e.attemptId,"attempt id"),TRt(t,"POST",`/api/v1/runner/attempts/${e.attemptId}/end`,jPe({reportUploaded:e.reportUploaded,recipeUploaded:e.recipeUploaded,revisionsUploaded:e.revisionsUploaded,cancelled:e.cause==="cancelled",timedOut:e.cause==="timed_out",setupFailed:e.cause==="setup_failed",checkoutFailed:e.cause==="checkout_failed",environmentUnverified:e.cause==="environment_unverified",credentialMissing:e.cause==="credential_missing"}))}var NRt={focused:"Focused",impacted_critical:"Impacted and critical",broad:"Broad"};function cx(e,t){return Xa(e,t).length+(e.relatedChanges??[]).filter(r=>r.note).length}function lx(e,t){return e.confirmedRunId===null&&e.initialBaselineId===null?"first_qualification":t>0?"delta":"unchanged"}var S5="nothing changed since the baseline, so there is nothing to validate",hQe="Nothing changed since the baseline, so there was nothing to validate: this run validated nothing.";function _Rt(e,t){return e!==void 0&&lx(e,t)==="unchanged"}function I5(e){let t=sr(e);return t!==void 0&&_Rt(e.inputs.scheduledValidation,cx(t,Qr(e.inputs).slug))}function mQe(e,t){return`No changes since ${e.confirmedRunId?`the Confirmed Baseline (run ${e.confirmedRunId})`:"the Initial Baseline"}: no file changed in ${t.join(", ")}. The Change Set is empty, so there was nothing to validate; Testbot ran no test and wrote none.`}function gQe(){throw new Error(`a scheduled run with no change since its baseline has no frame: ${S5}`)}var AQe=e=>e.depth?` at depth ${NRt[e.depth]}`:"",yQe=e=>e.confirmedRunId?`the Confirmed Baseline (run ${e.confirmedRunId})`:"the Initial Baseline (the heads saved without a run when the schedule was turned on or its setup changed; it was never validated, so do not assume its code works)",PRt="Sweep the configured scope instead of a diff: every repository of the run, its public surface (endpoints, screens, exported functions) and its existing test suites, and list the behaviors they establish, so triage can plan evidence for them. A finding here is a latent defect of the current state.";function bQe(e,t){switch(lx(e,t)){case"first_qualification":return["This is a scheduled validation, first qualification: the policy has no Confirmed Baseline yet, so this run establishes one. It validates the Target's configured state broadly, not a change.",PRt];case"delta":return[`This is a scheduled validation${AQe(e)}. The diff below is everything that changed since ${yQe(e)}, across every source: not one pull request. Review it as the change under validation; there is no PR description.`];case"unchanged":return gQe()}}var QRt="Plan evidence for the behaviors analyze found: run the existing suites (existing_unit), accept current approved CI evidence, and bring up the SUT only where only runtime evidence will do. The existing suites run under runtime_required too. A run that obtains no evidence validated nothing.";function EQe(e,t){switch(lx(e,t)){case"first_qualification":return["Scheduled validation, first qualification: the policy has no Confirmed Baseline yet. Validate the configured scope broadly; this run's success becomes the Confirmed Baseline.",QRt];case"delta":return[`Scheduled validation${AQe(e)}: the files below changed since ${yQe(e)}, across every source. Judge the evidence the policy needs for them, at its depth, as for any change.`];case"unchanged":return gQe()}}var yE=j(require("fs")),qD=j(require("path"));var ux=j(require("fs")),sc=j(require("path")),AE=sc.join(".skyramp","sut"),wQe=sc.join(".skyramp","workspace.yml");function DRt(e){return e.startsWith(`${AE}${sc.sep}`)||e.startsWith(".skyramp/sut/")||e===wQe||e===".skyramp/workspace.yml"||/(^|\/)(docker-compose|compose)[^/]*\.ya?ml$/.test(e)||/(^|\/)Dockerfile[^/]*$/.test(e)||/^\.github\/workflows\//.test(e)}function Eo(e,t,r={}){let n=t.split(/[\\/]+/).filter(Boolean),s=e;for(let[i,o]of n.entries()){s=sc.join(s,o);let a=ux.lstatSync(s,{throwIfNoEntry:!1}),c=i===n.length-1;if(!a||a.isSymbolicLink()||(c?r.directory?!a.isDirectory():!a.isFile():!a.isDirectory()))return}return n.length?s:void 0}function wo(e,t=[]){let r=p=>Eo(e,p),n=r(sc.join(AE,"setup.sh")),s=r(sc.join(AE,"teardown.sh")),i=r(sc.join(AE,"get-auth-token.sh")),o=r(wQe),a,c=r(sc.join(AE,"health.json"));if(c)try{let p=JSON.parse(ux.readFileSync(c,"utf-8"));p&&(p.url||p.command)&&(a=p)}catch{}let l,u=r(sc.join(AE,"deploy-budget.json"));if(u)try{let p=JSON.parse(ux.readFileSync(u,"utf-8"));typeof p?.minutes=="number"&&Number.isFinite(p.minutes)&&p.minutes>0&&(l=p.minutes)}catch{}let d=t.filter(DRt);return{setupScript:n,teardownScript:s,authTokenScript:i,workspaceFile:o,healthHint:a,budgetMinutes:l,present:!!(n||o),staleFiles:d,stale:d.length>0}}function v5(e,t){let{value:r,error:n}=Xt(e);if(n)return{errors:[n]};let s=t&&!t.testEnvironment?ORt(r,t):r,i=Sb(s)&&s.schemaVersion===void 0?{schemaVersion:1,...s}:s,{value:o,errors:a}=Ib(dv,x4,i);return o?{onboard:o,errors:[]}:{errors:a}}function ORt(e,t){if(!Sb(e))return e;let{environment:r,...n}=e,s=[...t.repositorySlug?[{slug:t.repositorySlug,path:t.repositoryPath}]:[],...(t.relatedRepos??[]).map(a=>({slug:a.slug,path:a.path}))],i=a=>typeof a=="string"?s.find(c=>Eo(c.path,a))?.slug:void 0,o=Array.isArray(n.components)?n.components.map(a=>{if(!Sb(a))return a;let{deployed:c,...l}=a;if(l.repository!==Vn)return l;let u=Sb(l.from)?l.from.file:void 0,d=i(u)??s[0]?.slug;return d?{...l,repository:d}:l}):n.components;return{...n,components:o}}var $D=".skyramp/sut/health.json",MRt={[$D]:`${$D} (with a url or command)`,".skyramp/workspace.yml":".skyramp/workspace.yml (create it with skyramp_init_scan and skyramp_init_workspace)"};function CQe(){return{name:"onboard-recipe",verify(e,t){let{onboard:r,errors:n}=v5(t.stdout,e.inputs);if(!r)return ce(this.name,n,{fatal:!0});let s=r.environment!==void 0;if(r.status==="blocked")return{name:this.name,passed:!0};let i=e.inputs.repositoryPath,o=wo(i),a=s?ex.filter(u=>Eo(i,u)):[];if(a.length>0)return ce(this.name,[`an answer with "environment" tests a deployment where it runs and never starts or stops it: delete ${a.join(" and ")}, keep the health check, and answer "ready" again`]);let l=(s?mPe:hPe).filter(u=>!Eo(i,u)).map(u=>MRt[u]??u);return Eo(i,$D)&&!o.healthHint&&l.push(`${$D} (with a url or command)`),o.present&&l.length===0?{name:this.name,passed:!0}:ce(this.name,[`status is "ready" but the recipe deploy replays is incomplete in ${e.inputs.repositoryPath} \u2014 missing (each must be a regular file, not a symlink): ${l.join(", ")}. Write the missing files as the skill specifies and answer "ready" again, or answer "blocked" with the blocker that stopped you.`])}}}function SQe(){return{name:"deployed-revisions",async verify(e,t){let r={name:this.name,passed:!0},n=e.checkDeployedRevisions;if(!n)return r;let{onboard:s}=v5(t.stdout,e.inputs);if(!s?.environment||s.status==="blocked")return r;let i=xQ(x5(e.inputs.repositoryPath).recipeFiles);if(!i)return r;let o=k4(s.components.map(({name:l,repository:u})=>({name:l,repository:u})),s.environment.revisionSources),{blockers:a}=await n(i.content,o,s.environment.credentials);if(a.length===0)return r;let c=a.map(l=>`${l.component}: ${l.problem} (${l.evidence})`).join("; ");return{...r,details:`${Pb} could not prove every revision, so those are kept as unknown, each a problem on the Ready setup: ${c}`}}}}function FRt(e){try{return new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(e)}catch{return}}function x5(e){let t=[],r=o=>{let a;try{a=yE.readdirSync(qD.join(e,o),{withFileTypes:!0})}catch{return}for(let c of a.sort((l,u)=>l.name.localeCompare(u.name))){let l=qD.posix.join(o,c.name);c.isDirectory()&&!c.name.startsWith(".")?r(l):c.isFile()&&t.push(l)}};Eo(e,".skyramp/sut",{directory:!0})&&r(".skyramp/sut"),Eo(e,".skyramp/workspace.yml")&&t.push(".skyramp/workspace.yml");let n=[],s=[],i=0;for(let o of t){let a=Eo(e,o);if(!a)continue;let l=yE.statSync(a).size;if(l>Pm){s.push({path:o,reason:`larger than ${Pm} bytes`});continue}if(i+l>Qm){s.push({path:o,reason:`recipe text over ${Qm} bytes in total`});continue}let u=FRt(yE.readFileSync(a));if(u===void 0||vQ.test(u)){s.push({path:o,reason:"not text"});continue}n.push({path:o,content:u}),i+=l}return{recipeFiles:n,recipeFilesOmitted:s}}function IQe(e,t){let{onboard:r,errors:n}=v5(t.stdout,e.inputs),s=r&&{...r,...x5(e.inputs.repositoryPath)};return ot(e,"onboard",gr(s,e.secretValues??[]),n)}function GD(e){if(e.state.stages.onboard?.status==="passed")return ee(e,"onboard.json")}var Npr=20*1024*1024;var Ll=j(require("fs")),bE=j(require("path"));var URt=[/^\.github\//,/^\.gitlab(-ci)?/,/^\.circleci\//,/(^|\/)Jenkinsfile$/,/^docs?\//,/\.(md|mdx|rst)$/i,/(^|\/)LICENSE([._-].*)?$/i,/(^|\/)CODEOWNERS$/,/(^|\/)\.gitignore$/,/(^|\/)\.gitattributes$/,/(^|\/)\.editorconfig$/,/(^|\/)\.prettierrc[^/]*$/,/(^|\/)\.eslintrc[^/]*$/,/(^|\/)eslint\.config\.[^/]+$/,/(^|\/)package-lock\.json$/,/(^|\/)yarn\.lock$/,/(^|\/)pnpm-lock\.yaml$/,/(^|\/)poetry\.lock$/,/(^|\/)Pipfile\.lock$/,/(^|\/)Cargo\.lock$/,/(^|\/)go\.sum$/,/(^|\/)composer\.lock$/,/(^|\/)Gemfile\.lock$/,/\.(png|jpe?g|gif|svg|ico|webp)$/i];function $Rt(e){return URt.some(t=>t.test(e))}function qRt(e){let t=[],r=e.inputs.repositoryPath;return!r||!Ll.existsSync(r)?t.push(`repository path does not exist: ${r}`):wv(r)?Fb(r,e.inputs.baseBranch)||t.push(e.inputs.baseBranch?`base branch "${e.inputs.baseBranch}" does not resolve`:"could not auto-detect a base branch (origin/HEAD, main, master)"):t.push(`not a git repository: ${r}`),{ok:t.length===0,reasons:t}}function GRt(e){return(e.inputs.relatedRepos??[]).map(t=>{let r=Ll.existsSync(t.path)?rf(t.path):void 0;return r?{repository:t.slug,changedFiles:r.changedFiles}:{repository:t.slug,changedFiles:[],note:`could not read the change in ${t.path}`}})}function HRt(e){let{repositoryPath:t,baseBranch:r}=e.inputs;Ll.rmSync(bE.join(t,Dr),{recursive:!0,force:!0});let n=rf(t,r);if(!n)throw new Error(`could not compute git facts for ${t}`);let s=Cv(t,r);if(!s)throw new Error(`could not compute the PR diff for ${t}`);let i=GRt(e),o=[n.changedFiles,...i.map(d=>d.changedFiles)].flat(),a=o.map(d=>d.path).filter($Rt),c=o.length>0&&a.length===o.length,l={schemaVersion:1,repository:{path:t,currentBranch:n.currentBranch,baseBranch:n.baseBranch},changedFiles:n.changedFiles,...i.length?{relatedChanges:i}:{},newFiles:s.newFiles,deletedFiles:s.deletedFiles,diffStat:s.diffStat,diffBytes:s.diffContent.length,nonApplicationFiles:a,nonApplicationOnly:c,sutRequired:!c};Ll.writeFileSync(bE.join(e.runDir,Rm),s.diffContent);let u=bE.join(e.runDir,g4);return Ll.mkdirSync(bE.dirname(u),{recursive:!0}),Ll.writeFileSync(u,JSON.stringify(l,null,2)+`
|
|
335
|
+
`)[0]}`];case"endgroup":return["##[endgroup]"];default:return[]}}function ax(e){return e.replace(/\/+$/,"")}function y5(e){let t=new URL(e),r=t.pathname.split("/").filter(Boolean);if(r.length)return decodeURIComponent(r[r.length-1]);if(t.hostname.endsWith(".visualstudio.com"))return t.hostname.split(".")[0];throw new Error(`SYSTEM_COLLECTIONURI "${e}" names no organization`)}var hRt=/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,48}[A-Za-z0-9])?$/,mRt=/[\\/:*?"<>|;#${},+=[\]%\p{Cc}\p{Cf}]/u;function tQe(e){return e.length>0&&e.length<=64&&e===e.trim()&&!mRt.test(e)&&!/[^\S ]/u.test(e)&&!/^[._]/.test(e)&&!e.endsWith(".")}function LD(e){return b5(`${e.namespace}/${e.name}`)}function b5(e){let t=e.indexOf("/"),r=e.lastIndexOf("/"),n=e.slice(0,t),s=e.slice(t+1,r),i=e.slice(r+1);if(t<0||t===r||!hRt.test(n)||!tQe(s)||!tQe(i))throw new Error(`"${e}" is not an Azure DevOps organization/project/repository`);return{organization:n,project:s,name:i}}function rQe(e,t){let r=y5(e);if(r.toLowerCase()!==t.organization.toLowerCase())throw new Error(`${t.organization}/${t.project}/${t.name} is not in ${r}, the Azure DevOps organization this job runs in`)}function nQe(e,t){return rQe(e,t),`${ax(e)}/${encodeURIComponent(t.project)}/_git/${encodeURIComponent(t.name)}`}function E5(e,t){return rQe(e,t),`${ax(e)}/${encodeURIComponent(t.project)}/_apis/git/repositories/${encodeURIComponent(t.name)}`}var gRt="7.1",ox=class extends Error{constructor(r,n){super(r);this.status=n}status};async function w5(e){let t=e.accept??"application/json",r=new URL(e.url);r.searchParams.has("api-version")||r.searchParams.set("api-version",gRt);let n=await(e.fetch??fetch)(r.toString(),{method:e.method??"GET",headers:{Authorization:`Bearer ${e.token}`,Accept:t,...e.body!==void 0?{"Content-Type":"application/json"}:{}},...e.body!==void 0?{body:JSON.stringify(e.body)}:{},redirect:"error",signal:AbortSignal.timeout(3e4)});if(!n.ok){let s=(await n.json().catch(()=>({}))).message;throw new ox(`Azure DevOps answered ${n.status}${typeof s=="string"?`: ${s}`:""}`,n.status)}return t!=="application/json"?Buffer.from(await n.arrayBuffer()):n.status===204?{}:await n.json()}function ARt(e){return`AUTHORIZATION: bearer ${e}`}function sQe(e,t){return{GIT_CONFIG_COUNT:"1",GIT_CONFIG_KEY_0:`http.${ax(e)}/.extraheader`,GIT_CONFIG_VALUE_0:ARt(t)}}var yRt="7.1-preview.1",bRt=".azure-pipelines/skyramp-testbot-v3.yml";function rg(e){return e.GITHUB_ACTIONS!=="true"&&/^true$/i.test(e.TF_BUILD??"")}var ERt={INPUT_PIPELINE:"SKYRAMP_TESTBOT_PIPELINE",INPUT_SKYRAMPRUNID:"SKYRAMP_RUN_ID",INPUT_SKYRAMPAPPORIGIN:"SKYRAMP_APP_ORIGIN",INPUT_SKYRAMPMCPVERSION:"SKYRAMP_MCP_VERSION",INPUT_SKYRAMPMCPSOURCE:"SKYRAMP_MCP_SOURCE",INPUT_SKYRAMPMCPGITHUBREF:"SKYRAMP_MCP_GITHUB_REF",INPUT_SKYRAMPMCPGITHUBTOKEN:"SKYRAMP_MCP_GITHUB_TOKEN",INPUT_USEBEDROCK:"SKYRAMP_USE_BEDROCK",INPUT_AWSREGION:"SKYRAMP_AWS_REGION",INPUT_AWSROLEARN:"SKYRAMP_AWS_ROLE_ARN"};function aQe(e=process.env){if(rg(e))for(let[t,r]of Object.entries(ERt))!e[t]&&e[r]!==void 0&&(e[t]=e[r])}function cQe(e,t={}){let r=d=>{let p=e[d];if(!p)throw new Error(`${d} is not set; the V3 runner handshake needs it`);return p},n=ax(e.SYSTEM_COLLECTIONURI??""),s=()=>y5(r("SYSTEM_COLLECTIONURI")),i=e.SYSTEM_TEAMPROJECT,o=e.BUILD_REPOSITORY_NAME,a=e.BUILD_REPOSITORY_ID?.toLowerCase(),c=e.SYSTEM_ACCESSTOKEN,l=t.mask??(d=>ZPe(d)),u=d=>async()=>{if(!d)throw new Error("The job cannot request an OIDC token: the Testbot step's env must set SYSTEM_OIDCREQUESTURI to $(System.OidcRequestUri).");if(!c)throw new Error("The job cannot request an OIDC token: the Testbot step's env must set SYSTEM_ACCESSTOKEN to $(System.AccessToken).");let p=new URL(d);if(p.protocol!=="https:")throw new Error("SYSTEM_OIDCREQUESTURI is not an https URL");p.searchParams.set("api-version",yRt);let f=await(t.fetch??fetch)(p.toString(),{method:"POST",headers:{Authorization:`Bearer ${c}`,"Content-Type":"application/json",Accept:"application/json"},body:"{}",redirect:"error",signal:AbortSignal.timeout(3e4)});if(!f.ok)throw new Error(`Azure DevOps refused the OIDC token request: ${f.status}`);let h=(await f.json().catch(()=>({}))).oidcToken;if(typeof h!="string"||!h)throw new Error("Azure DevOps's OIDC token response carried no token");return l(h),h};return{runnerPlatform:rg(e)?"azure":void 0,workspace:e.BUILD_SOURCESDIRECTORY||void 0,serverUrl:n,apiUrl:n,repository:a&&i&&o&&n?{id:a,slug:`${s()}/${i}/${o}`}:void 0,runId:e.BUILD_BUILDID||void 0,runAttempt:e.SYSTEM_STAGEATTEMPT||void 0,job:e.SYSTEM_JOBNAME||void 0,execution(){let d=r("SYSTEM_STAGEATTEMPT");if(!/^[1-9][0-9]*$/.test(d))throw new Error(`SYSTEM_STAGEATTEMPT is "${d}", not a positive whole number`);let p=r("SYSTEM_COLLECTIONID").toLowerCase();if(!hE.test(p))throw new Error(`SYSTEM_COLLECTIONID is "${p}", not a GUID`);let f=r("BUILD_REPOSITORY_ID").toLowerCase();if(!hE.test(f))throw new Error(`BUILD_REPOSITORY_ID is "${f}", not a GUID`);let h=[s(),r("SYSTEM_TEAMPROJECT"),r("SYSTEM_DEFINITIONID"),r("BUILD_BUILDID")].map(encodeURIComponent).join("/");return{provider:"azure-devops",repository:{provider:"azure-devops",providerAccountId:p,providerRepositoryId:f},providerRunId:h,providerRunAttempt:Number(d),workflowRef:`${bRt}@${r("BUILD_SOURCEBRANCH")}`}},takeIdToken(){let d=e.SYSTEM_OIDCREQUESTURI;delete e.SYSTEM_OIDCREQUESTURI;let p=u(d);return()=>p()},takeSourceToken(){return delete e.SYSTEM_ACCESSTOKEN,c||void 0},webIdentity(){if(!e.SYSTEM_OIDCREQUESTURI?.trim()||!c)return;let d=u(e.SYSTEM_OIDCREQUESTURI);return{token:()=>d(),runId:e.BUILD_BUILDID}},v3RunsOnly:!0,assumesBedrockRole:!0,namesSourceToMcp:!0,checkSourceName(d){LD(d)},cloneUrl(d){return nQe(n,LD(d))},gitAuthEnv(d){return sQe(n,d)},async pullRequest(d,p,f){let h=await w5({token:await f.token(),url:`${E5(n,LD(d))}/pullrequests/${p}`,fetch:f.fetch}),A=h.status==="completed";return{...typeof h.title=="string"?{title:h.title}:{},...typeof h.description=="string"?{body:h.description}:{},...typeof h.status=="string"?{merged:A}:{},...A&&typeof h.lastMergeCommit?.commitId=="string"?{mergeCommit:h.lastMergeCommit.commitId}:{},...A&&typeof h.lastMergeSourceCommit?.commitId=="string"?{mergedHead:h.lastMergeSourceCommit.commitId}:{}}},async commit(d,p,f){let h;try{h=E5(n,b5(d))}catch{return{lookup:"unknown"}}try{let A=await w5({token:await f.token(),url:`${h}/commits/${encodeURIComponent(p)}`,fetch:f.fetch});return typeof A.commitId=="string"?{sha:A.commitId}:{lookup:"missing"}}catch(A){return{lookup:A instanceof ox&&(A.status===404||A.status===400)?"missing":"unknown"}}}}}ft();var wRt=5e3,C5=/^(?!\.\.?$)[A-Za-z0-9._-]{1,100}$/;function lQe(e){let t=Buffer.from(`x-access-token:${e}`).toString("base64");return Qs(t),`AUTHORIZATION: basic ${t}`}function uQe(e,t={}){let r=c=>{let l=e[c];if(!l)throw new Error(`${c} is not set; the V3 runner handshake needs it`);return l},n=e.GITHUB_REPOSITORY_ID,s=e.GITHUB_REPOSITORY,i=(e.GITHUB_SERVER_URL||"https://github.com").replace(/\/+$/,""),o=(e.GITHUB_API_URL||"https://api.github.com").replace(/\/+$/,""),a=async(c,l)=>l.fetch(c,{headers:{Authorization:`Bearer ${await l.token()}`,Accept:"application/vnd.github+json"},redirect:"error",signal:AbortSignal.timeout(3e4)});return{runnerPlatform:e.GITHUB_ACTIONS==="true"?"github":void 0,workspace:e.GITHUB_WORKSPACE||void 0,serverUrl:i,apiUrl:o,repository:n&&s?{id:n,slug:s}:void 0,runId:e.GITHUB_RUN_ID||void 0,runAttempt:e.GITHUB_RUN_ATTEMPT||void 0,job:e.GITHUB_JOB||void 0,execution(){let c=r("GITHUB_RUN_ATTEMPT");if(!/^[1-9][0-9]*$/.test(c))throw new Error(`GITHUB_RUN_ATTEMPT is "${c}", not a positive whole number`);return{provider:"github",repository:{provider:"github",providerAccountId:r("GITHUB_REPOSITORY_OWNER_ID"),providerRepositoryId:r("GITHUB_REPOSITORY_ID")},providerRunId:r("GITHUB_RUN_ID"),providerRunAttempt:Number(c),workflowRef:r("GITHUB_WORKFLOW_REF")}},takeIdToken(){let c=e.ACTIONS_ID_TOKEN_REQUEST_URL,l=e.ACTIONS_ID_TOKEN_REQUEST_TOKEN;return delete e.ACTIONS_ID_TOKEN_REQUEST_URL,delete e.ACTIONS_ID_TOKEN_REQUEST_TOKEN,async u=>{if(!c||!l)throw new Error("The job cannot request an OIDC token. Give it the `id-token: write` permission.");let d=new URL(c);d.searchParams.set("audience",u);let p=await fetch(d,{headers:{Authorization:`Bearer ${l}`,Accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(3e4)});if(!p.ok)throw new Error(`GitHub refused the OIDC token request: ${p.status}`);let f=(await p.json().catch(()=>({}))).value;if(typeof f!="string"||!f)throw new Error("GitHub's OIDC token response carried no token");return Qs(f),f}},webIdentity(){return!e.ACTIONS_ID_TOKEN_REQUEST_TOKEN?.trim()||!e.ACTIONS_ID_TOKEN_REQUEST_URL?.trim()?void 0:{token:t.getIDToken??(l=>dse(l)),runId:e.GITHUB_RUN_ID}},v3RunsOnly:!1,assumesBedrockRole:!1,namesSourceToMcp:!1,checkSourceName(c){for(let l of[c.namespace,c.name])if(!C5.test(l))throw new Error(`"${l}" is not a repository name`)},cloneUrl(c){return`${i}/${c.namespace}/${c.name}.git`},gitAuthEnv(c){return c?{GIT_CONFIG_COUNT:"1",GIT_CONFIG_KEY_0:`http.${i}/.extraheader`,GIT_CONFIG_VALUE_0:lQe(c)}:{}},async pullRequest({namespace:c,name:l},u,d){if(![c,l].every(h=>C5.test(h)))throw new Error("the repository name is not valid");let p=await a(`${o}/repos/${c}/${l}/pulls/${u}`,d);if(!p.ok)throw new Error(`GitHub answered ${p.status}`);let f=await p.json();return{...typeof f.title=="string"?{title:f.title}:{},...typeof f.body=="string"?{body:f.body}:{},...typeof f.merged=="boolean"?{merged:f.merged}:{},...f.merged===!0&&typeof f.merge_commit_sha=="string"?{mergeCommit:f.merge_commit_sha}:{},...f.merged===!0&&typeof f.head?.sha=="string"?{mergedHead:f.head.sha}:{}}},async commit(c,l,u){let[d,p,...f]=c.split("/");if(f.length||![d,p].every(h=>h!==void 0&&C5.test(h)))return{lookup:"unknown"};try{let h=await a(`${o}/repos/${d}/${p}/commits/${encodeURIComponent(l)}`,u);if(h.status===404||h.status===422)return{lookup:"missing"};if(!h.ok)return{lookup:"unknown"};let A=await h.json();return typeof A.sha=="string"?{sha:A.sha}:{lookup:"missing"}}catch{return{lookup:"unknown"}}},async revokeToken(c,l){let u=await l(`${o}/installation/token`,{method:"DELETE",headers:{Authorization:`Bearer ${c}`,Accept:"application/vnd.github+json"},redirect:"error",signal:AbortSignal.timeout(wRt)});if(!u.ok&&u.status!==401)throw new Error(`GitHub answered ${u.status}`)}}}function Fl(e=process.env){return rg(e)?cQe(e):uQe(e)}var CRt=10*6e4;function pQe(e,t){return e.getTime()-t.getTime()-CRt}var Xdr=10*6e4;var SRt=3e4,IRt=3,gE=class extends Error{constructor(r,n,s){super(r);this.status=n;this.code=s}status;code},UD=class extends Error{};function vRt(e){let t;try{t=new URL(e)}catch{throw new Error(`skyrampAppOrigin "${e}" is not a URL`)}if(t.protocol!=="https:"||t.origin!==e.replace(/\/+$/,""))throw new Error(`skyrampAppOrigin must be an https origin, got "${e}"`);return t.origin}function xRt(e,t){if(!hE.test(e))throw new Error(`The ${t} "${e}" is not a uuid`);return e}function RRt(e,t,r){throw t<500&&t!==429?new gE(e,t,r):new UD(e)}async function kRt(e,t,r,n){let s=vRt(e.origin),i;for(let o=1;o<=IRt;o+=1){o>1&&await new Promise(a=>setTimeout(a,(e.retryDelayMs??2e3)*(o-1)));try{let a=await e.idToken(s),c=await(e.fetch??fetch)(new URL(t,s).toString(),{...r(a),redirect:"error",signal:AbortSignal.timeout(SRt)}).catch(l=>{throw new UD(l instanceof Error?l.message:String(l),{cause:l})});return await n(c)}catch(a){if(a instanceof gE)throw a;i=a}}throw i}function TRt(e,t,r,n){return kRt(e,r,i=>({method:t,headers:{Authorization:`Bearer ${i}`,"Content-Type":"application/json",Accept:"application/json"},body:t==="GET"?void 0:JSON.stringify(n)}),async i=>{let o=await i.json().catch(()=>({}));if(i.ok)return o.data;let a=o.error?.fields,c=typeof a?.path=="string"&&typeof a.reason=="string"?` at ${a.path}: ${a.reason}`:"",l=`The Skyramp app refused ${t} ${r}: ${i.status} ${o.error?.code??"no error code"}${c}`;return RRt(l,i.status,o.error?.code)})}var Zdr=10*6e4;var epr=["TRIGGER","AUTHORITATIVE_RELATED_CHANGE"];var tpr=g.object({tests:g.object({placements:g.array(g.unknown()).optional()}).passthrough().optional()}).passthrough(),rpr=g.object({repository:o5,testType:g.nativeEnum(xm),directory:g.string()}).passthrough();var npr=g.object({report:g.object({language:g.string()}).passthrough()}).passthrough();var spr=g.object({environment:g.object({components:g.array(g.unknown()).optional(),dependencies:g.array(g.unknown()).optional()}).passthrough()}).passthrough(),ipr=g.object({name:g.string().min(1),provision:g.literal("existing"),url:g.string().min(1),repository:o5.optional(),revisionUrl:g.string().min(1).optional()}).passthrough(),opr=g.object({name:g.string().min(1),url:g.string().nullable(),versionUrl:g.string().nullable(),notes:g.string().nullable()}).passthrough();var apr=new Set(["TRIGGER","AUTHORITATIVE_RELATED_CHANGE","MANUAL_OVERRIDE"]);async function fQe(e,t){return xRt(e.attemptId,"attempt id"),TRt(t,"POST",`/api/v1/runner/attempts/${e.attemptId}/end`,jPe({reportUploaded:e.reportUploaded,recipeUploaded:e.recipeUploaded,revisionsUploaded:e.revisionsUploaded,cancelled:e.cause==="cancelled",timedOut:e.cause==="timed_out",setupFailed:e.cause==="setup_failed",checkoutFailed:e.cause==="checkout_failed",environmentUnverified:e.cause==="environment_unverified",credentialMissing:e.cause==="credential_missing"}))}var NRt={focused:"Focused",impacted_critical:"Impacted and critical",broad:"Broad"};function cx(e,t){return Xa(e,t).length+(e.relatedChanges??[]).filter(r=>r.note).length}function lx(e,t){return e.confirmedRunId===null&&e.initialBaselineId===null?"first_qualification":t>0?"delta":"unchanged"}var S5="nothing changed since the baseline, so there is nothing to validate",hQe="Nothing changed since the baseline, so there was nothing to validate: this run validated nothing.";function _Rt(e,t){return e!==void 0&&lx(e,t)==="unchanged"}function I5(e){let t=sr(e);return t!==void 0&&_Rt(e.inputs.scheduledValidation,cx(t,Qr(e.inputs).slug))}function mQe(e,t){return`No changes since ${e.confirmedRunId?`the Confirmed Baseline (run ${e.confirmedRunId})`:"the Initial Baseline"}: no file changed in ${t.join(", ")}. The Change Set is empty, so there was nothing to validate; Testbot ran no test and wrote none.`}function gQe(){throw new Error(`a scheduled run with no change since its baseline has no frame: ${S5}`)}var AQe=e=>e.depth?` at depth ${NRt[e.depth]}`:"",yQe=e=>e.confirmedRunId?`the Confirmed Baseline (run ${e.confirmedRunId})`:"the Initial Baseline (the heads saved without a run when the schedule was turned on or its setup changed; it was never validated, so do not assume its code works)",PRt="Sweep the configured scope instead of a diff: every repository of the run, its public surface (endpoints, screens, exported functions) and its existing test suites, and list the behaviors they establish, so triage can plan evidence for them. A finding here is a latent defect of the current state.";function bQe(e,t){switch(lx(e,t)){case"first_qualification":return["This is a scheduled validation, first qualification: the policy has no Confirmed Baseline yet, so this run establishes one. It validates the Target's configured state broadly, not a change.",PRt];case"delta":return[`This is a scheduled validation${AQe(e)}. The diff below is everything that changed since ${yQe(e)}, across every source: not one pull request. Review it as the change under validation; there is no PR description.`];case"unchanged":return gQe()}}var QRt="Plan evidence for the behaviors analyze found: run the existing suites (existing_unit), accept current approved CI evidence, and bring up the SUT only where only runtime evidence will do. The existing suites run under runtime_required too. A run that obtains no evidence validated nothing.";function EQe(e,t){switch(lx(e,t)){case"first_qualification":return["Scheduled validation, first qualification: the policy has no Confirmed Baseline yet. Validate the configured scope broadly; this run's success becomes the Confirmed Baseline.",QRt];case"delta":return[`Scheduled validation${AQe(e)}: the files below changed since ${yQe(e)}, across every source. Judge the evidence the policy needs for them, at its depth, as for any change.`];case"unchanged":return gQe()}}var yE=j(require("fs")),qD=j(require("path"));var ux=j(require("fs")),sc=j(require("path")),AE=sc.join(".skyramp","sut"),wQe=sc.join(".skyramp","workspace.yml");function DRt(e){return e.startsWith(`${AE}${sc.sep}`)||e.startsWith(".skyramp/sut/")||e===wQe||e===".skyramp/workspace.yml"||/(^|\/)(docker-compose|compose)[^/]*\.ya?ml$/.test(e)||/(^|\/)Dockerfile[^/]*$/.test(e)||/^\.github\/workflows\//.test(e)}function Eo(e,t,r={}){let n=t.split(/[\\/]+/).filter(Boolean),s=e;for(let[i,o]of n.entries()){s=sc.join(s,o);let a=ux.lstatSync(s,{throwIfNoEntry:!1}),c=i===n.length-1;if(!a||a.isSymbolicLink()||(c?r.directory?!a.isDirectory():!a.isFile():!a.isDirectory()))return}return n.length?s:void 0}function wo(e,t=[]){let r=p=>Eo(e,p),n=r(sc.join(AE,"setup.sh")),s=r(sc.join(AE,"teardown.sh")),i=r(sc.join(AE,"get-auth-token.sh")),o=r(wQe),a,c=r(sc.join(AE,"health.json"));if(c)try{let p=JSON.parse(ux.readFileSync(c,"utf-8"));p&&(p.url||p.command)&&(a=p)}catch{}let l,u=r(sc.join(AE,"deploy-budget.json"));if(u)try{let p=JSON.parse(ux.readFileSync(u,"utf-8"));typeof p?.minutes=="number"&&Number.isFinite(p.minutes)&&p.minutes>0&&(l=p.minutes)}catch{}let d=t.filter(DRt);return{setupScript:n,teardownScript:s,authTokenScript:i,workspaceFile:o,healthHint:a,budgetMinutes:l,present:!!(n||o),staleFiles:d,stale:d.length>0}}function v5(e,t){let{value:r,error:n}=Xt(e);if(n)return{errors:[n]};let s=t&&!t.testEnvironment?ORt(r,t):r,i=Sb(s)&&s.schemaVersion===void 0?{schemaVersion:1,...s}:s,{value:o,errors:a}=Ib(dv,x4,i);return o?{onboard:o,errors:[]}:{errors:a}}function ORt(e,t){if(!Sb(e))return e;let{environment:r,...n}=e,s=[...t.repositorySlug?[{slug:t.repositorySlug,path:t.repositoryPath}]:[],...(t.relatedRepos??[]).map(a=>({slug:a.slug,path:a.path}))],i=a=>typeof a=="string"?s.find(c=>Eo(c.path,a))?.slug:void 0,o=Array.isArray(n.components)?n.components.map(a=>{if(!Sb(a))return a;let{deployed:c,...l}=a;if(l.repository!==Vn)return l;let u=Sb(l.from)?l.from.file:void 0,d=i(u)??s[0]?.slug;return d?{...l,repository:d}:l}):n.components;return{...n,components:o}}var $D=".skyramp/sut/health.json",MRt={[$D]:`${$D} (with a url or command)`,".skyramp/workspace.yml":".skyramp/workspace.yml (create it with skyramp_init_scan and skyramp_init_workspace)"};function CQe(){return{name:"onboard-recipe",verify(e,t){let{onboard:r,errors:n}=v5(t.stdout,e.inputs);if(!r)return ce(this.name,n,{fatal:!0});let s=r.environment!==void 0;if(r.status==="blocked")return{name:this.name,passed:!0};let i=e.inputs.repositoryPath,o=wo(i),a=s?ex.filter(u=>Eo(i,u)):[];if(a.length>0)return ce(this.name,[`an answer with "environment" tests a deployment where it runs and never starts or stops it: delete ${a.join(" and ")}, keep the health check, and answer "ready" again`]);let l=(s?mPe:hPe).filter(u=>!Eo(i,u)).map(u=>MRt[u]??u);return Eo(i,$D)&&!o.healthHint&&l.push(`${$D} (with a url or command)`),o.present&&l.length===0?{name:this.name,passed:!0}:ce(this.name,[`status is "ready" but the recipe deploy replays is incomplete in ${e.inputs.repositoryPath} \u2014 missing (each must be a regular file, not a symlink): ${l.join(", ")}. Write the missing files as the skill specifies and answer "ready" again, or answer "blocked" with the blocker that stopped you.`])}}}function SQe(){return{name:"deployed-revisions",async verify(e,t){let r={name:this.name,passed:!0},n=e.checkDeployedRevisions;if(!n)return r;let{onboard:s}=v5(t.stdout,e.inputs);if(!s?.environment||s.status==="blocked")return r;let i=xQ(x5(e.inputs.repositoryPath).recipeFiles);if(!i)return r;let o=k4(s.components.map(({name:l,repository:u})=>({name:l,repository:u})),s.environment.revisionSources),{blockers:a}=await n(i.content,o,s.environment.credentials);if(a.length===0)return r;let c=a.map(l=>`${l.component}: ${l.problem} (${l.evidence})`).join("; ");return{...r,details:`${Pb} could not prove every revision, so those are kept as unknown, each a problem on the Ready setup: ${c}`}}}}function FRt(e){try{return new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0}).decode(e)}catch{return}}function x5(e){let t=[],r=o=>{let a;try{a=yE.readdirSync(qD.join(e,o),{withFileTypes:!0})}catch{return}for(let c of a.sort((l,u)=>l.name.localeCompare(u.name))){let l=qD.posix.join(o,c.name);c.isDirectory()&&!c.name.startsWith(".")?r(l):c.isFile()&&t.push(l)}};Eo(e,".skyramp/sut",{directory:!0})&&r(".skyramp/sut"),Eo(e,".skyramp/workspace.yml")&&t.push(".skyramp/workspace.yml");let n=[],s=[],i=0;for(let o of t){let a=Eo(e,o);if(!a)continue;let l=yE.statSync(a).size;if(l>Pm){s.push({path:o,reason:`larger than ${Pm} bytes`});continue}if(i+l>Qm){s.push({path:o,reason:`recipe text over ${Qm} bytes in total`});continue}let u=FRt(yE.readFileSync(a));if(u===void 0||vQ.test(u)){s.push({path:o,reason:"not text"});continue}n.push({path:o,content:u}),i+=l}return{recipeFiles:n,recipeFilesOmitted:s}}function IQe(e,t){let{onboard:r,errors:n}=v5(t.stdout,e.inputs),s=r&&{...r,...x5(e.inputs.repositoryPath)};return ot(e,"onboard",gr(s,e.secretValues??[]),n)}function GD(e){if(e.state.stages.onboard?.status==="passed")return ee(e,"onboard.json")}var Npr=20*1024*1024;var Ll=j(require("fs")),bE=j(require("path"));var URt=[/^\.github\//,/^\.gitlab(-ci)?/,/^\.circleci\//,/(^|\/)Jenkinsfile$/,/^docs?\//,/\.(md|mdx|rst)$/i,/(^|\/)LICENSE([._-].*)?$/i,/(^|\/)CODEOWNERS$/,/(^|\/)\.gitignore$/,/(^|\/)\.gitattributes$/,/(^|\/)\.editorconfig$/,/(^|\/)\.prettierrc[^/]*$/,/(^|\/)\.eslintrc[^/]*$/,/(^|\/)eslint\.config\.[^/]+$/,/(^|\/)package-lock\.json$/,/(^|\/)yarn\.lock$/,/(^|\/)pnpm-lock\.yaml$/,/(^|\/)poetry\.lock$/,/(^|\/)Pipfile\.lock$/,/(^|\/)Cargo\.lock$/,/(^|\/)go\.sum$/,/(^|\/)composer\.lock$/,/(^|\/)Gemfile\.lock$/,/\.(png|jpe?g|gif|svg|ico|webp)$/i];function $Rt(e){return URt.some(t=>t.test(e))}function qRt(e){let t=[],r=e.inputs.repositoryPath;return!r||!Ll.existsSync(r)?t.push(`repository path does not exist: ${r}`):wv(r)?Fb(r,e.inputs.baseBranch)||t.push(e.inputs.baseBranch?`base branch "${e.inputs.baseBranch}" does not resolve`:"could not auto-detect a base branch (origin/HEAD, main, master)"):t.push(`not a git repository: ${r}`),{ok:t.length===0,reasons:t}}function GRt(e){return(e.inputs.relatedRepos??[]).map(t=>{let r=Ll.existsSync(t.path)?rf(t.path):void 0;return r?{repository:t.slug,changedFiles:r.changedFiles}:{repository:t.slug,changedFiles:[],note:`could not read the change in ${t.path}`}})}function HRt(e){let{repositoryPath:t,baseBranch:r}=e.inputs;Ll.rmSync(bE.join(t,Dr),{recursive:!0,force:!0});let n=rf(t,r);if(!n)throw new Error(`could not compute git facts for ${t}`);let s=Cv(t,r);if(!s)throw new Error(`could not compute the PR diff for ${t}`);let i=GRt(e),o=[n.changedFiles,...i.map(d=>d.changedFiles)].flat(),a=o.map(d=>d.path).filter($Rt),c=o.length>0&&a.length===o.length,l={schemaVersion:1,repository:{path:t,currentBranch:n.currentBranch,baseBranch:n.baseBranch},changedFiles:n.changedFiles,...i.length?{relatedChanges:i}:{},newFiles:s.newFiles,deletedFiles:s.deletedFiles,diffStat:s.diffStat,diffBytes:s.diffContent.length,nonApplicationFiles:a,nonApplicationOnly:c,sutRequired:!c};Ll.writeFileSync(bE.join(e.runDir,Rm),s.diffContent);let u=bE.join(e.runDir,g4);return Ll.mkdirSync(bE.dirname(u),{recursive:!0}),Ll.writeFileSync(u,JSON.stringify(l,null,2)+`
|
|
336
336
|
`),e.prepared={preflight:l},{preflight:g4,diff:Rm}}var vQe={name:"preflight",timeoutMinutes:1,requires:[],validateInput:qRt,execute:HRt};var mf=j(require("fs")),OQe=j(require("path"));var HD=j(require("fs"));var jRt={name:"output-produced",verify(e,t,r){let n=e.outputFileFor(r.name);return(HD.existsSync(n)?HD.readFileSync(n,"utf-8"):"").trim().length>0?{name:this.name,passed:!0}:{name:this.name,passed:!1,details:`stage produced no output (${n} empty or missing)`}}},zRt=["Re-read the stage instructions above and confirm every task was completed.","If you find a mistake or an incomplete task, fix it now before finishing.","End your response with a one-line summary of what this stage accomplished."];function cr(e){let t=e.requires??[];return{name:e.name,model:e.model??"sonnet",maxAttempts:e.maxAttempts,effort:e.effort,timeoutMinutes:e.timeoutMinutes??15,scaleTimeout:e.scaleTimeout,requires:t,softRequires:e.softRequires,validateInput:e.validateInput??(()=>({ok:!0,reasons:[]})),buildPrompt:e.buildPrompt??(()=>`You are the "${e.name}" stage of the Skyramp Testbot.`),selfVerification:e.selfVerification??zRt,exitGates:e.exitGates??[jRt],prepare:e.prepare,abortIf:e.abortIf,onAbort:e.onAbort,teardown:e.teardown,buildMcpServers:e.buildMcpServers,buildReadDirs:e.buildReadDirs,buildPluginDirs:e.buildPluginDirs,buildSettings:e.buildSettings,namesSession:e.namesSession,resumeFrom:e.resumeFrom,requiredSkills:e.requiredSkills,buildSessionEnv:e.buildSessionEnv,allowedTools:e.allowedTools,buildDisallowedTools:e.buildDisallowedTools,captureTrace:e.captureTrace,onPassed:e.onPassed,passReason:e.passReason,adversarialReview:e.adversarialReview,retryHint:e.retryHint,beforeGates:e.beforeGates,afterAttempt:e.afterAttempt,salvage:e.salvage,checkpoint:e.checkpoint,needsSutAuth:e.needsSutAuth,triageBranch:e.triageBranch,branchSkipClears:e.branchSkipClears,branchRequires:e.branchRequires}}var dx=require("child_process");var ng=j(require("fs")),ic=j(require("path"));function xQe(e,t,r){let n=r.indexOf("/");if(n<=0)return!1;let s=kQe(e,t,r.slice(0,n)),i=r.slice(n+1);return!!(s&&i&&Si(s,i))}function kQe(e,t,r){if(!r||r==="."||r===".."||r.includes("/")||r.includes(ic.sep))return;let n=ic.resolve(e),s=ic.join(ic.dirname(n),r);if(!(s===n||t.some(i=>ic.resolve(i)===s))&&ng.existsSync(ic.join(s,".git")))try{let i=(0,dx.execFileSync)("git",[...Cs,"rev-parse","--show-toplevel"],{cwd:s,encoding:"utf-8",env:Ye(),stdio:["ignore","pipe","ignore"]}).trim();return ng.realpathSync(i)===ng.realpathSync(s)?s:void 0}catch{return}}var RQe=6e4;function VRt(e){return Pr(xv,e).errors}function R5(e,t=[]){let{value:r,error:n}=Xt(e,t);if(n)return{errors:[n]};let s=VRt(r);return s.length>0?{errors:s}:{analysis:r,errors:[]}}function jD(e,t=[]){return R5(e.stdout,t)}var TQe=zn("analysis-schema",(e,t)=>jD(t,e.secretValues));function Ul(e){let t=e.split("\u2014")[0].split(" ")[0].trim(),r=t.match(/^(.*?):\d+/);return(r?r[1]:t.replace(/:$/,"")).trim()}function WRt(e){let t=e.split("#")[0].trim(),r=Ul(t);return/\.[A-Za-z0-9]+$/.test(r)||r.includes("/")||/:\d+$/.test(t)?r:void 0}function YRt(e,t){let r=e.match(/^(.*?)\s*\((\d+)\s*files?\)\s*$/i),n=(r?r[1]:e).trim(),s=r?Number(r[2]):void 0;if(t.has(n))return{isPattern:!1,claimedCount:s,matched:[n]};if(!/[*?]/.test(n))return{isPattern:!1,claimedCount:s,matched:[]};let i=new RegExp("^"+n.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*\*/g,"\0").replace(/\*/g,"[^/]*").replace(/\0/g,".*").replace(/\?/g,"[^/]")+"$");return{isPattern:!0,claimedCount:s,matched:[...t].filter(o=>i.test(o))}}function EE(e,t,r=[]){for(let i of[...r].sort((o,a)=>a.length-o.length)){let o=i.replace(/\/+$/,"")+"/";if(e.startsWith(o))return e.slice(o.length)}let n=e,s=!1;for(let i of[...t].sort((o,a)=>a.length-o.length)){let o=i.replace(/[.*+?^${}()|[\]\\/]/g,"\\$&"),a=String.raw`(?:\s*(?::|→|->|—|–|-|/)\s*)?`,c=new RegExp(`${a}[\\s([{<]*${o}[\\s)\\]}>]*${a}`,"g"),l=n.replace(c," ");l!==n&&(s=!0),n=l}return n=n.replace(/\s+/g," ").trim(),s?n.replace(/^\/+/,""):n}var BQe={name:"analysis-grounded",async verify(e,t){let{analysis:r,errors:n}=jD(t);if(!r)return ce(this.name,n);let s=e.inputs.repositoryPath,i=rf(s,e.inputs.baseBranch);if(!i)return ce(this.name,[`could not compute git facts for ${s}`]);let o=new Set(i.changedFiles.map(V=>V.path)),a=new Set,c=[s,...(e.inputs.relatedRepos??[]).map(V=>V.path)],l=[],u=new Map;for(let V of e.inputs.relatedRepos??[]){for(let K of[V.slug,V.slug.split("/").pop()])K&&a.add(K);let N=rf(V.path);if(!N){l.push(V.slug);continue}for(let K of N.changedFiles)o.add(K.path);u.set(V.slug,new Set(N.changedFiles.map(K=>K.path)))}let d=[],p=[...r.endpoints.new,...r.endpoints.modified,...r.endpoints.removed],f=r.endpoints.removed.length>0||p.some(V=>V.method.toUpperCase()==="DELETE"),h=r.unexamined.some(V=>/model|schema|entit|migration/i.test(V));f&&r.entityMap.entities.length>0&&r.entityMap.references.length===0&&!h&&d.push("the change removes or deletes something, entityMap names entities, but entityMap.references is empty \u2014 map the INBOUND references to the affected entity (which other entities point at it, and what happens to them on delete), or list the models/schema files you could not examine in `unexamined`");for(let V of r.diff.changedFiles){let N=EE(V,a,c);if(o.has(N))continue;let K=YRt(N,o);if(K.matched.length===0&&l.length>0){d.push(`could not read ${l.join(", ")} to verify "${N}" \u2014 a related checkout of a multi-repo run must be readable for changedFiles to be grounded`);continue}K.matched.length===0?d.push(K.isPattern?`diff.changedFiles pattern "${N}" matches nothing git reports as changed`:`diff.changedFiles claims "${N}" which git does not report as changed`):K.claimedCount!=null&&K.claimedCount!==K.matched.length&&d.push(`diff.changedFiles says "${N}" but that pattern matches ${K.matched.length} changed file(s), not ${K.claimedCount}`)}let A,C=()=>{if(!A)try{A=(0,dx.execFileSync)("git",[...Cs,"ls-files"],{cwd:s,encoding:"utf-8",env:Ye()}).split(`
|
|
337
337
|
`).filter(Boolean)}catch{A=[]}return A},w=(e.inputs.relatedRepos??[]).map(V=>V.path),b=(V,N)=>{if(!V)return;let K=EE(V,a,c);if(o.has(K)||Si(s,K)||w.some(dt=>Si(dt,K))||xQe(s,w,K))return;let se=`/${K}`,ue=C().filter(dt=>dt.endsWith(se));if(ue.length===0&&w.length>0)for(let dt of w)try{if((0,dx.execFileSync)("git",[...Cs,"ls-files"],{cwd:dt,encoding:"utf-8",env:Ye()}).split(`
|
|
338
338
|
`).some(xr=>xr&&(xr===K||xr.endsWith(se))))return}catch{}if(ue.length!==1){if(ue.length>1){d.push(`${N} cites "${K}" which matches ${ue.length} files (${ue.slice(0,3).join(", ")}) \u2014 cite the repository-relative path`);return}d.push(`${N} cites "${K}" which does not exist in the repository`)}};for(let V of["new","modified","removed"])r.endpoints[V].forEach((N,K)=>b(Ul(N.evidence),`endpoints.${V}[${K}].evidence`));r.services.forEach((V,N)=>b(Ul(V.evidence),`services[${N}].evidence`)),r.findings.forEach((V,N)=>b(V.file,`findings[${N}].file`)),r.behaviors.forEach((V,N)=>b(Ul(V.evidence),`behaviors[${N}].evidence`));let I=Ge(e.inputs);if(I.length>1){let V=Xa(sr(e)??{changedFiles:i.changedFiles},I[0].slug);r.behaviors.forEach((N,K)=>{let se=km(I,N.repository);se||d.push(`behaviors[${K}].repository ${N.repository} is not a repository of this run (${I.map(dt=>dt.slug).join(", ")})`);let ue=EE(Ul(N.evidence),a,c);se&&ue&&!Si(se.path,ue)&&!vb(V,se.slug,ue)&&d.push(`behaviors[${K}].evidence cites "${ue}", which is not in ${se.slug} \u2014 set "repository" to the checkout the file is in, and cite its repository-relative path`)})}let v=r.behaviors.map(V=>(V.surface??"").toLowerCase());for(let V of["new","modified"])for(let N of r.endpoints[V]){let K=`${N.method} ${N.path}`.toLowerCase();!v.some(ue=>ue.includes(N.path.toLowerCase())||K.includes(ue)||ue.includes(K))&&!r.unexamined.some(ue=>ue.includes(N.path))&&d.push(`endpoints.${V} ships "${N.method} ${N.path}" but no behaviors[] entry describes it \u2014 say what the change makes true there, or list it in \`unexamined\``)}r.existingTests.locations.forEach((V,N)=>b(V.dir,`existingTests.locations[${N}].dir`));let T=(V,N)=>{if(Si(V,N))return!0;try{return(0,dx.execFileSync)("git",[...Cs,"ls-files"],{cwd:V,encoding:"utf-8",env:Ye()}).split(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skyramp/testbot-core",
|
|
3
|
-
"version": "0.13.0-v3.
|
|
3
|
+
"version": "0.13.0-v3.152",
|
|
4
4
|
"description": "Skyramp Testbot engine: AI-powered deterministic test generation, execution and maintenance",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"//files": "An explicit allowlist, never a glob. `dist/` is gitignored, so without this key npm's .gitignore fallback would publish a package with no engine in it; with a glob it would publish the sourcemaps, whose sourcesContent embeds every src/*.ts verbatim. eval-entry.js is a development entry and must not ship. dist/VERSION.json exists only in a release-engine.yml build. assets/gen-reference/ is the staged codegen reference corpus, which generate.ts finds at ../assets from dist/.",
|