@sreetej510/pi-shipd-checks 0.5.1 → 0.5.3

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.
@@ -2516,6 +2516,6 @@ Options:
2516
2516
  ${n}`,"/work",t,900*1e3);for(let o of e.runtimeCommands)nvc(o)||await eye(o,e.workdir,t,900*1e3)}function eu(e){return`'${e.replace(/'/g,"'\\''")}'`}function oUo(e){let t=HKe(e,"utf-8");ste(e,t.replace(/\r\n?/g,`
2517
2517
  `),"utf-8")}async function svc(e,t,r){let n=ote.join(tUo,`solver_${e}`),o=ote.join(n,"test.patch"),s=[`mkdir -p ${eu(n)}`,`tar --exclude=.git --exclude=solution.patch -cf - -C ${eu(t.workdir)} . | tar --no-same-owner -xf - -C ${eu(n)}`,`rm -rf ${eu(ote.join(n,".git"))} ${eu(ote.join(n,"solution.patch"))} ${eu(o)}`,`git -C ${eu(n)} init -q`,`git -C ${eu(n)} config user.email solvergap@shipd-checks.local`,`git -C ${eu(n)} config user.name shipd-checks-solver`,`git -C ${eu(n)} add -A`,`git -C ${eu(n)} commit -q -m baseline --allow-empty`,`cp ${eu(ote.join(t.workdir,"test.patch"))} ${eu(o)}`,`git -C ${eu(n)} apply --recount ${eu(o)}`,`chmod +x ${eu(ote.join(n,"test.sh"))}`,`rm -f ${eu(o)}`,`git -C ${eu(n)} add -A`,`git -C ${eu(n)} commit -q -m tests-applied --allow-empty`];await eye(`set -eu
