@sreetej510/pi-shipd-checks 0.10.7 → 0.10.9

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/index.js CHANGED
@@ -89,7 +89,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
89
89
  `)}function Uke(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.",GMn(t),OMn(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 \`${DT}\` tool exactly once with the complete candidate list. That tool call is your only way to report a result.`].join(`
90
90
  `)}function qMn(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 \`${BC}/solver_${e.index}/\``}function Hke(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 \`${BC}/solver_<index>/\` (\`solution.diff\`, \`test_output.txt\`), with a \`${BC}/manifest.json\` summary. Use read/grep/find/ls to open exactly what you need. Status summary:`,"",...e.map(qMn),"","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 \`${bT}\` 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 FMn=900*1e3,Ane=["read","grep","find","ls"];function Dne(e){return e==="off"?void 0:e}async function bne(e,t,s=FMn){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 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:[Vke(t)],sessionManager:Tne.inMemory()}));let c=await bne(async()=>{await a?.prompt(Bke(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 zke(e){let t={},s=e.model,a;try{({session:a}=await Cne({cwd:e.tempDir,model:s,thinkingLevel:Dne(e.thinkingLevel),tools:[...Ane,bT],customTools:[Fke(t)],sessionManager:Tne.inMemory()}));let c=await bne(async()=>{await a?.prompt(Hke(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 Kke(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:[qke(t)],sessionManager:Tne.inMemory()}));let c=await bne(async()=>{await a?.prompt(Uke(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 zg=Xn($tn(),1),yo=Xn(gdn(),1),_r=Xn(dDn(),1),jee=Xn(tEn(),1),aEn=Xn(j_(),1),Xy=Xn(nEn(),1);import{randomUUID as DAe}from"node:crypto";import{createReadStream as Lxo,existsSync as xAe,mkdirSync as Mxo,readFileSync as oEn,rmSync as bAe,writeFileSync as wC}from"node:fs";import{tmpdir as EAe}from"node:os";import{join as fd}from"node:path";import{fileURLToPath as rEn}from"node:url";import{posix as Pxo}from"node:path";function sEn(e){let t,s="/",a={},c=[];for(let l of wxo(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=Uee(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=Pxo.resolve(s,d);break;case"ENV":$xo(d,a);break;case"COPY":if(Uee(d).length<2||Uee(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 $xo(e,t){let s=Uee(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 wxo(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();kxo(l)?s=`${l.slice(0,-1).trimEnd()} `:(l.trim()&&t.push(l.trim()),s="")}return s.trim()&&t.push(s.trim()),t}function kxo(e){let t=0;for(let s=e.length-1;s>=0&&e[s]==="\\";s-=1)t+=1;return t%2===1}function Uee(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 iEn="shipd-worker",Gxo="fargate-worker.mjs",$C=3300,Oxo=5e3;function cEn(e){return new Promise(t=>setTimeout(t,e))}function Nxo(e,t){let s=(0,aEn.defaultProvider)({profile:process.env.AWS_PROFILE??t}),a={region:e,credentials:s,maxAttempts:5};return{ecs:new yo.ECSClient(a),ec2:new zg.EC2Client(a),s3:new _r.S3Client(a),sts:new jee.STSClient(a)}}async function lEn(e){if(e.cancelSignal.aborted)throw new Error("Cancelled by user.");e.onPhase?.("preparing image");let t=fd(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=sEn(oEn(t,"utf-8")),a=qxo(e.config,e.repoDir,e.mode),c=process.env.AWS_REGION??a.region??"us-east-1",l=Nxo(c,a.awsProfile),u=sDe(e.repoDir,a),p=fd(EAe(),`.shipd-fargate-source-${DAe()}.tar.gz`),d=Bxo(),m=e.solverConfig,S=e.mode==="solver"?fd(Fxo(),"auth.json"):void 0,v=S?fd(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 B={source:`runs/${e.runId}/source.tar.gz`,worker:`runs/${e.runId}/${Gxo}`,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 jxo(l,a,c);w=ee.bucket,x=ee.cluster,await Uxo(e.pi,e.snapshotDir,p,e.cancelSignal,e.mode==="solver"),await Hee(l.s3,ee.bucket,B.source,p,"application/gzip"),await Hee(l.s3,ee.bucket,B.worker,d,"text/javascript"),S&&v&&m&&(Hxo(S,m.provider,v),await Hee(l.s3,ee.bucket,B.auth,v,"application/json")),L=fd(EAe(),`.shipd-fargate-bootstrap-${DAe()}.json`);let ie=await Kxo(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,Xy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:B.worker}),{expiresIn:$C}),ce=_e?void 0:await(0,Xy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:B.source}),{expiresIn:$C}),M=_e||!S?void 0:await(0,Xy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:B.auth}),{expiresIn:$C}),se=_e?void 0:await(0,Xy.getSignedUrl)(l.s3,new _r.PutObjectCommand({Bucket:ee.bucket,Key:B.result,ContentType:"application/json"}),{expiresIn:$C}),Yo=_e?void 0:await(0,Xy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:B.result}),{expiresIn:$C});wC(L,`${JSON.stringify({workerUrl:tt,sourceUrl:ce,authUrl:M,resultPutUrl:se,resultGetUrl:Yo,..._e?{bucket:ee.bucket,region:c,sourceKey:B.source,...S?{authKey:B.auth}:{},resultKey:B.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 Hee(l.s3,ee.bucket,B.bootstrap,L,"application/json");let RL=await(0,Xy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:B.bootstrap}),{expiresIn:$C}),SL={name:iEn,environment:[{name:"SHIPD_BOOTSTRAP_URL",value:RL}]},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:[SL]}})),yL=gc.failures?.[0]?.reason;if(T=gc.tasks?.[0]?.taskArn,x=ee.cluster,!T){Ce=yL??"Fargate could not place the Spot task.",e.onPhase?.("requesting sandbox");continue}e.onPhase?.("sandbox created");let Za=await Qxo(l.ecs,ee.cluster,T,()=>Zxo(l.s3,ee.bucket,B.result),we,e.cancelSignal,(Mm,IL)=>{e.mode==="solver"&&e.onSolverProgress?.(Mm),IL&&e.onResourceUsage?.(IL)},()=>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=Xxo(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 Wxo(l.ecs,x,T)),await ePo(l.s3,w,B).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 uEn(e){let t=await lEn({...e,mode:"solver"}),s=await Yxo(e,t.results,e.solverConfig.saveArtifacts);for(let a of s)e.onSolverCompleted?.(a);return s}function Vxo(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(`
92
+ `,"utf-8"),await Hee(l.s3,ee.bucket,B.bootstrap,L,"application/json");let RL=await(0,Xy.getSignedUrl)(l.s3,new _r.GetObjectCommand({Bucket:ee.bucket,Key:B.bootstrap}),{expiresIn:$C}),SL={name:iEn,environment:[{name:"SHIPD_BOOTSTRAP_URL",value:RL}]},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:[SL]}})),yL=gc.failures?.[0]?.reason;if(T=gc.tasks?.[0]?.taskArn,x=ee.cluster,!T){Ce=yL??"Fargate could not place the Spot task.",e.onPhase?.("requesting sandbox");continue}e.onPhase?.("sandbox created");let Za=await Qxo(l.ecs,ee.cluster,T,()=>Zxo(l.s3,ee.bucket,B.result),we,e.cancelSignal,(Mm,IL)=>{e.mode==="solver"&&e.onSolverProgress?.(Mm),IL&&e.onResourceUsage?.(IL)},()=>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=Xxo(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 Wxo(l.ecs,x,T)),await ePo(l.s3,w,B).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 uEn(e){let t=await lEn({...e,mode:"solver"}),s=await Yxo(e,t.results,e.solverConfig.saveArtifacts);for(let a of s)e.onSolverCompleted?.(a);return s}function Vxo(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 case or subtest fails or errors individually before the solution; no new case may pass. Do not remove tests.",`passed tests: ${t.passedTestcases}`,`skipped tests: ${t.skippedTestcases??"unknown"}`,`passing tests: ${t.passedTestNames.length>0?t.passedTestNames.join(", "):"none"}`,`partially passing tests (also failed): ${t.partiallyPassedTestNames.length>0?t.partiallyPassedTestNames.join(", "):"none"}`,`failed tests: ${t.failedTestNames.length>0?t.failedTestNames.join(", "):"none"}`,`errored tests: ${t.erroredTestNames.length>0?t.erroredTestNames.join(", "):"none"}`].join(`
93
93
  `);return{...e,status:"failed",passed:!1,error:s}}async function pEn(e){try{let t=await lEn({...e,mode:"patch-precheck"});if(!t.precheck)throw new Error(t.error??"no result was returned");return Vxo(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 qxo(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 Fxo(){let e=Math.max(Ya.lastIndexOf("/"),Ya.lastIndexOf("\\"));return e>=0?Ya.slice(0,e):"."}function Bxo(){let t=[rEn(new URL("./fargate-worker.mjs",import.meta.url)),rEn(new URL("../dist/fargate-worker.mjs",import.meta.url)),fd(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 Uxo(e,t,s,a,c){let p=`tar ${process.platform==="win32"?"--force-local ":""}${c?"--exclude=./solution.patch ":""}-czf ${il(Wg(s))} -C ${il(Wg(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 Hxo(e,t,s){let a;try{a=JSON.parse(oEn(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){wC(s,`{}
@@ -107,7 +107,7 @@ ${t instanceof Error?t.message:String(t)}`)}}function qxo(e,t,s){let a=e.fargate
107
107
  Required behavior: ${s.requiredBehavior}
108
108
  Recommendation: ${s.recommendation}`)].join(`
109
109
  `)}import{spawn as hPo}from"node:child_process";import{randomUUID as vPo}from"node:crypto";import{existsSync as VAe,mkdirSync as CPo}from"node:fs";import{mkdtemp as CEn,readFile as LAe,rm as MAe,writeFile as TEn}from"node:fs/promises";import{createServer as TPo}from"node:net";import{homedir as APo,tmpdir as AEn}from"node:os";import{dirname as DPo,join as al}from"node:path";import{Text as mL}from"@earendil-works/pi-tui";import{chromium as LEn}from"playwright-core";var Xee="quality-check",GAe="shipd:link",OAe="shipd_job_link",DEn=al(APo(),".pi","agent","shipd-auth","shipd.ai.json"),bPo=15,bEn="https://shipd.ai/",EPo=12e4,xPo=3e5,PPo=9e4,eI=5e3,NAe=["Test Quality","Solution Quality"],$Po=Ct.Object({});function fL(e){return(e??"").trim().replace(/\s+/g," ")}function wPo(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function wi(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function gL(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 EEn(){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 kPo(){let e=TPo();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 LPo(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 gL(250)}throw new Error("Timed out waiting for Chrome to start.")}async function MPo(e,t=3e4){let s=Date.now()+t;for(;Date.now()<s;){let a=e.pages();for(let c of a){if(!LC(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)LC(c.url())&&await c.reload({waitUntil:"domcontentloaded",timeout:15e3}).catch(()=>{});await gL(1e3)}}function LC(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 GPo(e){try{return/\/sign-in(?:\/|$)/i.test(new URL(e).pathname)}catch{return!1}}function OPo(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"&&LC(a.url)?t=a.url:a.url===null&&(t=void 0))}return t}function MEn(e,t){return e.locator("span").filter({hasText:new RegExp(`^${wPo(t)}$`)}).first()}function Jee(e,t){return MEn(e,t).locator("..")}function NPo(e,t){return e.locator("div.fixed").filter({hasText:t}).last()}function GEn(e){return/(?:starting|queued|pending|running|processing|reviewing|finalizing|building|evaluating|checking|\d+%)/i.test(e)}function VPo(e){return/\bstale\b/i.test(e)}function qPo(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 FPo(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(NC(),["create_patches.sh"],{cwd:t,timeout:EPo,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 BPo(e,t,s){$i(s);let a=await e.goto(t,{waitUntil:"domcontentloaded",timeout:6e4});if($i(s),!LC(e.url()))throw new Error("Shipd authentication or job-link navigation failed. Check the saved job link and auth state.");if(GPo(e.url()))throw new Error("Shipd authentication failed: the saved session is expired or signed out. Run /shipd:auth again.");if(a&&a.status()>=400)throw new Error(`Shipd job-link navigation returned HTTP ${a.status()}.`);await e.waitForTimeout(4e3),$i(s)}async function xEn(e,t,s,a){$i(a);let c=await LEn.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 BPo(u,s,a),{browser:c,page:u}}catch(l){throw await c.close().catch(()=>{}),l}}async function PEn(e,t,s){await t.click({timeout:eI}),await e.keyboard.press(`${process.platform==="darwin"?"Meta":"Control"}+A`),await e.keyboard.insertText(s)}async function UPo(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 PEn(e,c,t.testPatch),await PEn(e,l,t.solutionPatch),await Jee(e,"Test Quality").hover(),await gL(1e3,s)}async function HPo(e,t,s){$i(s);let a=Jee(e,t),c=fL(await a.innerText());if(GEn(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:eI});let m=fL(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 gL(500,s),{quality:t,status:"started",rerunTitle:p,confirmation:m}}async function $En(e,t,s=NAe){let a=[];for(let c of s){$i(t);let l=MEn(e,c);if(await l.count()!==1)throw new Error(`${c}: quality status row was not found.`);await l.waitFor({state:"visible",timeout:eI});let u=l.locator(".."),p=fL(await u.innerText()),d=await u.locator('button[title^="Run"]').count()>0;a.push({quality:c,rowText:p,busy:GEn(p),shouldRun:d||VPo(p)})}return a}async function jPo(e,t){return await Jee(e,t).locator('button[title^="Re-run"]').count()>0}async function zPo(e,t){await Jee(e,t).hover();let s=NPo(e,t);await s.waitFor({state:"visible",timeout:eI});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 KPo(e,t,s){$i(s),await(await zPo(e,t)).click();let c=e.getByRole("dialog").last();await c.waitFor({state:"visible",timeout:eI});let l=fL(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:eI})}catch{let S=fL(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:eI});let p=await u.innerText(),d=qPo(p,t);return await e.keyboard.press("Escape").catch(()=>{}),{quality:t,parsed:d}}function WPo(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?ZPo(t.evaluation)?"PASS":"FAIL":null,evaluation:QPo(t?.evaluation)}}}function wEn(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 ZPo(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 YPo(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 ${wEn(p,"code_quality")} \xB7 comprehensiveness ${wEn(p,"solution_comprehensiveness")}`;return[` ${t.fg("accent","Test Quality")} ${t.fg("muted",d)}`,` ${t.fg("accent","Solution Quality")} ${t.fg("muted",m)}`]}function kEn(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 XPo(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 JPo(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=kEn(s,"passed tests"),u=kEn(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: ${XPo(c,l,u,p,d,m)}`].join(`
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 BPo(e,t,s){$i(s);let a=await e.goto(t,{waitUntil:"domcontentloaded",timeout:6e4});if($i(s),!LC(e.url()))throw new Error("Shipd authentication or job-link navigation failed. Check the saved job link and auth state.");if(GPo(e.url()))throw new Error("Shipd authentication failed: the saved session is expired or signed out. Run /shipd:auth again.");if(a&&a.status()>=400)throw new Error(`Shipd job-link navigation returned HTTP ${a.status()}.`);await e.waitForTimeout(4e3),$i(s)}async function xEn(e,t,s,a){$i(a);let c=await LEn.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 BPo(u,s,a),{browser:c,page:u}}catch(l){throw await c.close().catch(()=>{}),l}}async function PEn(e,t,s){await t.click({timeout:eI}),await e.keyboard.press(`${process.platform==="darwin"?"Meta":"Control"}+A`),await e.keyboard.insertText(s)}async function UPo(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 PEn(e,c,t.testPatch),await PEn(e,l,t.solutionPatch),await Jee(e,"Test Quality").hover(),await gL(1e3,s)}async function HPo(e,t,s){$i(s);let a=Jee(e,t),c=fL(await a.innerText());if(GEn(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:eI});let m=fL(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 gL(500,s),{quality:t,status:"started",rerunTitle:p,confirmation:m}}async function $En(e,t,s=NAe){let a=[];for(let c of s){$i(t);let l=MEn(e,c);if(await l.count()!==1)throw new Error(`${c}: quality status row was not found.`);await l.waitFor({state:"visible",timeout:eI});let u=l.locator(".."),p=fL(await u.innerText()),d=await u.locator('button[title^="Run"]').count()>0;a.push({quality:c,rowText:p,busy:GEn(p),shouldRun:d||VPo(p)})}return a}async function jPo(e,t){return await Jee(e,t).locator('button[title^="Re-run"]').count()>0}async function zPo(e,t){await Jee(e,t).hover();let s=NPo(e,t);await s.waitFor({state:"visible",timeout:eI});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 KPo(e,t,s){$i(s),await(await zPo(e,t)).click();let c=e.getByRole("dialog").last();await c.waitFor({state:"visible",timeout:eI});let l=fL(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:eI})}catch{let S=fL(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:eI});let p=await u.innerText(),d=qPo(p,t);return await e.keyboard.press("Escape").catch(()=>{}),{quality:t,parsed:d}}function WPo(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?ZPo(t.evaluation)?"PASS":"FAIL":null,evaluation:QPo(t?.evaluation)}}}function wEn(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 ZPo(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 YPo(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 ${wEn(p,"code_quality")} \xB7 comprehensiveness ${wEn(p,"solution_comprehensiveness")}`;return[` ${t.fg("accent","Test Quality")} ${t.fg("muted",d)}`,` ${t.fg("accent","Solution Quality")} ${t.fg("muted",m)}`]}function kEn(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 XPo(e,t,s,a,c,l){return e==="new tests before solution"?t!==void 0&&t>0?"Some individual test cases or subtests pass before the solution; the precheck remains failed. Ensure every new case fails or errors before 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 JPo(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=kEn(s,"passed tests"),u=kEn(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: ${XPo(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 e$o(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.10.7",
3
+ "version": "0.10.9",
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",