@sreetej510/pi-shipd-checks 0.9.14 → 0.9.16
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/fargate-worker.mjs +524 -523
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -89,7 +89,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
89
89
|
`)}function Fke(e,t=[],s=""){return["You are the sole, strict post-implementation solution-quality auditor for a coding-agent benchmark task.","You must discover candidate defects and then skeptically re-check and deduplicate them yourself before submitting. Do not defer validation to another agent.","You are working inside the actual repository in read-only mode. You have access to read/grep/find/ls tools only \u2014 you cannot execute code, edit files, or modify the repository.","The task contract is `agent_prompt.md`. The changed code-file list and in-memory changed-code diff below are the authoritative implementation scope. Inspect the changed source and directly relevant public code/analogues only. Do not inspect `solution.patch`, `test.patch`, other patches, unrelated Markdown, shell scripts, Dockerfiles, generated files, lockfiles, or unrelated repository areas.",EMn(t),xMn(s),"","Use the `# Gaps in solution` section of `rules.md` below as the authoritative solution-gap contract. Report concrete implementation defects, not test-quality complaints, hypothetical hardening, reference-only differences, or personal style preferences.","","Mandatory full-audit procedure \u2014 complete every step before calling the report tool:","1. Read `agent_prompt.md` and every listed changed code file completely enough to understand all changed symbols, control flow, public boundaries, state transitions, error handling, cleanup, and compatibility behavior.","2. Map each explicit requirement, public invariant, prohibition, supported path, and failure guarantee to the changed code. Check for missing requirements, wrong public results/state, regressions, inconsistent equivalent entry points, unsafe partial failure/cancellation/rollback/concurrency/resource behavior, dead or unreachable code, and unrelated changes.","3. Compare changed areas with one or two closest real repository analogues for layering, naming, exports, logging and errors, persistence, async/state handling, cleanup, and public extension points. Treat a convention as evidence only when it is directly relevant and unambiguous; do not prescribe one equivalent architecture.","4. For every candidate, cite the exact prompt/public contract or established convention, the concrete changed-code evidence, the observable consequence, and why it is a real defect rather than a different valid implementation. Use the narrowest S1/S2/S3 quality classification implied by the rules, and allow combined metrics when justified.","5. Perform an adversarial self-review: imagine a compliant caller, invalid input, later-phase failure, repeated or parallel invocation, fresh process/backend, and every equivalent public path. Re-read every candidate and drop anything speculative, duplicate, unrelated to the inspected scope, or unsupported by evidence.","6. Return an empty list when the changed code is good quality after this complete review. Do not use the reference solution or visible tests as a completeness oracle.","","Use only these finding categories (include S1/S2/S3 in the evidence or subject when useful):","- missing-requirement: the implementation misses an explicit prompt requirement or required public behavior (usually S1).","- regression: the change breaks existing behavior, compatibility, defaults, or an unrelated public scope (S1/S3).","- architecture: the implementation violates a clear repository pattern/public extension point or adds avoidable duplication/coupling that harms correctness or maintainability (S3).","- unsafe-failure: invalid input, cancellation, partial failure, persistence, rollback, concurrency, or cleanup leaves invalid, destructive, leaked, or inconsistent state contrary to the contract (S2, possibly S1).","- inconsistent-path: equivalent public entry points, representations, modes, or lifecycle paths have different semantics without a prompt-supported reason (S1/S2).","- dead-code: grep/read proves added or changed code is unused, unreachable, or leftover scaffolding (S3).","- unrelated-change: behavior outside the task changed without a contract or regression reason (S3).","","Solution-gap rules from `rules.md` \u2014 authoritative for this audit:",e,"","For every retained finding provide its category, short subject identifier, concrete problem, evidence from the inspected code/analogues and prompt, required behavior or quality property to preserve, and a focused repair recommendation. Do not prescribe a private name or one equivalent implementation when alternatives remain valid.",`When you are done, call the \`${AT}\` tool exactly once with the complete candidate list. That tool call is your only way to report a result.`].join(`
|
|
90
90
|
`)}function wMn(e){let t=e.status==="ok"?e.passed?"PASSED all new tests":"did NOT pass all new tests":`did not complete normally (status: ${e.status})`;return`- Solver ${e.index} \u2014 ${t} \u2014 solution.diff / test_output.txt in \`${FC}/solver_${e.index}/\``}function Bke(e,t,s,a){let c=["You are a strict, skeptical behavioral-gap auditor for a coding-agent benchmark task.","You are working inside a throwaway, read-only copy of a git repository (this is your current directory). You have access to read/grep/find/ls tools only \u2014 you cannot execute code, apply patches, or edit files.","The repo root contains `agent_prompt.md` (the real task description), `solution.patch` (a unified diff of the real golden/reference solution), and `test.patch` (a unified diff adding the hidden tests).","",`Separately, several coding agents ('solvers') were each given the same \`agent_prompt.md\` plus the failing tests from \`test.patch\` \u2014 but never \`solution.patch\` \u2014 and asked to implement the task TDD-style, iterating with real shell access until the tests passed or they gave up. Each solver's diff and full \`test.sh new\` output \u2014 captured and verified independently by the harness, not self-reported \u2014 is saved under \`${FC}/solver_<index>/\` (\`solution.diff\`, \`test_output.txt\`), with a \`${FC}/manifest.json\` summary. Use read/grep/find/ls to open exactly what you need. Status summary:`,"",...e.map(wMn),"","Your job: compare the reference `solution.patch` with each solver's `solution.diff` to find concrete BEHAVIORAL GAPS. Keep only a difference where: (a) `agent_prompt.md` explicitly requires the behavior, (b) the solver passed the relevant tests (even if it failed elsewhere), (c) the reference and solver produce observably different behavior for a real edge case or scenario, and (d) a fair public-facing test could distinguish them. The reference solution is evidence for scenarios to inspect, never a specification by itself.","","How to work:","1. Read `agent_prompt.md` sentence by sentence and note every distinct requirement, constraint, and prohibition.","2. Read `solution.patch` to see how the reference solution satisfies those requirements.","3. For each solver, read its `solution.diff` and compare it against the reference behavior. Look specifically for a solver shortcut, missed constraint, edge case, or side effect that the PROMPT requires, where the solver still passes because the tests do not observe the behavioral difference.","4. A solver that did not pass the full suite may still provide evidence for a completed, relevant part of its diff, but only when its test output shows the failure is unrelated to that behavior (or shows the relevant tests already passed). Do not treat its failing behavior as a gap, and do not infer gaps from a hypothetical wrong implementation.","5. Treat multiple solvers converging on the same divergent-but-passing shortcut as stronger evidence of a real gap, not proof it's acceptable \u2014 the tests are what's under scrutiny, not majority solver behavior.","","The `# Gaps in tests` section of `rules.md` is authoritative for candidate gaps:",s,"- Every gap must be evidenced by an actual, cited solver diff and a contrasting reference behavior. For a solver that failed the full suite, also cite its test output showing that the relevant behavior already passed or is unrelated to the failure. Cite the prompt sentence that makes the behavioral difference required; do not report a gap that is purely theoretical or based only on the reference implementation.","- It is fine, and expected, to submit an empty list if the solvers that passed all converged on behavior equivalent to the reference solution with no material gaps.","- Do not self-censor for volume, but do not pad the list either \u2014 only include what you can concretely justify with cited evidence.","","For reference, here is the checklist for the tests focus area (use it to calibrate what good coverage looks like, not as a list of gaps to report verbatim):",t,"","Apply the `# Fairness vs. unfairness` rules from `rules.md` before retaining any candidate:",a];return c.push("",`When you are done, call the \`${DT}\` tool exactly once with your final list (which may be empty). That tool call is your only way to report a result.`),c.join(`
|
|
91
91
|
`)}var kMn=900*1e3,Ane=["read","grep","find","ls"];function Dne(e){return e==="off"?void 0:e}async function bne(e,t,s=kMn){return t.aborted?"cancelled":new Promise((a,c)=>{let l=!1,u,p=()=>{u!==void 0&&clearTimeout(u),t.removeEventListener("abort",m)},d=S=>{l||(l=!0,p(),a(S))},m=()=>d("cancelled");u=setTimeout(()=>d("timedOut"),s),t.addEventListener("abort",m,{once:!0}),e().then(()=>d("done"),S=>{l||(l=!0,p(),c(S))})})}async function Ene(e){if(e){try{e.isIdle||await e.abort()}catch{}e.dispose()}}async function Uke(e){let t={},s=e.model,a;try{({session:a}=await Cne({cwd:e.tempDir,model:s,thinkingLevel:Dne(e.thinkingLevel),tools:[...Ane,TT],customTools:[Oke(t)],sessionManager:Tne.inMemory()}));let c=await bne(async()=>{await a?.prompt(qke(e.testRubric,e.gapRules,e.fairnessRules,e.codeFiles))},e.cancelSignal,e.timeoutMinutes*60*1e3);if(c!=="done")return await a.abort(),{status:c,gaps:[]}}catch{return{status:"error",gaps:[]}}finally{await Ene(a)}return t.gaps?{status:"ok",gaps:t.gaps}:{status:"noSubmission",gaps:[]}}async function Hke(e){let t={},s=e.model,a;try{({session:a}=await Cne({cwd:e.tempDir,model:s,thinkingLevel:Dne(e.thinkingLevel),tools:[...Ane,DT],customTools:[Vke(t)],sessionManager:Tne.inMemory()}));let c=await bne(async()=>{await a?.prompt(Bke(e.solverResults,e.testRubric,e.gapRules,e.fairnessRules))},e.cancelSignal);if(c!=="done")return await a.abort(),{status:c,gaps:[]}}catch{return{status:"error",gaps:[]}}finally{await Ene(a)}return t.gaps?{status:"ok",gaps:t.gaps}:{status:"noSubmission",gaps:[]}}async function jke(e){let t={},s=e.model,a;try{({session:a}=await Cne({cwd:e.tempDir,model:s,thinkingLevel:Dne(e.thinkingLevel),tools:[...Ane,AT],customTools:[Nke(t)],sessionManager:Tne.inMemory()}));let c=await bne(async()=>{await a?.prompt(Fke(e.solutionRules,e.codeFiles,e.changedCodeDiff))},e.cancelSignal,e.timeoutMinutes*60*1e3);if(c!=="done")return await a.abort(),{status:c,findings:[]}}catch{return{status:"error",findings:[]}}finally{await Ene(a)}return t.findings?{status:"ok",findings:t.findings}:{status:"noSubmission",findings:[]}}var jg=Xn(xtn(),1),yo=Xn(mdn(),1),_r=Xn(uDn(),1),Hee=Xn(Jbn(),1),rEn=Xn(U_(),1),Zy=Xn(eEn(),1);import{randomUUID as DAe}from"node:crypto";import{createReadStream as Dxo,existsSync as xAe,mkdirSync as bxo,readFileSync as sEn,rmSync as bAe,writeFileSync as PC}from"node:fs";import{tmpdir as EAe}from"node:os";import{join as md}from"node:path";import{fileURLToPath as nEn}from"node:url";import{posix as vxo}from"node:path";function tEn(e){let t,s="/",a={},c=[];for(let l of Txo(e)){let u=l.match(/^([A-Za-z]+)(?:\s+(.+))?$/s);if(!u)throw new Error(`Invalid Dockerfile instruction: ${l}`);let p=u[1]?.toUpperCase(),d=u[2]?.trim()??"";switch(p){case"FROM":{if(t)throw new Error("Multi-stage Dockerfiles are not supported by the Fargate runner.");let m=Bee(d);if(!m[0]||m.some(S=>S.startsWith("--")||S.toUpperCase()==="AS"))throw new Error(`Unsupported FROM instruction: ${l}`);t=m[0];break}case"WORKDIR":if(!d||d.includes("$")||d.includes("\\"))throw new Error(`WORKDIR must be a concrete POSIX path: ${l}`);s=vxo.resolve(s,d);break;case"ENV":Cxo(d,a);break;case"COPY":if(Bee(d).length<2||Bee(d).some(m=>m.startsWith("--")))throw new Error(`COPY flags and malformed COPY instructions are not supported: ${l}`);break;case"RUN":if(!d||d.startsWith("--")||d.startsWith("["))throw new Error(`Only shell-form RUN instructions without options are supported: ${l}`);c.push(d);break;case"CMD":case"ENTRYPOINT":case"LABEL":case"EXPOSE":break;default:throw new Error(`Unsupported Dockerfile instruction for Fargate execution: ${p}`)}}if(!t)throw new Error("Dockerfile is missing a FROM instruction.");return{baseImage:t,workdir:s,env:a,runtimeCommands:c}}function Cxo(e,t){let s=Bee(e);if(s.length===0)throw new Error("ENV requires a variable assignment.");if(s[0]?.includes("=")){for(let a of s){let c=a.indexOf("=");if(c<=0)throw new Error(`Invalid ENV assignment: ${a}`);t[a.slice(0,c)]=a.slice(c+1)}return}if(s.length<2)throw new Error(`ENV requires a value: ${e}`);t[s[0]]=s.slice(1).join(" ")}function Txo(e){let t=[],s="";for(let a of e.split(/\r?\n/)){let c=a.trimEnd();if(!s&&/^\s*#/.test(c))continue;let l=s?`${s}${c.trimStart()}`:c.trimStart();Axo(l)?s=`${l.slice(0,-1).trimEnd()} `:(l.trim()&&t.push(l.trim()),s="")}return s.trim()&&t.push(s.trim()),t}function Axo(e){let t=0;for(let s=e.length-1;s>=0&&e[s]==="\\";s-=1)t+=1;return t%2===1}function Bee(e){let t=[],s="",a,c=!1;for(let l of e)c?(s+=l,c=!1):l==="\\"&&a!=="'"?c=!0:a?l===a?a=void 0:s+=l:l==='"'||l==="'"?a=l:/\s/.test(l)?s&&(t.push(s),s=""):s+=l;if(c&&(s+="\\"),a)throw new Error(`Unterminated quote in Dockerfile instruction: ${e}`);return s&&t.push(s),t}var oEn="shipd-worker",Exo="fargate-worker.mjs",xC=3300,xxo=5e3;function aEn(e){return new Promise(t=>setTimeout(t,e))}function Pxo(e,t){let s=(0,rEn.defaultProvider)({profile:process.env.AWS_PROFILE??t}),a={region:e,credentials:s,maxAttempts:5};return{ecs:new yo.ECSClient(a),ec2:new jg.EC2Client(a),s3:new _r.S3Client(a),sts:new Hee.STSClient(a)}}async function iEn(e){if(e.cancelSignal.aborted)throw new Error("Cancelled by user.");e.onPhase?.("preparing image");let t=md(e.repoDir,"Dockerfile");if(!xAe(t))throw new Error(`Fargate ${e.mode==="solver"?"solver gap finder":"patch precheck"} requires Dockerfile in the project root.`);let s=tEn(sEn(t,"utf-8")),a=wxo(e.config,e.repoDir,e.mode),c=process.env.AWS_REGION??a.region??"us-east-1",l=Pxo(c,a.awsProfile),u=sDe(e.repoDir,a),p=md(EAe(),`.shipd-fargate-source-${DAe()}.tar.gz`),d=Lxo(),m=e.solverConfig,S=e.mode==="solver"?md(kxo(),"auth.json"):void 0,v=S?md(EAe(),`.shipd-fargate-auth-${DAe()}.json`):void 0,T,x,w,L,G=!1,O=()=>{T&&(G=!0,l.ecs.send(new yo.StopTaskCommand({cluster:x,task:T,reason:"shipd checks cancelled"})).catch(()=>{}))};e.cancelSignal.addEventListener("abort",O,{once:!0});let H={source:`runs/${e.runId}/source.tar.gz`,worker:`runs/${e.runId}/${Exo}`,auth:`runs/${e.runId}/auth.json`,bootstrap:`runs/${e.runId}/bootstrap.json`,result:`runs/${e.runId}/result.json`};try{if(e.mode==="solver"&&!m)throw new Error("Fargate solver configuration is missing.");if(S&&!xAe(S))throw new Error(`Missing Pi auth file: ${S}`);let ee=await Oxo(l,a,c);w=ee.bucket,x=ee.cluster,await Mxo(e.pi,e.snapshotDir,p,e.cancelSignal,e.mode==="solver"),await Uee(l.s3,ee.bucket,H.source,p,"application/gzip"),await Uee(l.s3,ee.bucket,H.worker,d,"text/javascript"),S&&v&&m&&(Gxo(S,m.provider,v),await Uee(l.s3,ee.bucket,H.auth,v,"application/json")),L=md(EAe(),`.shipd-fargate-bootstrap-${DAe()}.json`);let ie=await Vxo(l.ecs,s,u.cpu,u.memoryMiB,c,a),we=e.mode==="solver"?Math.max(1,Math.floor(m?.timeoutMinutes??1)):Math.max(1,Math.floor(e.precheckTimeoutMinutes??20)),ke=e.mode==="solver"?Math.max(1,Math.floor(m?.solverCount??1)):0,_e=!!a.taskRoleArn,ve=Math.min(3,Math.max(0,Math.floor(a.maxRetries??1))),Ce="Fargate task did not produce a result.";e.onPhase?.("requesting sandbox");let Le=[];for(let Ae=0;Ae<=ve;Ae+=1){if(e.cancelSignal.aborted)throw new Error("Cancelled by user.");e.onPhase?.("requesting sandbox");let tt=await(0,Zy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:H.worker}),{expiresIn:xC}),ce=_e?void 0:await(0,Zy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:H.source}),{expiresIn:xC}),M=_e||!S?void 0:await(0,Zy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:H.auth}),{expiresIn:xC}),se=_e?void 0:await(0,Zy.getSignedUrl)(l.s3,new _r.PutObjectCommand({Bucket:ee.bucket,Key:H.result,ContentType:"application/json"}),{expiresIn:xC}),Yo=_e?void 0:await(0,Zy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:H.result}),{expiresIn:xC});PC(L,`${JSON.stringify({workerUrl:tt,sourceUrl:ce,authUrl:M,resultPutUrl:se,resultGetUrl:Yo,..._e?{bucket:ee.bucket,region:c,sourceKey:H.source,...S?{authKey:H.auth}:{},resultKey:H.result}:{},mode:e.mode,planB64:Buffer.from(JSON.stringify(s),"utf-8").toString("base64url"),...m?{provider:m.provider,modelId:m.modelId,thinkingLevel:m.thinkingLevel}:{},timeoutMinutes:we,...e.mode==="solver"?{solverCount:ke}:{},resourceProfile:u.profile})}
|
|
92
|
-
`,"utf-8"),await Uee(l.s3,ee.bucket,H.bootstrap,L,"application/json");let gL=await(0,Zy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:H.bootstrap}),{expiresIn:xC}),RL={name:oEn,environment:[{name:"SHIPD_BOOTSTRAP_URL",value:gL}]},gc=await l.ecs.send(new yo.RunTaskCommand({cluster:ee.cluster,capacityProviderStrategy:[{capacityProvider:"FARGATE_SPOT",weight:1}],taskDefinition:ie,count:1,networkConfiguration:{awsvpcConfiguration:{subnets:ee.subnets,securityGroups:[ee.securityGroup],assignPublicIp:"ENABLED"}},overrides:{containerOverrides:[RL]}})),SL=gc.failures?.[0]?.reason;if(T=gc.tasks?.[0]?.taskArn,x=ee.cluster,!T){Ce=SL??"Fargate could not place the Spot task.",e.onPhase?.("requesting sandbox");continue}e.onPhase?.("sandbox created");let Za=await Fxo(l.ecs,ee.cluster,T,()=>Bxo(l.s3,ee.bucket,H.result),we,e.cancelSignal,(Lm,yL)=>{e.mode==="solver"&&e.onSolverProgress?.(Lm),yL&&e.onResourceUsage?.(yL)},()=>e.onPhase?.(e.mode==="solver"?"running agents":"running patch prechecks"),()=>{G=!0});if(T=void 0,Za?.resourceUsage&&e.onResourceUsage?.(Za.resourceUsage),e.mode==="patch-precheck"){if(Za?.complete&&!Za.error&&Za.precheck)return e.onPhase?.("finalizing"),Za;Ce=Za?.error??Ce}else{if(Le=Hxo(Le,Za?.results??[]),e.onSolverProgress?.(Le),Za?.complete&&!Za.error&&Le.length>=ke)return e.onPhase?.("finalizing"),{...Za,results:Le};Ce=Za?.error??Ce}if(e.cancelSignal.aborted)throw new Error("Cancelled by user.")}return e.mode==="patch-precheck"?{complete:!1,results:[],error:Ce}:{complete:!1,results:jxo(ke,Le,Ce),error:Ce}}finally{e.cancelSignal.removeEventListener("abort",O),T&&(G||await l.ecs.send(new yo.StopTaskCommand({cluster:x,task:T,reason:"shipd checks cleanup"})).catch(()=>{}),await qxo(l.ecs,x,T)),await zxo(l.s3,w,H).catch(()=>{}),l.ecs.destroy(),l.ec2.destroy(),l.s3.destroy(),l.sts.destroy();try{bAe(p,{force:!0}),L&&bAe(L,{force:!0}),v&&bAe(v,{force:!0})}catch{}}}async function cEn(e){let t=await iEn({...e,mode:"solver"}),s=await Uxo(e,t.results,e.solverConfig.saveArtifacts);for(let a of s)e.onSolverCompleted?.(a);return s}function $xo(e){let t=e.phases.find(a=>a.phase==="new-before-solution");if(!t||t.passedTestcases===null||t.passedTestcases<=0)return e;let s=e.error??["phase: new tests before solution","instruction: Fix test.patch so every new test fails or errors individually before the solution; no new test may pass. Do not remove tests.",`passed tests: ${t.passedTestcases}`,`skipped tests: ${t.skippedTestcases??"unknown"}`,`
|
|
92
|
+
`,"utf-8"),await Uee(l.s3,ee.bucket,H.bootstrap,L,"application/json");let gL=await(0,Zy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:H.bootstrap}),{expiresIn:xC}),RL={name:oEn,environment:[{name:"SHIPD_BOOTSTRAP_URL",value:gL}]},gc=await l.ecs.send(new yo.RunTaskCommand({cluster:ee.cluster,capacityProviderStrategy:[{capacityProvider:"FARGATE_SPOT",weight:1}],taskDefinition:ie,count:1,networkConfiguration:{awsvpcConfiguration:{subnets:ee.subnets,securityGroups:[ee.securityGroup],assignPublicIp:"ENABLED"}},overrides:{containerOverrides:[RL]}})),SL=gc.failures?.[0]?.reason;if(T=gc.tasks?.[0]?.taskArn,x=ee.cluster,!T){Ce=SL??"Fargate could not place the Spot task.",e.onPhase?.("requesting sandbox");continue}e.onPhase?.("sandbox created");let Za=await Fxo(l.ecs,ee.cluster,T,()=>Bxo(l.s3,ee.bucket,H.result),we,e.cancelSignal,(Lm,yL)=>{e.mode==="solver"&&e.onSolverProgress?.(Lm),yL&&e.onResourceUsage?.(yL)},()=>e.onPhase?.(e.mode==="solver"?"running agents":"running patch prechecks"),()=>{G=!0});if(T=void 0,Za?.resourceUsage&&e.onResourceUsage?.(Za.resourceUsage),e.mode==="patch-precheck"){if(Za?.complete&&!Za.error&&Za.precheck)return e.onPhase?.("finalizing"),Za;Ce=Za?.error??Ce}else{if(Le=Hxo(Le,Za?.results??[]),e.onSolverProgress?.(Le),Za?.complete&&!Za.error&&Le.length>=ke)return e.onPhase?.("finalizing"),{...Za,results:Le};Ce=Za?.error??Ce}if(e.cancelSignal.aborted)throw new Error("Cancelled by user.")}return e.mode==="patch-precheck"?{complete:!1,results:[],error:Ce}:{complete:!1,results:jxo(ke,Le,Ce),error:Ce}}finally{e.cancelSignal.removeEventListener("abort",O),T&&(G||await l.ecs.send(new yo.StopTaskCommand({cluster:x,task:T,reason:"shipd checks cleanup"})).catch(()=>{}),await qxo(l.ecs,x,T)),await zxo(l.s3,w,H).catch(()=>{}),l.ecs.destroy(),l.ec2.destroy(),l.s3.destroy(),l.sts.destroy();try{bAe(p,{force:!0}),L&&bAe(L,{force:!0}),v&&bAe(v,{force:!0})}catch{}}}async function cEn(e){let t=await iEn({...e,mode:"solver"}),s=await Uxo(e,t.results,e.solverConfig.saveArtifacts);for(let a of s)e.onSolverCompleted?.(a);return s}function $xo(e){let t=e.phases.find(a=>a.phase==="new-before-solution");if(!t||t.passedTestcases===null||t.passedTestcases<=0)return e;let s=e.error??["phase: new tests before solution","instruction: Fix test.patch so every new test fails or errors individually before the solution; no new test may pass. Do not remove tests.",`passed tests: ${t.passedTestcases}`,`skipped tests: ${t.skippedTestcases??"unknown"}`,`passing tests: ${t.passedTestNames.length>0?t.passedTestNames.join(", "):"unknown"}`].join(`
|
|
93
93
|
`);return{...e,status:"failed",passed:!1,error:s}}async function lEn(e){try{let t=await iEn({...e,mode:"patch-precheck"});if(!t.precheck)throw new Error(t.error??"no result was returned");return $xo(t.precheck)}catch(t){throw new Error(`Fargate patch precheck task failed.
|
|
94
94
|
platform: linux
|
|
95
95
|
${t instanceof Error?t.message:String(t)}`)}}function wxo(e,t,s){let a=e.fargate??{};if(s==="patch-precheck")return{...a,resourceProfile:tDe,adaptiveResourceProfile:!1,projectProfiles:{}};let c=a.projectProfiles?.[t];return c?{...a,resourceProfile:c}:a}function kxo(){let e=Math.max(Ya.lastIndexOf("/"),Ya.lastIndexOf("\\"));return e>=0?Ya.slice(0,e):"."}function Lxo(){let t=[nEn(new URL("./fargate-worker.mjs",import.meta.url)),nEn(new URL("../dist/fargate-worker.mjs",import.meta.url)),md(process.cwd(),"dist","fargate-worker.mjs")].find(s=>xAe(s));if(!t)throw new Error("Missing dist/fargate-worker.mjs. Build pi-shipd-checks first.");return t}async function Mxo(e,t,s,a,c){let p=`tar ${process.platform==="win32"?"--force-local ":""}${c?"--exclude=./solution.patch ":""}-czf ${NC(OC(s))} -C ${NC(OC(t))} .`,d=process.platform==="win32"?"C:\\Program Files\\Git\\bin\\bash.exe":"bash",m=await e.exec(d,["-c",p],{cwd:t,timeout:12e4,signal:a});if(a.aborted)throw new Error("Cancelled by user.");if(m.code!==0)throw new Error(m.stderr?.trim()||"Could not create the Fargate source archive.")}function Gxo(e,t,s){let a;try{a=JSON.parse(sEn(e,"utf-8"))}catch(u){throw new Error(`Could not read Pi auth file: ${u instanceof Error?u.message:String(u)}`)}if(typeof a!="object"||a===null||Array.isArray(a))throw new Error("Could not prepare Fargate auth: auth.json must contain an object.");let c=a,l=c[t];if(t==="commandcode"&&(typeof l=="string"&&(l={type:"api_key",key:l}),l===void 0&&(l=c["command-code"]),typeof l=="string"&&(l={type:"api_key",key:l}),l===void 0&&typeof c.apiKey=="string"&&(l={type:"api_key",key:c.apiKey})),l===void 0){PC(s,`{}
|
|
@@ -107,7 +107,7 @@ ${t instanceof Error?t.message:String(t)}`)}}function wxo(e,t,s){let a=e.fargate
|
|
|
107
107
|
Required behavior: ${s.requiredBehavior}
|
|
108
108
|
Recommendation: ${s.recommendation}`)].join(`
|
|
109
109
|
`)}import{spawn as mPo}from"node:child_process";import{randomUUID as fPo}from"node:crypto";import{existsSync as VAe,mkdirSync as gPo}from"node:fs";import{mkdtemp as hEn,readFile as LAe,rm as MAe,writeFile as vEn}from"node:fs/promises";import{createServer as RPo}from"node:net";import{homedir as SPo,tmpdir as CEn}from"node:os";import{dirname as yPo,join as al}from"node:path";import{Text as dL}from"@earendil-works/pi-tui";import{chromium as wEn}from"playwright-core";var Yee="quality-check",GAe="shipd:link",OAe="shipd_job_link",TEn=al(SPo(),".pi","agent","shipd-auth","shipd.ai.json"),IPo=15,AEn="https://shipd.ai/",_Po=12e4,hPo=3e5,vPo=9e4,Xy=5e3,NAe=["Test Quality","Solution Quality"],CPo=Ct.Object({});function mL(e){return(e??"").trim().replace(/\s+/g," ")}function TPo(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function wi(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function fL(e,t){return new Promise((s,a)=>{if(t?.aborted){a(new Error("Cancelled by user."));return}let c=()=>{clearTimeout(l),t?.removeEventListener("abort",c),a(new Error("Cancelled by user."))},l=setTimeout(()=>{t?.removeEventListener("abort",c),s()},e);t?.addEventListener("abort",c,{once:!0})})}function $i(e){if(e?.aborted)throw new Error("Cancelled by user.")}function DEn(){return[process.env.SHIPD_CHROME_PATH,process.env.PROGRAMFILES&&al(process.env.PROGRAMFILES,"Google","Chrome","Application","chrome.exe"),process.env["PROGRAMFILES(X86)"]&&al(process.env["PROGRAMFILES(X86)"],"Google","Chrome","Application","chrome.exe"),process.env.LOCALAPPDATA&&al(process.env.LOCALAPPDATA,"Google","Chrome","Application","chrome.exe"),"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/usr/bin/google-chrome","/usr/bin/chromium","/usr/bin/chromium-browser"].filter(t=>!!t).find(t=>VAe(t))}function APo(){let e=RPo();return new Promise((t,s)=>{e.once("error",s),e.listen(0,"127.0.0.1",()=>{let a=e.address();if(!a||typeof a=="string"){e.close(),s(new Error("Could not allocate a local Chrome debugging port."));return}e.close(c=>c?s(c):t(a.port))})})}async function DPo(e,t,s=15e3){let a=Date.now()+s;for(;Date.now()<a;){if(t.exitCode!==null)throw new Error("Chrome exited before its debugging connection became available.");try{if((await fetch(`http://127.0.0.1:${e}/json/version`)).ok)return}catch{}await fL(250)}throw new Error("Timed out waiting for Chrome to start.")}async function bPo(e,t=3e4){let s=Date.now()+t;for(;Date.now()<s;){let a=e.pages();for(let c of a){if(!wC(c.url()))continue;if(await c.locator('button[aria-label="Open user menu"]').isVisible({timeout:1e3}).catch(()=>!1))return c}for(let c of a)wC(c.url())&&await c.reload({waitUntil:"domcontentloaded",timeout:15e3}).catch(()=>{});await fL(1e3)}}function wC(e){try{let t=new URL(e),s=t.hostname.toLowerCase();return t.protocol==="https:"&&(s==="shipd.ai"||s.endsWith(".shipd.ai"))}catch{return!1}}function EPo(e){let t;for(let s of e){if(!wi(s)||s.type!=="custom"||s.customType!==OAe)continue;let a=s.data;wi(a)&&(typeof a.url=="string"&&wC(a.url)?t=a.url:a.url===null&&(t=void 0))}return t}function kEn(e,t){return e.locator("span").filter({hasText:new RegExp(`^${TPo(t)}$`)}).first()}function Xee(e,t){return kEn(e,t).locator("..")}function xPo(e,t){return e.locator("div.fixed").filter({hasText:t}).last()}function LEn(e){return/(?:starting|queued|pending|running|processing|reviewing|finalizing|building|evaluating|checking|\d+%)/i.test(e)}function PPo(e){return/\bstale\b/i.test(e)}function $Po(e,t){let s=e.trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/i,"").trim(),a;try{a=JSON.parse(s)}catch(c){throw new Error(`${t} raw output was not valid JSON: ${c instanceof Error?c.message:String(c)}`)}if(!wi(a))throw new Error(`${t} raw output was not a JSON object.`);return a}async function wPo(e,t,s){let a=al(t,"create_patches.sh"),c=al(t,"agent_prompt.md"),l=al(t,"test.patch"),u=al(t,"solution.patch"),p=[["create_patches.sh",a],["agent_prompt.md",c],["test.patch",l],["solution.patch",u]].filter(([,T])=>!VAe(T)).map(([T])=>T);if(p.length)throw new Error(`Missing required file(s) in the working directory: ${p.join(", ")}`);$i(s);let d=await e.exec(GC(),["create_patches.sh"],{cwd:t,timeout:_Po,signal:s});if(d.killed||d.code!==0){let T=(d.stderr||d.stdout||"").trim().slice(-2e3);throw new Error(`create_patches.sh failed${d.killed?" or timed out":` (exit ${d.code})`}.${T?`
|
|
110
|
-
${T}`:""}`)}$i(s);let[m,S,v]=await Promise.all([LAe(c,"utf8"),LAe(l,"utf8"),LAe(u,"utf8")]);return{taskPrompt:m,testPatch:S,solutionPatch:v}}async function kPo(e,t,s){$i(s);let a=await e.goto(t,{waitUntil:"domcontentloaded",timeout:6e4});if($i(s),!wC(e.url()))throw new Error("Shipd authentication or job-link navigation failed. Check the saved job link and auth state.");if(a&&a.status()>=400)throw new Error(`Shipd job-link navigation returned HTTP ${a.status()}.`);await e.waitForTimeout(4e3),$i(s)}async function bEn(e,t,s,a){$i(a);let c=await wEn.launch({executablePath:e,headless:!0});try{let l=await c.newContext({storageState:t});await l.route("**/*",async p=>{let d=p.request().resourceType();d==="image"||d==="font"||d==="media"?await p.abort():await p.continue()});let u=await l.newPage();return await kPo(u,s,a),{browser:c,page:u}}catch(l){throw await c.close().catch(()=>{}),l}}async function EEn(e,t,s){await t.click({timeout:Xy}),await e.keyboard.press(`${process.platform==="darwin"?"Meta":"Control"}+A`),await e.keyboard.insertText(s)}async function LPo(e,t,s){$i(s);let a=e.locator("#problem-description"),c=e.locator('#problem-test-patch [contenteditable="true"][role="textbox"]'),l=e.locator('#problem-solution-patch [contenteditable="true"][role="textbox"]');for(let u of[a,c,l])if(await u.count()!==1)throw new Error("Shipd challenge form selectors were not found exactly once.");await a.fill(t.taskPrompt),await EEn(e,c,t.testPatch),await EEn(e,l,t.solutionPatch),await Xee(e,"Test Quality").hover(),await fL(1e3,s)}async function MPo(e,t,s){$i(s);let a=Xee(e,t),c=mL(await a.innerText());if(LEn(c))return{quality:t,status:"already-running",rowTextAfterConfirm:c};let l=a.locator('button[title^="Re-run"]').or(a.locator('button[title^="Run"]')),u=await l.count();if(u!==1)throw new Error(`${t}: expected one Run button, found ${u}`);if(!await l.isEnabled())throw new Error(`${t}: Run button is disabled.`);let p=await l.getAttribute("title");await l.click();let d=e.getByRole("dialog").last();await d.waitFor({state:"visible",timeout:Xy});let m=mL(await d.innerText()),S=d.getByRole("button",{name:/confirm/i});if(await S.count()!==1)throw new Error(`${t}: rerun confirmation button was not found.`);return await S.click(),await fL(500,s),{quality:t,status:"started",rerunTitle:p,confirmation:m}}async function xEn(e,t,s=NAe){let a=[];for(let c of s){$i(t);let l=kEn(e,c);if(await l.count()!==1)throw new Error(`${c}: quality status row was not found.`);await l.waitFor({state:"visible",timeout:Xy});let u=l.locator(".."),p=mL(await u.innerText()),d=await u.locator('button[title^="Run"]').count()>0;a.push({quality:c,rowText:p,busy:LEn(p),shouldRun:d||PPo(p)})}return a}async function GPo(e,t){return await Xee(e,t).locator('button[title^="Re-run"]').count()>0}async function OPo(e,t){await Xee(e,t).hover();let s=xPo(e,t);await s.waitFor({state:"visible",timeout:Xy});let a=s.locator('button[title="Expand to full view"]'),c=await a.count();if(c!==1)throw new Error(`${t}: expected one quality expander, found ${c}`);return a.first()}async function NPo(e,t,s){$i(s),await(await OPo(e,t)).click();let c=e.getByRole("dialog").last();await c.waitFor({state:"visible",timeout:Xy});let l=mL(await c.locator("h2").first().innerText().catch(()=>""));if(l!==t)throw new Error(`${t}: expanded the wrong report dialog (${l||"unknown"}).`);let u=c.locator("pre code").last();if(!await u.isVisible().catch(()=>!1)){let m=c.locator("button").filter({hasText:/raw output/i}).first();try{await m.waitFor({state:"visible",timeout:Xy})}catch{let S=mL(await c.innerText());throw new Error(`${t}: raw output control did not appear; dialog text: ${S.slice(0,1e3)}`)}await m.click()}await u.waitFor({state:"visible",timeout:Xy});let p=await u.innerText(),d=$Po(p,t);return await e.keyboard.press("Escape").catch(()=>{}),{quality:t,parsed:d}}function VPo(e,t){let s=Array.isArray(e?.coverageSuggestions)?e.coverageSuggestions:[],a=Array.isArray(e?.tests)?e.tests.filter(c=>wi(c)&&(c.fairness==="Not fair"||Array.isArray(c.concerns)&&c.concerns.length>0)).map(c=>c.fairness==="Not fair"&&Array.isArray(c.concerns)&&c.concerns.length===0?{...c,concerns:["Not fully fair"]}:c):[];return{testQuality:{verdict:e?a.length===0&&s.length===0?"PASS":"FAIL":null,coverageSuggestions:s,unfairnessCount:a.length,tests:a},solutionQuality:{verdict:t?FPo(t.evaluation)?"PASS":"FAIL":null,evaluation:qPo(t?.evaluation)}}}function PEn(e,t){if(!wi(e)||!wi(e[t]))return"\u2014";let s=e[t].score,a=e[t].max_score;return typeof s=="number"&&typeof a=="number"?`${s}/${a}`:"\u2014"}function qPo(e){return wi(e)?Object.fromEntries(Object.entries(e).filter(([t])=>t!=="overall_feedback").map(([t,s])=>[t,wi(s)?Object.fromEntries(Object.entries(s).filter(([a])=>a!=="level")):s])):e??null}function FPo(e){return!wi(e)||!["code_quality","solution_comprehensiveness"].every(a=>{let c=e[a];return wi(c)&&typeof c.score=="number"&&typeof c.max_score=="number"})?!1:Object.values(e).filter(a=>wi(a)&&("score"in a||"max_score"in a)).every(a=>typeof a.score=="number"&&typeof a.max_score=="number"&&a.score===a.max_score)}function BPo(e,t){let s=wi(e)?e:{},a=wi(s.testQuality)?s.testQuality:{},c=wi(s.solutionQuality)?s.solutionQuality:{},l=typeof a.unfairnessCount=="number"?a.unfairnessCount:Array.isArray(a.tests)?a.tests.length:0,u=Array.isArray(a.coverageSuggestions)?a.coverageSuggestions.length:0,p=c.evaluation,d=a.verdict===null?"skipped":`${l} unfairness \xB7 ${u} suggestions`,m=c.verdict===null?"skipped":`quality ${PEn(p,"code_quality")} \xB7 comprehensiveness ${PEn(p,"solution_comprehensiveness")}`;return[` ${t.fg("accent","Test Quality")} ${t.fg("muted",d)}`,` ${t.fg("accent","Solution Quality")} ${t.fg("muted",m)}`]}function $En(e,t){let a=e.find(c=>new RegExp(`^${t}:`,"i").test(c))?.match(/:\s*(\d+)/)?.[1];return a===void 0?void 0:Number.parseInt(a,10)}function UPo(e,t,s,a,c){return e==="new tests before solution"?t!==void 0&&t>0?"Some new tests pass before the solution; add assertions for behavior introduced by the solution.":t===0&&/:\s*none$/i.test(a)&&/:\s*none$/i.test(c)?"The test file did not produce individual failures or errors; use lazy imports so every test executes separately.":"Every new test must fail or error individually before the solution.":e==="new tests after solution"?s!==void 0&&s>0?"New tests were skipped after the solution; every new test must execute and pass.":"The solution does not make every new test pass.":e==="base tests after solution"?"Base-test regression: existing base tests fail after the solution.":e==="base tests before solution"?"Base tests fail before the solution; review the test patch and test setup.":"The patch precheck did not meet the required test outcomes."}function HPo(e){let t=(e.content??[]).map(c=>c.type==="text"?c.text??"":"").join(" "),s=t.split(/\r?\n/).map(c=>c.trim().replace(/\s+/g," ")).filter(Boolean),a=s.find(c=>/^phase:/i.test(c));if(/patch precheck/i.test(t)){if(a){let c=a.replace(/^phase:\s*/i,""),l=$En(s,"passed tests"),u=$En(s,"skipped tests"),p=s.find(
|
|
110
|
+
${T}`:""}`)}$i(s);let[m,S,v]=await Promise.all([LAe(c,"utf8"),LAe(l,"utf8"),LAe(u,"utf8")]);return{taskPrompt:m,testPatch:S,solutionPatch:v}}async function kPo(e,t,s){$i(s);let a=await e.goto(t,{waitUntil:"domcontentloaded",timeout:6e4});if($i(s),!wC(e.url()))throw new Error("Shipd authentication or job-link navigation failed. Check the saved job link and auth state.");if(a&&a.status()>=400)throw new Error(`Shipd job-link navigation returned HTTP ${a.status()}.`);await e.waitForTimeout(4e3),$i(s)}async function bEn(e,t,s,a){$i(a);let c=await wEn.launch({executablePath:e,headless:!0});try{let l=await c.newContext({storageState:t});await l.route("**/*",async p=>{let d=p.request().resourceType();d==="image"||d==="font"||d==="media"?await p.abort():await p.continue()});let u=await l.newPage();return await kPo(u,s,a),{browser:c,page:u}}catch(l){throw await c.close().catch(()=>{}),l}}async function EEn(e,t,s){await t.click({timeout:Xy}),await e.keyboard.press(`${process.platform==="darwin"?"Meta":"Control"}+A`),await e.keyboard.insertText(s)}async function LPo(e,t,s){$i(s);let a=e.locator("#problem-description"),c=e.locator('#problem-test-patch [contenteditable="true"][role="textbox"]'),l=e.locator('#problem-solution-patch [contenteditable="true"][role="textbox"]');for(let u of[a,c,l])if(await u.count()!==1)throw new Error("Shipd challenge form selectors were not found exactly once.");await a.fill(t.taskPrompt),await EEn(e,c,t.testPatch),await EEn(e,l,t.solutionPatch),await Xee(e,"Test Quality").hover(),await fL(1e3,s)}async function MPo(e,t,s){$i(s);let a=Xee(e,t),c=mL(await a.innerText());if(LEn(c))return{quality:t,status:"already-running",rowTextAfterConfirm:c};let l=a.locator('button[title^="Re-run"]').or(a.locator('button[title^="Run"]')),u=await l.count();if(u!==1)throw new Error(`${t}: expected one Run button, found ${u}`);if(!await l.isEnabled())throw new Error(`${t}: Run button is disabled.`);let p=await l.getAttribute("title");await l.click();let d=e.getByRole("dialog").last();await d.waitFor({state:"visible",timeout:Xy});let m=mL(await d.innerText()),S=d.getByRole("button",{name:/confirm/i});if(await S.count()!==1)throw new Error(`${t}: rerun confirmation button was not found.`);return await S.click(),await fL(500,s),{quality:t,status:"started",rerunTitle:p,confirmation:m}}async function xEn(e,t,s=NAe){let a=[];for(let c of s){$i(t);let l=kEn(e,c);if(await l.count()!==1)throw new Error(`${c}: quality status row was not found.`);await l.waitFor({state:"visible",timeout:Xy});let u=l.locator(".."),p=mL(await u.innerText()),d=await u.locator('button[title^="Run"]').count()>0;a.push({quality:c,rowText:p,busy:LEn(p),shouldRun:d||PPo(p)})}return a}async function GPo(e,t){return await Xee(e,t).locator('button[title^="Re-run"]').count()>0}async function OPo(e,t){await Xee(e,t).hover();let s=xPo(e,t);await s.waitFor({state:"visible",timeout:Xy});let a=s.locator('button[title="Expand to full view"]'),c=await a.count();if(c!==1)throw new Error(`${t}: expected one quality expander, found ${c}`);return a.first()}async function NPo(e,t,s){$i(s),await(await OPo(e,t)).click();let c=e.getByRole("dialog").last();await c.waitFor({state:"visible",timeout:Xy});let l=mL(await c.locator("h2").first().innerText().catch(()=>""));if(l!==t)throw new Error(`${t}: expanded the wrong report dialog (${l||"unknown"}).`);let u=c.locator("pre code").last();if(!await u.isVisible().catch(()=>!1)){let m=c.locator("button").filter({hasText:/raw output/i}).first();try{await m.waitFor({state:"visible",timeout:Xy})}catch{let S=mL(await c.innerText());throw new Error(`${t}: raw output control did not appear; dialog text: ${S.slice(0,1e3)}`)}await m.click()}await u.waitFor({state:"visible",timeout:Xy});let p=await u.innerText(),d=$Po(p,t);return await e.keyboard.press("Escape").catch(()=>{}),{quality:t,parsed:d}}function VPo(e,t){let s=Array.isArray(e?.coverageSuggestions)?e.coverageSuggestions:[],a=Array.isArray(e?.tests)?e.tests.filter(c=>wi(c)&&(c.fairness==="Not fair"||Array.isArray(c.concerns)&&c.concerns.length>0)).map(c=>c.fairness==="Not fair"&&Array.isArray(c.concerns)&&c.concerns.length===0?{...c,concerns:["Not fully fair"]}:c):[];return{testQuality:{verdict:e?a.length===0&&s.length===0?"PASS":"FAIL":null,coverageSuggestions:s,unfairnessCount:a.length,tests:a},solutionQuality:{verdict:t?FPo(t.evaluation)?"PASS":"FAIL":null,evaluation:qPo(t?.evaluation)}}}function PEn(e,t){if(!wi(e)||!wi(e[t]))return"\u2014";let s=e[t].score,a=e[t].max_score;return typeof s=="number"&&typeof a=="number"?`${s}/${a}`:"\u2014"}function qPo(e){return wi(e)?Object.fromEntries(Object.entries(e).filter(([t])=>t!=="overall_feedback").map(([t,s])=>[t,wi(s)?Object.fromEntries(Object.entries(s).filter(([a])=>a!=="level")):s])):e??null}function FPo(e){return!wi(e)||!["code_quality","solution_comprehensiveness"].every(a=>{let c=e[a];return wi(c)&&typeof c.score=="number"&&typeof c.max_score=="number"})?!1:Object.values(e).filter(a=>wi(a)&&("score"in a||"max_score"in a)).every(a=>typeof a.score=="number"&&typeof a.max_score=="number"&&a.score===a.max_score)}function BPo(e,t){let s=wi(e)?e:{},a=wi(s.testQuality)?s.testQuality:{},c=wi(s.solutionQuality)?s.solutionQuality:{},l=typeof a.unfairnessCount=="number"?a.unfairnessCount:Array.isArray(a.tests)?a.tests.length:0,u=Array.isArray(a.coverageSuggestions)?a.coverageSuggestions.length:0,p=c.evaluation,d=a.verdict===null?"skipped":`${l} unfairness \xB7 ${u} suggestions`,m=c.verdict===null?"skipped":`quality ${PEn(p,"code_quality")} \xB7 comprehensiveness ${PEn(p,"solution_comprehensiveness")}`;return[` ${t.fg("accent","Test Quality")} ${t.fg("muted",d)}`,` ${t.fg("accent","Solution Quality")} ${t.fg("muted",m)}`]}function $En(e,t){let a=e.find(c=>new RegExp(`^${t}:`,"i").test(c))?.match(/:\s*(\d+)/)?.[1];return a===void 0?void 0:Number.parseInt(a,10)}function UPo(e,t,s,a,c,l){return e==="new tests before solution"?t!==void 0&&t>0?"Some new tests pass before the solution; add assertions for behavior introduced by the solution.":l&&!/:\s*none$/i.test(l)?"New tests fail during collection; move solution-dependent imports or setup into each test so every testcase fails or errors individually.":t===0&&/:\s*none$/i.test(a)&&/:\s*none$/i.test(c)?"The test file did not produce individual failures or errors; use lazy imports so every test executes separately.":"Every new test must fail or error individually before the solution.":e==="new tests after solution"?s!==void 0&&s>0?"New tests were skipped after the solution; every new test must execute and pass.":"The solution does not make every new test pass.":e==="base tests after solution"?"Base-test regression: existing base tests fail after the solution.":e==="base tests before solution"?"Base tests fail before the solution; review the test patch and test setup.":"The patch precheck did not meet the required test outcomes."}function HPo(e){let t=(e.content??[]).map(c=>c.type==="text"?c.text??"":"").join(" "),s=t.split(/\r?\n/).map(c=>c.trim().replace(/\s+/g," ")).filter(Boolean),a=s.find(c=>/^phase:/i.test(c));if(/patch precheck/i.test(t)){if(a){let c=a.replace(/^phase:\s*/i,""),l=$En(s,"passed tests"),u=$En(s,"skipped tests"),p=s.find(S=>/^failed tests:/i.test(S))??"",d=s.find(S=>/^errored tests:/i.test(S))??"",m=s.find(S=>/^collection errors:/i.test(S))??"";return["Patch precheck failed.",`Phase: ${c}`,`Problem: ${UPo(c,l,u,p,d,m)}`].join(`
|
|
111
111
|
`)}return`Patch precheck failed.
|
|
112
112
|
Problem: The precheck task could not be completed.`}return s.map(c=>c.replace(/\bFargate\b\s*/gi,"").trim()).slice(0,4).join(`
|
|
113
113
|
`)||"Quality checks failed"}function jPo(e){let t=`Fargate patch precheck failed:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sreetej510/pi-shipd-checks",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.16",
|
|
4
4
|
"description": "Pi extension that runs a strict, multi-agent fairness review of a benchmark task's agent_prompt.md, test.patch, and solution.patch, plus behavioral test-gap analysis, via /checks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|