2518
2518
  ${s.join(`
2519
- `)}`,"/work",r,900*1e3);let i=yM(n,"test.sh");S9t(i)&&oUo(i);let a=await eye(`git -C ${eu(n)} rev-parse HEAD`,"/work",r,3e4),c=HKe(yM(t.workdir,"test.patch"),"utf-8");return{solverDir:n,testsAppliedCommit:a.stdout.trim(),testPatchPaths:ivc(c)}}function ivc(e){let t=new Set,r=/^diff --git "?a\/(.+?)"? "?b\/(.+?)"?$/gm;for(let n of e.matchAll(r))n[1]&&t.add(n[1]),n[2]&&t.add(n[2]);return[...t]}async function avc(e,t,r){let n=Date.now(),o=bg("SHIPD_PROVIDER"),s=bg("SHIPD_MODEL_ID"),i=bg("SHIPD_THINKING_LEVEL"),a=Number.parseInt(bg("SHIPD_TIMEOUT_MINUTES"),10),c=Min(o,s);if(!c)return{index:e,status:"error",passed:!1,diff:"",testOutputTail:`Could not resolve model ${o}/${s}.`,durationMs:Date.now()-n,totalTests:null,failedTests:null};let u="error",l=[];try{let _=cl.inMemory(),E;try{({session:E}=await Iee({cwd:t.solverDir,agentDir:Z_e,model:c,thinkingLevel:i==="off"?void 0:i,tools:["read","grep","find","ls","write","edit","bash"],sessionManager:_}));let S=E.prompt(Y1o());S.catch(()=>{});let v,x=new Promise((R,N)=>{v=setTimeout(()=>N(new Error("__SHIPD_SOLVER_TIMEOUT__")),a*60*1e3)});try{await Promise.race([S,x]),u="done"}catch(R){if(R instanceof Error&&R.message==="__SHIPD_SOLVER_TIMEOUT__")u="timedOut",await E.abort().catch(()=>{});else throw R}finally{v&&clearTimeout(v)}}finally{if(l=_.getEntries(),E)try{E.dispose()}catch{}}}catch(_){return{index:e,status:"error",passed:!1,diff:"",testOutputTail:_ instanceof Error?_.message:String(_),durationMs:Date.now()-n,totalTests:null,failedTests:null,trajectory:l}}let p=[...t.testPatchPaths,"agent_prompt.md"].map(_=>`:(exclude)${_}`),d=await b9t(`git add -A && git diff --cached ${eu(t.testsAppliedCommit)} -- . ${p.map(eu).join(" ")}`,t.solverDir,r,3e4),f=yM(t.solverDir,"test_output.xml"),m=await b9t(`bash test.sh --output_path ${eu(f)} new`,t.solverDir,r,(a+5)*60*1e3),h=`${m.stdout}
2519
+ `)}`,"/work",r,900*1e3);let i=yM(n,"test.sh");S9t(i)&&oUo(i);let a=await eye(`git -C ${eu(n)} rev-parse HEAD`,"/work",r,3e4),c=HKe(yM(t.workdir,"test.patch"),"utf-8");return{solverDir:n,testsAppliedCommit:a.stdout.trim(),testPatchPaths:ivc(c)}}function ivc(e){let t=new Set,r=/^diff --git "?a\/(.+?)"? "?b\/(.+?)"?$/gm;for(let n of e.matchAll(r))n[1]&&t.add(n[1]),n[2]&&t.add(n[2]);return[...t]}async function avc(e,t,r){let n=Date.now(),o=bg("SHIPD_PROVIDER"),s=bg("SHIPD_MODEL_ID"),i=bg("SHIPD_THINKING_LEVEL"),a=Number.parseInt(bg("SHIPD_TIMEOUT_MINUTES"),10),c=Min(o,s);if(!c)return{index:e,status:"error",passed:!1,diff:"",testOutputTail:`Could not resolve model ${o}/${s}.`,error:`Could not resolve model ${o}/${s}.`,durationMs:Date.now()-n,totalTests:null,failedTests:null};let u="error",l=[];try{let _=cl.inMemory(),E;try{({session:E}=await Iee({cwd:t.solverDir,agentDir:Z_e,model:c,thinkingLevel:i==="off"?void 0:i,tools:["read","grep","find","ls","write","edit","bash"],sessionManager:_}));let S=E.prompt(Y1o());S.catch(()=>{});let v,x=new Promise((R,N)=>{v=setTimeout(()=>N(new Error("__SHIPD_SOLVER_TIMEOUT__")),a*60*1e3)});try{await Promise.race([S,x]),u="done"}catch(R){if(R instanceof Error&&R.message==="__SHIPD_SOLVER_TIMEOUT__")u="timedOut",await E.abort().catch(()=>{});else throw R}finally{v&&clearTimeout(v)}}finally{if(l=_.getEntries(),E)try{E.dispose()}catch{}}}catch(_){return{index:e,status:"error",passed:!1,diff:"",testOutputTail:_ instanceof Error?_.message:String(_),error:_ instanceof Error?_.message:String(_),durationMs:Date.now()-n,totalTests:null,failedTests:null,trajectory:l}}let p=[...t.testPatchPaths,"agent_prompt.md"].map(_=>`:(exclude)${_}`),d=await b9t(`git add -A && git diff --cached ${eu(t.testsAppliedCommit)} -- . ${p.map(eu).join(" ")}`,t.solverDir,r,3e4),f=yM(t.solverDir,"test_output.xml"),m=await b9t(`bash test.sh --output_path ${eu(f)} new`,t.solverDir,r,(a+5)*60*1e3),h=`${m.stdout}
2520
2520
  ${m.stderr}`.trim();ste(yM(t.solverDir,"test_output.txt"),h,"utf-8"),ste(yM(t.solverDir,"trajectory.json"),`${JSON.stringify(l,null,2)}
2521
2521
  `,"utf-8");let g=cvc(f),y=u==="done"?"ok":u;return{index:e,status:y,passed:y==="ok"&&m.code===0,diff:d.code===0?d.stdout:"",testOutputTail:ZCc(h),durationMs:Date.now()-n,totalTests:g.totalTests,failedTests:g.failedTests,trajectory:l}}function cvc(e){try{let t=HKe(e,"utf-8").match(/<testsuites\b[^>]*>/i)?.[0];if(!t)return{totalTests:null,failedTests:null};let r=i=>Number.parseInt(t.match(new RegExp(`\\b${i}="(\\d+)"`,"i"))?.[1]??"",10),n=r("tests"),o=r("failures"),s=r("errors");return{totalTests:Number.isFinite(n)?n:null,failedTests:Number.isFinite(o)?o+(Number.isFinite(s)?s:0):null}}catch{return{totalTests:null,failedTests:null}}}async function lvc(){evc();let e=process.env.SHIPD_RESULT_PUT_URL??"",t=process.env.SHIPD_RESULT_GET_URL??"",r=bg("SHIPD_RESOURCE_PROFILE");X_e=new jKe(r),X_e.start();let n=await sUo(t),o=new Map((n?.results??[]).map(h=>[h.index,h])),s=tvc(),i=rvc(s);QKe(Z_e,{recursive:!0}),ite()?await nUo(bg("SHIPD_S3_BUCKET"),bg("SHIPD_S3_AUTH_KEY"),yM(Z_e,"auth.json")):await rUo(bg("SHIPD_AUTH_URL"),yM(Z_e,"auth.json")),ste(yM(Z_e,"settings.json"),JSON.stringify({shellPath:"/bin/bash"}),"utf-8"),QKe("/work",{recursive:!0}),await ovc(s,i);let a=yM(s.workdir,"test.patch");S9t(a)&&oUo(a);let c=Math.max(1,Number.parseInt(bg("SHIPD_SOLVER_COUNT"),10));QKe(tUo,{recursive:!0});let u=Array.from({length:c},(h,g)=>g+1).filter(h=>!o.has(h)),l=[];for(let h of u)l.push(await svc(h,s,i));let p=Promise.resolve(),d=h=>{o.set(h.index,h);let g=[...o.values()].sort((y,_)=>y.index-_.index);return p=p.then(()=>A9t(e,{complete:!1,results:g,resourceUsage:X_e?.snapshot()})),p};await Promise.all(l.map(async(h,g)=>{let y=u[g];if(y===void 0)throw new Error("Fargate solver workspace index mismatch.");let _=await avc(y,h,i);await d(_)})),await p;let f=[...o.values()].sort((h,g)=>h.index-g.index),m=X_e?.stop();await A9t(e,{complete:!0,results:f,resourceUsage:m})}async function sUo(e){try{if(ite()){let n=await(await x9t().send(new wV.GetObjectCommand({Bucket:bg("SHIPD_S3_BUCKET"),Key:bg("SHIPD_S3_RESULT_KEY")}))).Body?.transformToString();return n?JSON.parse(n):void 0}let t=await fetch(e);return t.ok?await t.json():void 0}catch{return}}lvc().catch(async e=>{let t=e instanceof Error?e.message:String(e),r=X_e?.stop();try{let n=process.env.SHIPD_RESULT_PUT_URL??"",o=process.env.SHIPD_RESULT_GET_URL??"",s=o||ite()?await sUo(o):void 0;(n||ite())&&await A9t(n,{complete:!0,results:s?.results??[],resourceUsage:r,error:t})}catch{}console.error(t),process.exitCode=1});
package/dist/index.js CHANGED
@@ -94,7 +94,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
94
94
  `)}function RMn(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 Gke(e,t,s){let a=["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(RMn),"","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.","",...xke,"- 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];return s&&a.push("","Fairness methodology (context on what a fair, in-scope requirement looks like):",s),a.push("",`When you are done, call the \`${PT}\` tool exactly once with your final list (which may be empty). That tool call is your only way to report a result.`),a.join(`
95
95
  `)}var SMn=900*1e3,cR=["read","grep","find","ls"];function lR(e){return e==="off"?void 0:e}async function uR(e,t,s=SMn){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 pR(e){if(e){try{e.isIdle||await e.abort()}catch{}e.dispose()}}async function Oke(e){let t={},s=e.model,a;try{({session:a}=await aR({cwd:e.tempDir,model:s,thinkingLevel:lR(e.thinkingLevel),tools:[...cR,TT],customTools:[Ike(t)],sessionManager:iR.inMemory()}));let c=await uR(async()=>{await a?.prompt(Pke(e.testRubric,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 pR(a)}return t.statements?{status:"ok",gaps:t.statements}:{status:"noSubmission",gaps:[]}}async function Nke(e){let t={},s=e.model,a;try{({session:a}=await aR({cwd:e.tempDir,model:s,thinkingLevel:lR(e.thinkingLevel),tools:[...cR,PT],customTools:[Dke(t)],sessionManager:iR.inMemory()}));let c=await uR(async()=>{await a?.prompt(Gke(e.solverResults,e.testRubric,e.fairnessRules))},e.cancelSignal);if(c!=="done")return await a.abort(),{status:c,gaps:[]}}catch{return{status:"error",gaps:[]}}finally{await pR(a)}return t.gaps?{status:"ok",gaps:t.gaps}:{status:"noSubmission",gaps:[]}}async function Vke(e){let t={},s=e.model,a;try{({session:a}=await aR({cwd:e.tempDir,model:s,thinkingLevel:lR(e.thinkingLevel),tools:[...cR,AT],customTools:[yke(t)],sessionManager:iR.inMemory()}));let c=await uR(async()=>{await a?.prompt($ke(e.statementReports,e.testRubric,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 pR(a)}return t.gaps?{status:"ok",gaps:t.gaps}:{status:"noSubmission",gaps:[]}}async function qke(e){let t={},s=e.model,a;try{({session:a}=await aR({cwd:e.tempDir,model:s,thinkingLevel:lR(e.thinkingLevel),tools:[...cR,DT],customTools:[hke(t)],sessionManager:iR.inMemory()}));let c=await uR(async()=>{await a?.prompt(wke(e.testRubric,e.fairnessRules,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 pR(a)}return t.findings?{status:"ok",findings:t.findings}:{status:"noSubmission",findings:[]}}async function Fke(e){let t={},s=e.model,a;try{({session:a}=await aR({cwd:e.tempDir,model:s,thinkingLevel:lR(e.thinkingLevel),tools:[...cR,bT],customTools:[vke(t)],sessionManager:iR.inMemory()}));let c=await uR(async()=>{await a?.prompt(kke(e.findings,e.testRubric,e.fairnessRules,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 pR(a)}return t.findings?{status:"ok",findings:t.findings}:{status:"noSubmission",findings:[]}}async function Bke(e){let t={},s=e.model,a;try{({session:a}=await aR({cwd:e.tempDir,model:s,thinkingLevel:lR(e.thinkingLevel),tools:[...cR,ET],customTools:[Tke(t)],sessionManager:iR.inMemory()}));let c=await uR(async()=>{await a?.prompt(Lke(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 pR(a)}return t.findings?{status:"ok",findings:t.findings}:{status:"noSubmission",findings:[]}}async function Uke(e){let t={},s=e.model,a;try{({session:a}=await aR({cwd:e.tempDir,model:s,thinkingLevel:lR(e.thinkingLevel),tools:[...cR,xT],customTools:[Ake(t)],sessionManager:iR.inMemory()}));let c=await uR(async()=>{await a?.prompt(Mke(e.findings,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 pR(a)}return t.findings?{status:"ok",findings:t.findings}:{status:"noSubmission",findings:[]}}var Hg=Xn(Atn(),1),yo=Xn(ldn(),1),hr=Xn(aDn(),1),zee=Xn(Zbn(),1),sEn=Xn(W_(),1),ty=Xn(Qbn(),1);import{randomUUID as Xbn}from"node:crypto";import{createReadStream as uxo,existsSync as IAe,mkdirSync as pxo,readFileSync as dxo,rmSync as Jbn,writeFileSync as jee}from"node:fs";import{tmpdir as eEn}from"node:os";import{join as km}from"node:path";import{fileURLToPath as tEn}from"node:url";import{posix as axo}from"node:path";function Ybn(e){let t,s="/",a={},c=[];for(let l of cxo(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=axo.resolve(s,d);break;case"ENV":ixo(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 ixo(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 cxo(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();lxo(l)?s=`${l.slice(0,-1).trimEnd()} `:(l.trim()&&t.push(l.trim()),s="")}return s.trim()&&t.push(s.trim()),t}function lxo(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 rEn="shipd-worker",mxo="fargate-worker.mjs",LC=3300,fxo=5e3;function oEn(e){return new Promise(t=>setTimeout(t,e))}function gxo(e,t){let s=(0,sEn.defaultProvider)({profile:process.env.AWS_PROFILE??t}),a={region:e,credentials:s,maxAttempts:5};return{ecs:new yo.ECSClient(a),ec2:new Hg.EC2Client(a),s3:new hr.S3Client(a),sts:new zee.STSClient(a)}}async function aEn(e){if(e.cancelSignal.aborted)throw new Error("Cancelled by user.");e.onPhase?.("preparing image");let t=km(e.repoDir,"Dockerfile");if(!IAe(t))throw new Error("Fargate solver gap finder requires Dockerfile in the project root.");let s=Ybn(dxo(t,"utf-8")),a=Rxo(e.config,e.repoDir),c=process.env.AWS_REGION??a.region??"us-east-1",l=gxo(c,a.awsProfile),u=NAe(e.repoDir,a),p=km(eEn(),`.shipd-fargate-source-${Xbn()}.tar.gz`),d=Ixo(),m=km(Sxo(),"auth.json");if(!IAe(m))throw new Error(`Missing Pi auth file: ${m}`);let S,v,A,x,w=!1,L=()=>{S&&(w=!0,l.ecs.send(new yo.StopTaskCommand({cluster:v,task:S,reason:"shipd checks cancelled"})).catch(()=>{}))};e.cancelSignal.addEventListener("abort",L,{once:!0});let M={source:`runs/${e.runId}/source.tar.gz`,worker:`runs/${e.runId}/${mxo}`,auth:`runs/${e.runId}/auth.json`,bootstrap:`runs/${e.runId}/bootstrap.json`,result:`runs/${e.runId}/result.json`};try{let G=await _xo(l,a,c);A=G.bucket,v=G.cluster,await yxo(e.pi,e.snapshotDir,p,e.cancelSignal),await Hee(l.s3,G.bucket,M.source,p,"application/gzip"),await Hee(l.s3,G.bucket,M.worker,d,"text/javascript"),await Hee(l.s3,G.bucket,M.auth,m,"application/json"),x=km(eEn(),`.shipd-fargate-bootstrap-${Xbn()}.json`);let K=await vxo(l.ecs,s,u.cpu,u.memoryMiB,c,a),re=Math.max(1,Math.floor(e.solverConfig.solverCount)),Re=!!a.taskRoleArn,Ae=Math.min(3,Math.max(0,Math.floor(a.maxRetries??1))),ve="Fargate task did not produce a result.";e.onPhase?.("requesting sandbox");let Ie=[];for(let it=0;it<=Ae;it+=1){if(e.cancelSignal.aborted)throw new Error("Cancelled by user.");e.onPhase?.("requesting sandbox");let pe=await(0,ty.getSignedUrl)(l.s3,new hr.GetObjectCommand({Bucket:G.bucket,Key:M.worker}),{expiresIn:LC}),Ct=Re?void 0:await(0,ty.getSignedUrl)(l.s3,new hr.GetObjectCommand({Bucket:G.bucket,Key:M.source}),{expiresIn:LC}),Me=Re?void 0:await(0,ty.getSignedUrl)(l.s3,new hr.GetObjectCommand({Bucket:G.bucket,Key:M.auth}),{expiresIn:LC}),O=Re?void 0:await(0,ty.getSignedUrl)(l.s3,new hr.PutObjectCommand({Bucket:G.bucket,Key:M.result,ContentType:"application/json"}),{expiresIn:LC}),F=Re?void 0:await(0,ty.getSignedUrl)(l.s3,new hr.GetObjectCommand({Bucket:G.bucket,Key:M.result}),{expiresIn:LC});jee(x,`${JSON.stringify({workerUrl:pe,sourceUrl:Ct,authUrl:Me,resultPutUrl:O,resultGetUrl:F,...Re?{bucket:G.bucket,region:c,sourceKey:M.source,authKey:M.auth,resultKey:M.result}:{},planB64:Buffer.from(JSON.stringify(s),"utf-8").toString("base64url"),provider:e.solverConfig.provider,modelId:e.solverConfig.modelId,thinkingLevel:e.solverConfig.thinkingLevel,timeoutMinutes:e.solverConfig.timeoutMinutes,solverCount:re,resourceProfile:u.profile})}
96
96
  `,"utf-8"),await Hee(l.s3,G.bucket,M.bootstrap,x,"application/json");let Ge=await(0,ty.getSignedUrl)(l.s3,new hr.GetObjectCommand({Bucket:G.bucket,Key:M.bootstrap}),{expiresIn:LC}),Xo={name:rEn,environment:[{name:"SHIPD_BOOTSTRAP_URL",value:Ge}]},OC=await l.ecs.send(new yo.RunTaskCommand({cluster:G.cluster,capacityProviderStrategy:[{capacityProvider:"FARGATE_SPOT",weight:1}],taskDefinition:K,count:1,networkConfiguration:{awsvpcConfiguration:{subnets:G.subnets,securityGroups:[G.securityGroup],assignPublicIp:"ENABLED"}},overrides:{containerOverrides:[Xo]}})),rl=OC.failures?.[0]?.reason;if(S=OC.tasks?.[0]?.taskArn,v=G.cluster,!S){ve=rl??"Fargate could not place the Spot task.",e.onPhase?.("requesting sandbox");continue}e.onPhase?.("sandbox created");let dd=await Txo(l.ecs,G.cluster,S,()=>Axo(l.s3,G.bucket,M.result),e.solverConfig.timeoutMinutes,e.cancelSignal,(ay,ol)=>{e.onSolverProgress?.(ay),ol&&e.onResourceUsage?.(ol)},()=>e.onPhase?.("running agents"),()=>{w=!0});if(S=void 0,Ie=Dxo(Ie,dd?.results??[]),e.onSolverProgress?.(Ie),dd?.resourceUsage&&e.onResourceUsage?.(dd.resourceUsage),dd?.complete&&!dd.error&&Ie.length>=re){e.onPhase?.("finalizing");let ay=await nEn(e,Ie,e.solverConfig.saveArtifacts);for(let ol of ay)e.onSolverCompleted?.(ol);return ay}if(ve=dd?.error??ve,e.cancelSignal.aborted)throw new Error("Cancelled by user.")}let we=await nEn(e,bxo(re,Ie,ve),e.solverConfig.saveArtifacts);for(let it of we)e.onSolverCompleted?.(it);return we}finally{e.cancelSignal.removeEventListener("abort",L),S&&(w||await l.ecs.send(new yo.StopTaskCommand({cluster:v,task:S,reason:"shipd checks cleanup"})).catch(()=>{}),await Cxo(l.ecs,v,S)),await Exo(l.s3,A,M).catch(()=>{}),l.ecs.destroy(),l.ec2.destroy(),l.s3.destroy(),l.sts.destroy();try{Jbn(p,{force:!0}),x&&Jbn(x,{force:!0})}catch{}}}function Rxo(e,t){let s=e.fargate??{},a=s.projectProfiles?.[t];return a?{...s,resourceProfile:a}:s}function Sxo(){let e=Math.max(dc.lastIndexOf("/"),dc.lastIndexOf("\\"));return e>=0?dc.slice(0,e):"."}function Ixo(){let t=[tEn(new URL("./fargate-worker.mjs",import.meta.url)),tEn(new URL("../dist/fargate-worker.mjs",import.meta.url)),km(process.cwd(),"dist","fargate-worker.mjs")].find(s=>IAe(s));if(!t)throw new Error("Missing dist/fargate-worker.mjs. Build pi-shipd-checks first.");return t}async function yxo(e,t,s,a){let l=`tar ${process.platform==="win32"?"--force-local ":""}--exclude=./solution.patch -czf ${VC(NC(s))} -C ${VC(NC(t))} .`,u=process.platform==="win32"?"C:\\Program Files\\Git\\bin\\bash.exe":"bash",p=await e.exec(u,["-c",l],{cwd:t,timeout:12e4,signal:a});if(a.aborted)throw new Error("Cancelled by user.");if(p.code!==0)throw new Error(p.stderr?.trim()||"Could not create the Fargate source archive.")}async function Hee(e,t,s,a,c){await e.send(new hr.PutObjectCommand({Bucket:t,Key:s,Body:uxo(a),ContentType:c,ServerSideEncryption:"AES256"}))}async function _xo(e,t,s){let a=await e.sts.send(new zee.GetCallerIdentityCommand({}));if(!a.Account)throw new Error("Could not determine AWS account identity.");let c=t.bucket??`shipd-checks-${a.Account}-${s}`;await hxo(e.s3,c,s);let l=t.cluster;if(l||(l=(await e.ecs.send(new yo.ListClustersCommand({maxResults:1}))).clusterArns?.[0]),l||(l=(await e.ecs.send(new yo.CreateClusterCommand({clusterName:"pi-shipd-checks"}))).cluster?.clusterArn),!l)throw new Error("Could not find or create an ECS cluster.");let p=(await e.ec2.send(new Hg.DescribeVpcsCommand({Filters:[{Name:"isDefault",Values:["true"]}]}))).Vpcs?.[0]?.VpcId;if(!p)throw new Error("No default VPC found. Configure Fargate subnetIds/securityGroupId explicitly.");let d=t.subnetIds?.length?t.subnetIds:(await e.ec2.send(new Hg.DescribeSubnetsCommand({Filters:[{Name:"vpc-id",Values:[p]},{Name:"map-public-ip-on-launch",Values:["true"]}]}))).Subnets?.map(S=>S.SubnetId).filter(S=>!!S)??[];if(d.length===0)throw new Error("No public subnet found for the Fargate task.");let m=t.securityGroupId;if(m||(m=(await e.ec2.send(new Hg.DescribeSecurityGroupsCommand({Filters:[{Name:"vpc-id",Values:[p]},{Name:"group-name",Values:["default"]}]}))).SecurityGroups?.[0]?.GroupId),!m)throw new Error("No default security group found.");return{region:s,bucket:c,cluster:l,subnets:d,securityGroup:m}}async function hxo(e,t,s){try{await e.send(new hr.HeadBucketCommand({Bucket:t}))}catch{await e.send(new hr.CreateBucketCommand({Bucket:t,...s==="us-east-1"?{}:{CreateBucketConfiguration:{LocationConstraint:s}}}))}await e.send(new hr.PutPublicAccessBlockCommand({Bucket:t,PublicAccessBlockConfiguration:{BlockPublicAcls:!0,BlockPublicPolicy:!0,IgnorePublicAcls:!0,RestrictPublicBuckets:!0}}))}async function vxo(e,t,s,a,c,l){let u=await e.send(new yo.RegisterTaskDefinitionCommand({family:"pi-shipd-checks-fargate",...l.taskRoleArn?{taskRoleArn:l.taskRoleArn}:{},...l.executionRoleArn?{executionRoleArn:l.executionRoleArn}:{},networkMode:"awsvpc",requiresCompatibilities:["FARGATE"],cpu:String(s*1024),memory:String(a),containerDefinitions:[{name:rEn,image:t.baseImage,essential:!0,command:["bash","-lc",`python -c "import os,urllib.request; urllib.request.urlretrieve(os.environ['SHIPD_BOOTSTRAP_URL'],'/tmp/shipd-bootstrap.json')" && python -c "import json,urllib.request; b=json.load(open('/tmp/shipd-bootstrap.json')); urllib.request.urlretrieve(b['workerUrl'],'/tmp/shipd-fargate-worker.mjs')" && exec node /tmp/shipd-fargate-worker.mjs`],...l.executionRoleArn?{logConfiguration:{logDriver:"awslogs",options:{"awslogs-group":l.logGroup??"/aws/ecs/pi-shipd-checks","awslogs-region":c,"awslogs-stream-prefix":"solver"}}}:{}}]}));if(!u.taskDefinition?.taskDefinitionArn)throw new Error("ECS did not return a task definition ARN.");return u.taskDefinition.taskDefinitionArn}async function Cxo(e,t,s){if(!t)return;let a=Date.now()+12e4;for(;Date.now()<a;){try{if((await e.send(new yo.DescribeTasksCommand({cluster:t,tasks:[s]}))).tasks?.[0]?.lastStatus==="STOPPED")return}catch{return}await oEn(2e3)}}async function Txo(e,t,s,a,c,l,u,p,d){let m=Date.now()+(Math.max(10,c)+20)*60*1e3,S,v=!1;for(;Date.now()<m;){if(l.aborted)throw d(),await e.send(new yo.StopTaskCommand({cluster:t,task:s,reason:"shipd checks cancelled"})).catch(()=>{}),new Error("Cancelled by user.");let A=await a();if(A&&(S=A,u(A.results,A.resourceUsage),A.complete))return A;let w=(await e.send(new yo.DescribeTasksCommand({cluster:t,tasks:[s]}))).tasks?.[0];if(w?.lastStatus==="RUNNING"&&!v&&(v=!0,p()),w?.lastStatus==="STOPPED"){let L=await a();if(L)return u(L.results,L.resourceUsage),L;let M=w.stoppedReason??w.containers?.[0]?.reason??"Fargate task stopped without a result.";return S??{complete:!1,results:[],error:M}}await oEn(fxo)}return d(),await e.send(new yo.StopTaskCommand({cluster:t,task:s,reason:"shipd checks timeout"})).catch(()=>{}),S??{complete:!1,results:[],error:"Fargate task timed out."}}async function Axo(e,t,s){try{let c=await(await e.send(new hr.GetObjectCommand({Bucket:t,Key:s}))).Body?.transformToString();return c?JSON.parse(c):void 0}catch{return}}async function nEn(e,t,s){return t.map(a=>{let{trajectory:c,...l}=a;if(s){let u=km(e.repoDir,WAe,e.runId,`solver_${a.index}`);pxo(u,{recursive:!0}),jee(km(u,"trajectory.json"),`${JSON.stringify(c??[],null,2)}
97
- `,"utf-8"),jee(km(u,"solution.patch"),a.diff,"utf-8"),jee(km(u,"test_output.txt"),a.testOutputTail,"utf-8"),l.artifactsDir=u}return l})}function Dxo(e,t){let s=new Map(e.map(a=>[a.index,a]));for(let a of t)s.set(a.index,a);return[...s.values()].sort((a,c)=>a.index-c.index)}function bxo(e,t,s){let a=new Map(t.map(c=>[c.index,c]));for(let c=1;c<=e;c+=1)a.has(c)||a.set(c,{index:c,status:"error",passed:!1,diff:"",testOutputTail:s,durationMs:0,totalTests:null,failedTests:null});return[...a.values()].sort((c,l)=>c.index-l.index)}async function Exo(e,t,s){t&&await e.send(new hr.DeleteObjectsCommand({Bucket:t,Delete:{Objects:Object.values(s).map(a=>({Key:a}))}}))}var gL="checks_progress";function xxo(e){let t=Math.max(0,Math.floor(e/1e3)),s=Math.floor(t/3600),a=Math.floor(t%3600/60),c=t%60;return s>0?`${s}:${String(a).padStart(2,"0")}:${String(c).padStart(2,"0")}`:`${a}:${String(c).padStart(2,"0")}`}function iEn(e,t,s,a){let c=a?.showBar!==!1,l=s>0?Math.min(1,t/s):0,u=Math.round(24*l),p="\u2588".repeat(u)+"\u2591".repeat(Math.max(0,24-u)),d=c?` [${p}] ${t}/${s}`:"",m=a?.startedAt===void 0?"":` elapsed: ${xxo(Date.now()-a.startedAt)}`;return[`checks: ${e}${d}${m}`]}import{existsSync as Pxo,readFileSync as $xo}from"node:fs";var yAe=["agent_prompt.md","solution.patch","test.patch"];function _Ae(e=new Date){let t=(l,u=2)=>String(l).padStart(u,"0"),s=-e.getTimezoneOffset(),a=s>=0?"+":"-",c=Math.abs(s);return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}T${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}.${t(e.getMilliseconds(),3)}${a}${t(Math.floor(c/60))}:${t(c%60)}`}function cEn(e){try{if(!Pxo(e))return{};let t=JSON.parse($xo(e,"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function lEn(e){let t={...e.existingReport,timestamp:_Ae(),model:`${e.config.provider}/${e.config.modelId}`,thinkingLevel:e.config.thinkingLevel};return delete t.overall,delete t.reports,e.runGapFinder&&(t.testGaps=e.testGaps,e.gapAnalysisIncomplete?t.testGapAnalysisNote=`Gap analysis did not fully complete (sentence finder: ${e.gapFinderStatus}, review: ${e.gapFilterStatus}); testGaps may be incomplete.`:delete t.testGapAnalysisNote),e.runSolverGapFinder&&(t.solverRunSummary=e.solverResults.map(s=>({index:s.index,status:s.status,passed:s.passed,durationMs:s.durationMs,totalTests:s.totalTests,failedTests:s.failedTests,artifactsDir:s.artifactsDir})),t.solverGaps=e.solverGaps,e.fargateResourceUsage?t.fargateResourceUsage=e.fargateResourceUsage:delete t.fargateResourceUsage,e.solverGapAnalysisIncomplete?t.solverGapAnalysisNote=`Solver-gap analysis did not fully complete (comparison reviewer: ${e.solverComparisonStatus}); solverGaps may be incomplete.`:delete t.solverGapAnalysisNote),t}function uEn(e){let t=Math.round(e/1e3);return t>=60?`${Math.floor(t/60)}m ${t%60}s`:`${t}s`}function pEn(e){let t=Array.isArray(e.merged.testGaps)?e.merged.testGaps.length:0,s=e.runSolverGapFinder&&Array.isArray(e.merged.solverRunSummary)?e.merged.solverRunSummary.map(l=>({...l,durationMs:l.durationMs??0})):[],a=Array.isArray(e.merged.solverGaps)?e.merged.solverGaps.length:0,c=[];return e.runGapFinder&&c.push(t>0?`${t} test gap(s) found`:"no test gaps found"),e.runSolverGapFinder&&c.push(`${s.filter(l=>l.passed).length}/${s.length} solvers passed, ${a} gap(s) found`),{content:`Gap finders: ${c.join(" | ")}`,details:{gapsCount:t,showGaps:e.runGapFinder,showSolverGaps:e.runSolverGapFinder,solverDetails:s,solverGapsCount:a}}}var dEn=`## The problem description (aka the task)\r
97
+ `,"utf-8"),jee(km(u,"solution.patch"),a.diff,"utf-8"),jee(km(u,"test_output.txt"),a.testOutputTail,"utf-8"),l.artifactsDir=u}return l})}function Dxo(e,t){let s=new Map(e.map(a=>[a.index,a]));for(let a of t)s.set(a.index,a);return[...s.values()].sort((a,c)=>a.index-c.index)}function bxo(e,t,s){let a=new Map(t.map(c=>[c.index,c]));for(let c=1;c<=e;c+=1)a.has(c)||a.set(c,{index:c,status:"error",passed:!1,diff:"",testOutputTail:s,error:s,durationMs:0,totalTests:null,failedTests:null});return[...a.values()].sort((c,l)=>c.index-l.index)}async function Exo(e,t,s){t&&await e.send(new hr.DeleteObjectsCommand({Bucket:t,Delete:{Objects:Object.values(s).map(a=>({Key:a}))}}))}var gL="checks_progress";function xxo(e){let t=Math.max(0,Math.floor(e/1e3)),s=Math.floor(t/3600),a=Math.floor(t%3600/60),c=t%60;return s>0?`${s}:${String(a).padStart(2,"0")}:${String(c).padStart(2,"0")}`:`${a}:${String(c).padStart(2,"0")}`}function iEn(e,t,s,a){let c=a?.showBar!==!1,l=s>0?Math.min(1,t/s):0,u=Math.round(24*l),p="\u2588".repeat(u)+"\u2591".repeat(Math.max(0,24-u)),d=c?` [${p}] ${t}/${s}`:"",m=a?.startedAt===void 0?"":` elapsed: ${xxo(Date.now()-a.startedAt)}`;return[`checks: ${e}${d}${m}`]}import{existsSync as Pxo,readFileSync as $xo}from"node:fs";var yAe=["agent_prompt.md","solution.patch","test.patch"];function _Ae(e=new Date){let t=(l,u=2)=>String(l).padStart(u,"0"),s=-e.getTimezoneOffset(),a=s>=0?"+":"-",c=Math.abs(s);return`${e.getFullYear()}-${t(e.getMonth()+1)}-${t(e.getDate())}T${t(e.getHours())}:${t(e.getMinutes())}:${t(e.getSeconds())}.${t(e.getMilliseconds(),3)}${a}${t(Math.floor(c/60))}:${t(c%60)}`}function cEn(e){try{if(!Pxo(e))return{};let t=JSON.parse($xo(e,"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function lEn(e){let t={...e.existingReport,timestamp:_Ae(),model:`${e.config.provider}/${e.config.modelId}`,thinkingLevel:e.config.thinkingLevel};return delete t.overall,delete t.reports,e.runGapFinder&&(t.testGaps=e.testGaps,e.gapAnalysisIncomplete?t.testGapAnalysisNote=`Gap analysis did not fully complete (sentence finder: ${e.gapFinderStatus}, review: ${e.gapFilterStatus}); testGaps may be incomplete.`:delete t.testGapAnalysisNote),e.runSolverGapFinder&&(t.solverRunSummary=e.solverResults.map(s=>({index:s.index,status:s.status,passed:s.passed,durationMs:s.durationMs,totalTests:s.totalTests,failedTests:s.failedTests,error:s.error??(s.status==="error"?s.testOutputTail:void 0),artifactsDir:s.artifactsDir})),t.solverGaps=e.solverGaps,e.fargateResourceUsage?t.fargateResourceUsage=e.fargateResourceUsage:delete t.fargateResourceUsage,e.solverGapAnalysisIncomplete?t.solverGapAnalysisNote=`Solver-gap analysis did not fully complete (comparison reviewer: ${e.solverComparisonStatus}); solverGaps may be incomplete.`:delete t.solverGapAnalysisNote),t}function uEn(e){let t=Math.round(e/1e3);return t>=60?`${Math.floor(t/60)}m ${t%60}s`:`${t}s`}function pEn(e){let t=Array.isArray(e.merged.testGaps)?e.merged.testGaps.length:0,s=e.runSolverGapFinder&&Array.isArray(e.merged.solverRunSummary)?e.merged.solverRunSummary.map(l=>({...l,durationMs:l.durationMs??0})):[],a=Array.isArray(e.merged.solverGaps)?e.merged.solverGaps.length:0,c=[];return e.runGapFinder&&c.push(t>0?`${t} test gap(s) found`:"no test gaps found"),e.runSolverGapFinder&&c.push(`${s.filter(l=>l.passed).length}/${s.length} solvers passed, ${a} gap(s) found`),{content:`Gap finders: ${c.join(" | ")}`,details:{gapsCount:t,showGaps:e.runGapFinder,showSolverGaps:e.runSolverGapFinder,solverDetails:s,solverGapsCount:a}}}var dEn=`## The problem description (aka the task)\r
98
98
  P1: Aligns with the repo's philosophy\r
99
99
  P2: Self-contained \u2014 solvable from the repo and description alone\r
100
100
  P3: Clear, concise, and unambiguous \u2014 describes what to build or fix and don't leave points for guessing\r
@@ -505,11 +505,11 @@ A solution is ready for a highest-quality review only when all of the following
505
505
  `).trim(),G=M?Vxo(M.split(`
506
506
  `)):["(no output)"];if(!s.expanded){let re=Math.max(0,G.length-SEn);G=G.slice(0,SEn),re>0&&G.push(`... (${re} more lines, ${Gxo("app.tools.expand","to expand")})`)}let K=c.lastComponent instanceof Yee?c.lastComponent:new Yee;return K.setContent(w,G,a),K},async execute(t,s,a,c,l){let u=s.mode??"gaps";if(!bL(l.cwd))throw new Error("analyze_task_tests is disabled for this project. Enable it with /analyze:on.");let p=Mxo(l.cwd,"agent_prompt.md");if(!Lxo(p))throw new Error("Missing required file in project root: agent_prompt.md");let d=u==="gaps"?lte():FAe(),m=d??Ea(),S=m,v=S?l.modelRegistry.find(S.provider,S.modelId):l.model;if(!v||S&&!l.modelRegistry.hasConfiguredAuth(v))throw new Error("No model configured/authenticated for analyze_task_tests. Set one via /checks --config (Analyze Tool section).");let A=m?.thinkingLevel??"off",x=d?.timeoutMinutes??cy,w=new AbortController;a&&(a.aborted?w.abort():a.addEventListener("abort",()=>w.abort(),{once:!0}));let L=await jAe(e,l.cwd,w.signal);if(w.signal.aborted)throw new Error("Cancelled by user.");let M=u==="gaps"?"":await zAe(e,l.cwd,L,w.signal);if(w.signal.aborted)throw new Error("Cancelled by user.");let G={tempDir:l.cwd,model:v,thinkingLevel:A,testRubric:Kee(),fairnessRules:Wee(),solutionRules:mEn(),codeFiles:L,changedCodeDiff:M,timeoutMinutes:x,cancelSignal:w.signal};if(u==="test-audit"){c?.({content:[{type:"text",text:"Phase 1/2 \u2014 auditing implemented tests for fairness..."}],details:{}});let Ae=await qke(G);if(w.signal.aborted)throw new Error("Cancelled by user.");if(Ae.status!=="ok")throw new Error(`Test audit did not complete (status: ${Ae.status}).`);let ve=[];if(Ae.findings.length>0){c?.({content:[{type:"text",text:`Phase 2/2 \u2014 validating ${Ae.findings.length} audit finding(s)...`}],details:{}});let Ie=await Fke({...G,findings:Ae.findings});if(w.signal.aborted)throw new Error("Cancelled by user.");if(Ie.status!=="ok")throw new Error(`Test-audit validation did not complete (status: ${Ie.status}).`);ve=Ie.findings}return{content:[{type:"text",text:Uxo(ve)}],details:{testAuditFindings:ve}}}if(u==="solution-audit"){c?.({content:[{type:"text",text:"Phase 1/2 \u2014 auditing solution quality..."}],details:{}});let Ae=await Bke(G);if(w.signal.aborted)throw new Error("Cancelled by user.");if(Ae.status!=="ok")throw new Error(`Solution audit did not complete (status: ${Ae.status}).`);let ve=[];if(Ae.findings.length>0){c?.({content:[{type:"text",text:`Phase 2/2 \u2014 validating ${Ae.findings.length} solution finding(s)...`}],details:{}});let Ie=await Uke({...G,findings:Ae.findings});if(w.signal.aborted)throw new Error("Cancelled by user.");if(Ie.status!=="ok")throw new Error(`Solution-audit validation did not complete (status: ${Ie.status}).`);ve=Ie.findings}return{content:[{type:"text",text:Hxo(ve)}],details:{solutionAuditFindings:ve}}}c?.({content:[{type:"text",text:"Finding behavioral test gaps sentence by sentence..."}],details:{}});let K=await Oke(G);if(w.signal.aborted)throw new Error("Cancelled by user.");if(K.status!=="ok")throw new Error(`Gap finder did not complete (status: ${K.status}).`);let re=K.gaps.reduce((Ae,ve)=>Ae+ve.gaps.length,0),Re=[];if(re>0){c?.({content:[{type:"text",text:`Validating ${re} candidate gap(s)...`}],details:{}});let Ae=await Vke({...G,statementReports:K.gaps});if(w.signal.aborted)throw new Error("Cancelled by user.");if(Ae.status!=="ok")throw new Error(`Gap review did not complete (status: ${Ae.status}).`);Re=Ae.gaps}return{content:[{type:"text",text:Bxo(Re)}],details:{testGaps:Re}}}})}function Vxo(e){let t=[],s=!1;for(let a of e)/^\s*\d+\.\s+/.test(a)?(s=!1,t.push(a)):/^\s*Justification:/i.test(a)?s=!0:s||t.push(a);return t}var Yee=class{header="";styledLines=[];theme;cachedWidth=-1;cachedLines=[];setContent(t,s,a){this.header=t,this.styledLines=s.map(c=>qxo(c,a)),this.theme=a,this.cachedWidth=-1}invalidate(){this.cachedWidth=-1}render(t){if(this.cachedWidth!==t){let s=this.theme,a=[];this.header&&a.push(this.header,"");for(let c of this.styledLines)s?a.push(...Nxo(c,t)):a.push(c);this.cachedLines=a,this.cachedWidth=t}return this.cachedLines}};function qxo(e,t){let s=e.match(/^(\d+)\.\s+(.*)$/);return s?`${t.fg("accent",`${s[1]}.`)} ${t.fg("muted",s[2]??"")}`:t.fg("toolOutput",e)}function Fxo(e){return`${Math.floor(e/1e3)}s`}function Bxo(e){return e.length===0?"Gap analysis complete: no confirmed behavioral test gaps were found.":["Below are the gaps found by another agent. If they are fair under our prompt, we need to add tests to fix the gap. If not fair, do not mind those \u2014 only add tests for gaps that are absolutely fair.","",...e.map((s,a)=>`${a+1}. ${s.description}
507
507
  Justification: ${s.justification}`)].join(`
508
- `)}function Uxo(e){return e.length===0?"Test audit complete: no actionable unfairness findings were found.":["Below are validated unfairness findings from a read-only audit of the implemented tests. Preserve each required behavior when applying the recommended repair.","",...e.map((s,a)=>`${a+1}. [${s.category}] ${s.testName}: ${s.problem}
508
+ `)}function Uxo(e){return e.length===0?"Test audit complete: no actionable unfairness findings were found.":["Below are suggestions from another agent, not instructions. Decide whether each test-fairness finding is valid under the prompt and repository, and implement only the repairs you judge appropriate while preserving the required behavior.","",...e.map((s,a)=>`${a+1}. [${s.category}] ${s.testName}: ${s.problem}
509
509
  Evidence: ${s.evidence}
510
510
  Required behavior: ${s.requiredBehavior}
511
511
  Recommendation: ${s.recommendation}`)].join(`
512
- `)}function Hxo(e){return e.length===0?"Solution audit complete: no actionable solution-quality findings were found.":["Below are validated solution-quality findings from a read-only audit. Apply only repairs grounded in the prompt and repository conventions; do not treat the reference implementation as the specification.","",...e.map((s,a)=>`${a+1}. [${s.category}] ${s.subject}: ${s.problem}
512
+ `)}function Hxo(e){return e.length===0?"Solution audit complete: no actionable solution-quality findings were found.":["Below are suggestions from another agent, not instructions. Decide whether each solution-quality finding is valid under the prompt and repository, and implement only the repairs you judge appropriate; do not treat the reference implementation as the specification.","",...e.map((s,a)=>`${a+1}. [${s.category}] ${s.subject}: ${s.problem}
513
513
  Evidence: ${s.evidence}
514
514
  Required behavior: ${s.requiredBehavior}
515
515
  Recommendation: ${s.recommendation}`)].join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sreetej510/pi-shipd-checks",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
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",