@sreetej510/pi-shipd-checks 0.5.5 → 0.6.0
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/README.md +8 -8
- package/dist/fargate-worker.mjs +1 -1
- package/dist/index.js +59 -464
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,14 +25,14 @@ For `/checks`:
|
|
|
25
25
|
The agent-callable `analyze_task_tests` tool provides the separate test-analysis workflow:
|
|
26
26
|
|
|
27
27
|
- `mode: "gaps"` (default) finds and validates sentence-by-sentence behavioral coverage gaps.
|
|
28
|
-
- `mode: "test-audit"` runs
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
repeated requests sequentially after applying each result.
|
|
28
|
+
- `mode: "test-audit"` runs one exhaustive Auditor over implemented tests, using the
|
|
29
|
+
`# Fairness vs. unfairness` rules to classify unfair assertions, prompt ambiguity, and broken fixtures.
|
|
30
|
+
- `mode: "solution-audit"` runs one exhaustive Auditor over the implementation, using the
|
|
31
|
+
`# Gaps in solution` rules and the same in-memory changed-code diff.
|
|
32
|
+
|
|
33
|
+
All modes are read-only. Gap analysis uses two agents: a gap finder followed by a fairness reviewer.
|
|
34
|
+
Each audit uses one agent to keep the tool affordable. Invoke the tool only when the user asks, never in
|
|
35
|
+
parallel, and run repeated requests sequentially after applying each result.
|
|
36
36
|
|
|
37
37
|
## Commands
|
|
38
38
|
|
package/dist/fargate-worker.mjs
CHANGED
|
@@ -2353,7 +2353,7 @@ Options:
|
|
|
2353
2353
|
`))});try{switch(n.command){case"install":return await l.installAndPersist(r,{local:n.local}),console.log(Jt.green(`Installed ${r}`)),!0;case"remove":return await l.removeAndPersist(r,{local:n.local})?(console.log(Jt.green(`Removed ${r}`)),!0):(console.error(Jt.red(`No matching package found for ${r}`)),process.exitCode=1,!0);case"list":{let p=l.listConfiguredPackages(),d=p.filter(f=>f.scope==="user"),m=p.filter(f=>f.scope==="project");if(p.length===0)return console.log(Jt.dim("No packages installed.")),!0;let h=f=>{let A=f.filtered?`${f.source} (filtered)`:f.source;console.log(` ${A}`),f.installedPath&&console.log(Jt.dim(` ${f.installedPath}`))};if(d.length>0){console.log(Jt.bold("User packages:"));for(let f of d)h(f)}if(m.length>0){d.length>0&&console.log(),console.log(Jt.bold("Project packages:"));for(let f of m)h(f)}return!0}case"update":{let p=n.updateTarget??{type:"self"};if(n.showExtensionsSkippedNote&&console.log(Jt.dim(`Extensions are skipped. Run ${bn} update --extensions to update extensions.`)),kRi(p)){let d=p.type==="extensions"?p.source:void 0;await l.update(d),console.log(d?Jt.green(`Updated ${d}`):Jt.green("Updated packages"))}if(RRi(p)){let d=await LRi(n.force);if(!d.shouldRun)return!0;let m=Lle();if(process.platform==="win32"&&m!=="npm"&&m!=="pnpm")return console.error(Jt.red(`${bn} self-update on Windows is only supported for npm and pnpm installs.`)),console.error(Jt.dim(`Detected install method: ${m}. Update ${bn} manually.`)),process.exitCode=1,!0;let h={packageName:d.packageName,installSpec:d.installSpec},f=z4t(rw,u,h);if(!f)return NRi(u,h),process.exitCode=1,!0;d.note&&MRi(d.note);try{m==="npm"&&FRi(),await BRi(f)}catch(A){let y=A instanceof Error?A.message:"Unknown package command error";return console.error(Jt.red(`Error: ${y}`)),m==="pnpm"&&DRi(),ORi(f),process.exitCode=1,!0}console.log(Jt.green(`Updated ${bn} from ${md} to ${d.version}`))}return!0}}}catch(p){let d=p instanceof Error?p.message:"Unknown package command error";return console.error(Jt.red(`Error: ${d}`)),process.exitCode=1,!0}}var QRi=`Hint: Start without extensions using "${bn} -ne".`;async function GRi(){if(!process.stdin.isTTY)return new Promise(t=>{let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",n=>{e+=n}),process.stdin.on("end",()=>{t(e.trim()||void 0)}),process.stdin.resume()})}function Fkn(t,e){return t.drainErrors().map(({scope:n,error:r})=>({type:"warning",message:`(${e}, ${n} settings) ${r.message}`}))}function Ukn(t){for(let e of t){let n=e.type==="error"?Jt.red:e.type==="warning"?Jt.yellow:Jt.dim,r=e.type==="error"?"Error: ":e.type==="warning"?"Warning: ":"";console.error(n(`${r}${e.message}`))}}function $kn(t){return t?t==="1"||t.toLowerCase()==="true"||t.toLowerCase()==="yes":!1}function qRi(t,e,n){return t.mode==="rpc"?"rpc":t.mode==="json"?"json":t.print||!e||!n?"print":"interactive"}function WRi(t){return t==="json"?"json":"text"}function HRi(t){return!t.print&&t.mode===void 0&&(t.help===!0||t.listModels!==void 0)}async function jRi(t){if(dvn(t))return mvn(),!0;let e;try{e=fvn(t)}catch(r){let i=r instanceof ic?r.message:"Failed to parse auth command";return console.error(Jt.red(`Error: ${i}`)),process.exitCode=1,!0}if(!e)return!1;let n=GH(e.args);if(n.unknownFlags.size>0){let r=n.unknownFlags.keys().next().value;return console.error(Jt.red(`Unknown option --${r} for "${M8e(e.kind)}".`)),console.error(Jt.dim(`Use "${bn} --help" or "${pvn(e.kind)}".`)),process.exitCode=1,!0}try{if(n.diagnostics.length>0)throw new ic(n.diagnostics.map(a=>a.message).join(`
|
|
2354
2354
|
`));if(e.kind!=="check"){let a=AbortSignal.timeout(15e3),c=await zf.create({allowModelNetwork:!1,signal:a}),u=await yvn(n,c,e.kind,e.minExpiryMs,a);return process.stdout.write(`${u}
|
|
2355
2355
|
`),!0}let r=d3(n,e.kind),i,s;try{let a=e.noRefresh?new khe:J$.create(),c=await Avn(a);i=await hvn(n,c,{refresh:!e.noRefresh}),e.credentials&&i.status==="ready"&&(s=await gvn(i.provider,c,a,{refresh:!e.noRefresh}),s||(i={status:"not_ready",provider:i.provider,reason:"credential_not_available"}))}catch{i={status:"invalid",provider:r.provider??r.model,reason:"invalid_state"}}let o=e.json?JSON.stringify({...i,...s?{credentials:s}:{}}):s??i.status;process.stdout.write(`${o}
|
|
2356
|
-
`),process.exitCode=i.status==="ready"?0:i.status==="not_ready"?1:2}catch(r){let i=r instanceof ic?r.message:"Failed to resolve credential";console.error(Jt.red(`Error: ${i}`)),process.exitCode=e.kind==="check"?2:1}return!0}async function VRi(t,e,n){if(t.fileArgs.length===0)return L8e({parsed:t,stdinContent:n});let{text:r,images:i}=await Evn(t.fileArgs,{autoResizeImages:e});return L8e({parsed:t,fileText:r,fileImages:i,stdinContent:n})}async function Qkn(t,e,n){let i=(await Ls.list(e,n)).find(s=>s.id===t);return i?{type:"local",path:i.path}:void 0}async function Gkn(t,e,n){if(t.includes("/")||t.includes("\\")||t.endsWith(".jsonl"))return{type:"path",path:jn(t,e)};let r=await Ls.list(e,n),i=r.find(a=>a.id===t)??r.find(a=>a.id.startsWith(t));if(i)return{type:"local",path:i.path};let s=await Ls.listAll(n),o=s.find(a=>a.id===t)??s.find(a=>a.id.startsWith(t));return o?{type:"global",path:o.path,cwd:o.cwd}:{type:"not_found",arg:t}}async function KRi(t){return new Promise(e=>{let n=$Ri({input:process.stdin,output:process.stdout});n.question(`${t} [y/N] `,r=>{n.close(),e(r.toLowerCase()==="y"||r.toLowerCase()==="yes")})})}function YRi(t){if(!t.fork)return;let e=[t.session?"--session":void 0,t.continue?"--continue":void 0,t.resume?"--resume":void 0,t.noSession?"--no-session":void 0].filter(n=>n!==void 0);e.length>0&&(console.error(Jt.red(`Error: --fork cannot be combined with ${e.join(", ")}`)),process.exit(1))}function zRi(t){if(t.sessionId===void 0)return;let e=[t.session?"--session":void 0,t.continue?"--continue":void 0,t.resume?"--resume":void 0].filter(n=>n!==void 0);e.length>0&&(console.error(Jt.red(`Error: --session-id cannot be combined with ${e.join(", ")}`)),process.exit(1));try{cfe(t.sessionId)}catch(n){let r=n instanceof Error?n.message:String(n);console.error(Jt.red(`Error: ${r}`)),process.exit(1)}}function JRi(t,e){try{return Ls.open(t,e)}catch(n){let r=n instanceof Error?n.message:String(n);console.error(Jt.red(`Error: ${r}`)),process.exit(1)}}function qkn(t,e,n,r){try{return Ls.forkFrom(t,e,n,{id:r})}catch(i){let s=i instanceof Error?i.message:String(i);console.error(Jt.red(`Error: ${s}`)),process.exit(1)}}async function XRi(t,e,n,r){if(t.noSession||t.help||t.listModels!==void 0)return Ls.inMemory(e,t.sessionId!==void 0?{id:t.sessionId}:void 0);if(t.fork){t.sessionId&&await Qkn(t.sessionId,e,n)&&(console.error(Jt.red(`Session already exists with id '${t.sessionId}'`)),process.exit(1));let i=await Gkn(t.fork,e,n);switch(i.type){case"path":case"local":case"global":return qkn(i.path,e,n,t.sessionId);case"not_found":console.error(Jt.red(`No session found matching '${i.arg}'`)),process.exit(1)}}if(t.session){let i=await Gkn(t.session,e,n);switch(i.type){case"path":case"local":return JRi(i.path,n);case"global":return console.log(Jt.yellow(`Session found in different project: ${i.cwd}`)),await KRi("Fork this session into current directory?")||(console.log(Jt.dim("Aborted.")),process.exit(0)),qkn(i.path,e,n);case"not_found":console.error(Jt.red(`No session found matching '${i.arg}'`)),process.exit(1)}}if(t.resume)try{let i=await Ovn(s=>Ls.list(e,n,s),s=>Ls.listAll(n,s),r);return i||(console.log(Jt.dim("No session selected")),process.exit(0)),Ls.open(i,n)}finally{Vb()}if(t.continue)return Ls.continueRecent(e,n);if(t.sessionId){let i=await Qkn(t.sessionId,e,n);if(i)return Ls.open(i.path,n);console.error(Jt.yellow(`Warning: No project session found with id '${t.sessionId}'; creating a new session with that id.`))}return Ls.create(e,n,{id:t.sessionId})}function ZRi(t,e,n,r,i){let s={},o=[],a=!1;if(t.model){let c=y0({cliProvider:t.provider,cliModel:t.model,cliThinking:t.thinking,modelRuntime:r});c.warning&&o.push({type:"warning",message:c.warning}),c.error&&o.push({type:"error",message:c.error}),c.model&&(s.model=c.model,!t.thinking&&c.thinkingLevel&&(s.thinkingLevel=c.thinkingLevel,a=!0))}if(!s.model&&e.length>0&&!n){let c=i.getDefaultProvider(),u=i.getDefaultModel(),l=c&&u?r.getModel(c,u):void 0,p=l?e.find(d=>yp(d.model,l)):void 0;p?(s.model=p.model,!t.thinking&&p.thinkingLevel&&(s.thinkingLevel=p.thinkingLevel)):(s.model=e[0].model,!t.thinking&&e[0].thinkingLevel&&(s.thinkingLevel=e[0].thinkingLevel))}return t.thinking&&(s.thinkingLevel=t.thinking),e.length>0&&(s.scopedModels=e.map(c=>({model:c.model,thinkingLevel:c.thinkingLevel}))),t.noTools?s.noTools="all":t.noBuiltinTools&&(s.noTools="builtin"),t.tools&&(s.tools=[...t.tools]),t.excludeTools&&(s.excludeTools=[...t.excludeTools]),{options:s,cliThinkingFromModel:a,diagnostics:o}}function Ebe(t,e){return e?.map(n=>PA(n)?jn(n,t):n)}async function eki(t,e){return I9(e,Bye(t),[{label:"Continue",value:t.fallbackCwd},{label:"Cancel",value:void 0}])}async function Wkn(t,e){s8();let n=[...Vvn,...e?.extensionFactories??[]],r=t.includes("--offline")||$kn(process.env.PI_OFFLINE);if(r&&(process.env.PI_OFFLINE="1",process.env.PI_SKIP_VERSION_CHECK="1"),await jRi(t))return;process.platform==="win32"&&bbe(al());let i=process.cwd(),s=Yr(),o=Hu.create(i,s,{projectTrusted:!1});if(I8e(o.getGlobalSettings().httpProxy),l3(),await Bkn(t,{extensionFactories:n})){let Re=process.exitCode??0;if(process.platform==="win32"&&Re===0&&t[0]==="update")return;process.exit(Re);return}if(await Lkn(t,{extensionFactories:n}))return;let a=GH(t);if(a.diagnostics.length>0){for(let Re of a.diagnostics){let Ie=Re.type==="error"?Jt.red:Jt.yellow;console.error(Ie(`${Re.type==="error"?"Error":"Warning"}: ${Re.message}`))}a.diagnostics.some(Re=>Re.type==="error")&&process.exit(1)}if(Gu("parseArgs"),a.version&&(console.log(md),process.exit(0)),a.export){let Re;try{let Ie=a.messages.length>0?a.messages[0]:void 0;Re=await Iun(a.export,Ie)}catch(Ie){let ne=Ie instanceof Error?Ie.message:"Failed to export session";console.error(Jt.red(`Error: ${ne}`)),process.exit(1)}console.log(`Exported to: ${Re}`),process.exit(0)}let c=qRi(a,process.stdin.isTTY,process.stdout.isTTY);c!=="interactive"&&!HRi(a)&&hge(),a.mode==="rpc"&&a.fileArgs.length>0&&(console.error(Jt.red("Error: @file arguments are not supported in RPC mode")),process.exit(1)),YRi(a),zRi(a);let{migratedAuthProviders:l,deprecationWarnings:p}=Xvn(i);Gu("runMigrations");let d=Hu.create(i,s);Ukn(Fkn(d,"startup session lookup")),c==="interactive"&&!a.help&&a.listModels===void 0&&Tvn()&&(await Ivn(d),Gu("firstTimeSetup")),c==="interactive"&&a.useTheme!==void 0&&d.applyOverrides({theme:a.useTheme});let m=process.env[Ule],h=(a.sessionDir?uo(a.sessionDir):void 0)??(m?uFe(m):void 0)??d.getSessionDir(),f=await XRi(a,i,h,d),A=N8e(f,i);if(A)if(c==="interactive"){let Re=await eki(A,d);Re||process.exit(0),f=Ls.open(A.sessionFile,h,Re)}else console.error(Jt.red(new Jv(A).message)),process.exit(1);if(a.name!==void 0){let Re=a.name.trim();Re||(console.error(Jt.red("Error: --name requires a non-empty value")),process.exit(1)),f.appendSessionInfo(Re)}Gu("createSessionManager");let y=new uE(s),b=f.getCwd(),E=a.projectTrustOverride===void 0&&!my(b)?b:void 0,_=a.help||a.listModels!==void 0?"print":c,x=new Map,S=Ebe(i,a.extensions),T=Ebe(i,a.skills),v=Ebe(i,a.promptTemplates),R=Ebe(i,a.themes),O=async({cwd:Re,agentDir:Ie,sessionManager:ne,sessionStartEvent:ce,projectTrustContext:se})=>{let z=ce===void 0,ee=[],j=x.get(Re),X=my(Re),le=a.projectTrustOverride===void 0&&j===void 0&&X,xe=le?!1:j??a.projectTrustOverride??(!X||y.get(Re)===!0),Se=Hu.create(Re,Ie,{projectTrusted:xe}),pe=await A9({cwd:Re,agentDir:Ie,settingsManager:Se,modelRuntimeSignal:AbortSignal.timeout(15e3),extensionFlagValues:a.unknownFlags,resourceLoaderReloadOptions:le?{resolveProjectTrust:async({extensionsResult:rt})=>{let _t=await Hye({cwd:Re,trustStore:y,trustOverride:a.projectTrustOverride,defaultProjectTrust:d.getDefaultProjectTrust(),extensionsResult:rt,projectTrustContext:se??Wye({cwd:Re,mode:z?_:c,settingsManager:d,hasUI:z&&_==="interactive"}),onExtensionError:Zt=>ee.push({type:"warning",message:Zt})});return x.set(Re,_t),_t}}:void 0,resourceLoaderOptions:{additionalExtensionPaths:S,additionalSkillPaths:T,additionalPromptTemplatePaths:v,additionalThemePaths:R,noExtensions:a.noExtensions,noSkills:a.noSkills,noPromptTemplates:a.noPromptTemplates,noThemes:a.noThemes,noContextFiles:a.noContextFiles,systemPrompt:a.systemPrompt,appendSystemPrompt:a.appendSystemPrompt,extensionFactories:n}}),{settingsManager:ge,modelRuntime:Te,resourceLoader:Ee}=pe,ve=[...ee,...pe.diagnostics,...Fkn(ge,"runtime creation"),...Ee.getExtensions().errors.map(({path:rt,error:_t})=>({type:"error",message:`Failed to load extension "${rt}": ${_t}`}))],ye=a.models??ge.getEnabledModels(),Y=ye&&ye.length>0?await ehn(ye,Te,{signal:AbortSignal.timeout(15e3)}):[],{options:qe,cliThinkingFromModel:He,diagnostics:dt}=ZRi(a,Y,ne.buildSessionContext().messages.length>0,Te,ge);ve.push(...dt),a.apiKey&&(qe.model?await Te.setRuntimeApiKey(qe.model.provider,a.apiKey):ve.push({type:"error",message:"--api-key requires a model to be specified via --model, --provider/--model, or --models"}));let at=await y9({services:pe,sessionManager:ne,sessionStartEvent:ce,model:qe.model,thinkingLevel:qe.thinkingLevel,scopedModels:qe.scopedModels,tools:qe.tools,excludeTools:qe.excludeTools,noTools:qe.noTools,customTools:qe.customTools}),ze=a.thinking!==void 0||He;return at.session.model&&ze&&at.session.setThinkingLevel(at.session.thinkingLevel),{...at,services:pe,diagnostics:ve}};Gu("createRuntime");let G=await Uye(O,{cwd:f.getCwd(),agentDir:s,sessionManager:f});Gu("createAgentSessionRuntime");let{services:$,session:U,modelFallbackMessage:W}=G,{settingsManager:re,modelRuntime:ie,resourceLoader:te}=$;if(I8e(re.getGlobalSettings().httpProxy),l3(re.getHttpIdleTimeoutMs()),a.help){let Re=te.getExtensions().extensions.flatMap(Ie=>Array.from(Ie.flags.values()));o5t(Re),process.exit(0)}if(a.listModels!==void 0){let Re=typeof a.listModels=="string"?a.listModels:void 0;await xvn(ie,Re,AbortSignal.timeout(15e3)),process.exit(0)}let q;c!=="rpc"&&(q=await GRi(),q!==void 0&&c==="interactive"&&(c="print")),Gu("readPipedStdin");let{initialMessage:oe,initialImages:be}=await VRi(a,re.getImageAutoResize(),q);Gu("prepareInitialMessage"),d0(re.getTheme(),c==="interactive"),Gu("initTheme"),c==="interactive"&&p.length>0&&await Jvn(p),Gu("resolveModelScope"),Ukn(G.diagnostics),G.diagnostics.some(Re=>Re.type==="error")&&(G.diagnostics.some(Re=>Re.message.includes("Failed to load extension"))&&console.error(Jt.yellow(QRi)),process.exit(1)),Gu("createAgentSession"),c!=="interactive"&&!U.model&&(console.error(Jt.red(u$())),process.exit(1));let De=$kn(process.env.PI_STARTUP_BENCHMARK);if(De&&c!=="interactive"&&(console.error(Jt.red("Error: PI_STARTUP_BENCHMARK only supports interactive mode")),process.exit(1)),!r&&c==="rpc"){let Re=new AbortController,Ie=setTimeout(()=>Re.abort(),15e3);ie.refresh({signal:Re.signal}).catch(()=>{}).finally(()=>clearTimeout(Ie))}if(c==="rpc")o8(),await z9(G);else if(c==="interactive"){let Re=new UO(G,{migratedProviders:l,modelFallbackMessage:W,autoTrustOnReloadCwd:E,initialMessage:oe,initialImages:be,initialMessages:a.messages,verbose:a.verbose,tuiMode:a.tuiMode,initialThemeSetting:a.useTheme});if(De){await Re.init(),Gu("interactiveMode.init"),await new Promise(Ie=>setTimeout(Ie,150)),Re.stop(),Vb(),o8(),process.stdout.writableLength>0&&await new Promise(Ie=>process.stdout.once("drain",Ie)),process.stderr.writableLength>0&&await new Promise(Ie=>process.stderr.once("drain",Ie));return}o8(),await Re.run()}else{o8();let Re=await K9(G,{mode:WRi(c),messages:a.messages,initialMessage:oe,initialImages:be});Vb(),kyn(),Re!==0&&(process.exitCode=Re);return}}var tki={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},J9=class extends En{selectList;constructor(e,n,r){super();let i=[{value:"yes",label:"Yes",description:"Show images inline in terminal"},{value:"no",label:"No",description:"Show text placeholder instead"}];this.addChild(new On),this.selectList=new hd(i,5,Kb(),tki),this.selectList.setSelectedIndex(e?0:1),this.selectList.onSelect=s=>{n(s.value==="yes")},this.selectList.onCancel=()=>{r()},this.addChild(this.selectList),this.addChild(new On)}getSelectList(){return this.selectList}};var nki={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},X9=class extends En{selectList;onPreview;constructor(e,n,r,i){super(),this.onPreview=i;let s=Fde(),o=s.map(c=>({value:c,label:c,description:c===e?"(current)":void 0}));this.addChild(new On),this.selectList=new hd(o,10,Kb(),nki);let a=s.indexOf(e);a!==-1&&this.selectList.setSelectedIndex(a),this.selectList.onSelect=c=>{n(c.value)},this.selectList.onCancel=()=>{r()},this.selectList.onSelectionChange=c=>{this.onPreview(c.value)},this.addChild(this.selectList),this.addChild(new On)}getSelectList(){return this.selectList}};var rki={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},iki={off:"No reasoning",minimal:"Very brief reasoning (~1k tokens)",low:"Light reasoning (~2k tokens)",medium:"Moderate reasoning (~8k tokens)",high:"Deep reasoning (~16k tokens)",xhigh:"Extra-high reasoning (~32k tokens)",max:"Maximum reasoning"},Z9=class extends En{selectList;constructor(e,n,r,i){super();let s=n.map(a=>({value:a,label:a,description:iki[a]}));this.addChild(new On),this.selectList=new hd(s,s.length,Kb(),rki);let o=s.findIndex(a=>a.value===e);o!==-1&&this.selectList.setSelectedIndex(o),this.selectList.onSelect=a=>{r(a.value)},this.selectList.onCancel=()=>{i()},this.addChild(this.selectList),this.addChild(new On)}getSelectList(){return this.selectList}};import{dirname as HQa,join as Hkn}from"node:path";var VQa=Hkn(Yr(),"checks-config.json"),KQa=Hkn(Yr(),"settings.json");var YQa=420*1e3,zQa=120*1e3;var c3a=gr.Object({verdict:gr.Union([gr.Literal("PASS"),gr.Literal("FAIL")],{description:"FAIL only for a genuine blocking issue (clear rubric violation, agent-fault-worthy gap, unfair/undiscoverable test requirement, or a real determinism/regression risk). Optional, minor, or stylistic points are NOT grounds for FAIL \u2014 put those in `notes` instead and use PASS."}),summary:gr.String({description:"One short sentence summarizing the verdict."}),reasons:gr.Array(gr.String(),{description:"Specific BLOCKING justifications only, citing rubric item IDs and concrete evidence from the files you read. Required (non-empty) when verdict is FAIL. Use an empty array when verdict is PASS."}),notes:gr.Array(gr.String(),{description:"Non-blocking, optional/minor observations or suggested improvements \u2014 the kind of feedback a real reviewer leaves as 'Minor/optional' without failing the task. Include these regardless of verdict; use an empty array if you truly have none."})});var l3a=gr.Object({statement:gr.String({description:"One sentence from agent_prompt.md, copied verbatim."}),gaps:gr.Array(gr.Object({description:gr.String({description:"A fair, publicly observable missing behavioral test."}),risk:gr.String({description:"Why an incorrect implementation could pass the current tests despite this missing behavior."})}),{description:"All candidate positive and negative gaps for this sentence; there is no maximum or target count, so include every distinct evidence-backed gap and relevant edge case rather than stopping at 10; use an empty array only when exhaustive analysis finds none."})});var u3a=gr.Object({gaps:gr.Array(gr.Object({description:gr.String({description:"The confirmed, real, fair test gap (may be reworded for clarity). Keep POSITIVE:/NEGATIVE: prefix when applicable."}),justification:gr.String({description:"Why this is genuinely grounded in agent_prompt.md or the repo, fair to test per the fairness methodology, and a real (non-duplicate) coverage hole in test.patch \u2014 for negative gaps, cite the prompt's prohibition/constraint and why no existing test catches the forbidden outcome."})}),{description:"The filtered, final list of confirmed test gaps. Use an empty array if none of the candidates survive strict scrutiny."})});var oki=gr.Object({category:gr.Union([gr.Literal("unfair-assertion"),gr.Literal("prompt-ambiguity"),gr.Literal("broken-fixture")],{description:"The kind of actionable problem found in the current test or its setup."}),testName:gr.String({description:"The test name or short identifier that lets the caller find the affected assertion."}),problem:gr.String({description:"What is wrong with the test and why it is blocking or actionable."}),evidence:gr.String({description:"The prompt, public repository contract, test, or fixture evidence supporting the finding."}),requiredBehavior:gr.String({description:"The semantic behavior or gap that must remain covered after the test is repaired."}),recommendation:gr.String({description:"A fair repair, or a prompt clarification when the contract is genuinely ambiguous."})}),p3a=gr.Object({findings:gr.Array(oki,{description:"Only confirmed, actionable test-fairness, ambiguity, or fixture findings. Use an empty array when the current tests contain no confirmed unfairness."})});var aki=gr.Object({category:gr.Union([gr.Literal("missing-requirement"),gr.Literal("regression"),gr.Literal("architecture"),gr.Literal("unsafe-failure"),gr.Literal("inconsistent-path"),gr.Literal("dead-code"),gr.Literal("unrelated-change")],{description:"The kind of actionable quality problem found in the solution implementation."}),subject:gr.String({description:"A short behavior, symbol, or concern identifier; do not require a source line or file location."}),problem:gr.String({description:"What is wrong with the implementation and why it is actionable."}),evidence:gr.String({description:"The prompt, repository, implementation, or regression evidence supporting the finding."}),requiredBehavior:gr.String({description:"The requirement, invariant, or solution-quality property that must be preserved."}),recommendation:gr.String({description:"A concrete repair that stays within the prompt and repository conventions."})}),d3a=gr.Object({findings:gr.Array(aki,{description:"Only confirmed, actionable solution-quality findings. Use an empty array when the implementation meets the prompt and repository standards."})});var m3a=gr.Object({gaps:gr.Array(gr.Object({description:gr.String({description:"The specific behavioral gap: a way one or more solver's diff differs materially from what agent_prompt.md/solution.patch require, despite that solver passing `./test.sh new`."}),justification:gr.String({description:"Why this is a genuine requirement from agent_prompt.md or solution.patch (cite the specific requirement/line) that the solver's diff misses, contradicts, or diverges from \u2014 and why the current tests fail to catch that divergence."}),evidence:gr.String({description:"Which solver(s) (by index) exhibit this, and the specific part of their diff that grounds the gap."})}),{description:"Concrete, diff-grounded behavioral gaps \u2014 cases where a passing solver's materially different approach reveals that `test.sh new` under-specifies a real requirement. Use an empty array if the solvers converged on equivalent behavior; do not manufacture gaps just to report something."})});function jkn(){return["You are a adversarial tester. Your goal is to find the most minimal, shortcut implementation that makes all new tests pass \u2014 not a full, correct solution. This is intentional: we want to discover whether the test suite lets through an implementation that barely satisfies the assertions without properly implementing the prompt's required behavior.","`agent_prompt.md` in the repo root describes the intended task. Tests for it already exist and are currently failing.","","Goal: make ALL of the new tests pass with the least amount of real logic possible.","1. Run `bash test.sh new` to see the failures and what the tests expect. Read the failing tests carefully \u2014 they are the only spec you need to satisfy.","2. Understand exactly what each test assertion checks. Ask, 'what is the minimum thing I can do \u2014 a stub, a hardcoded return, a mockish pass-through, a trivial branch \u2014 to satisfy this test?', not 'what does agent_prompt.md intend?'. Skim `agent_prompt.md` only enough to understand what the test file names and assertions refer to, then rely on the test errors to drive what to implement.","3. Prefer the most minimal implementation possible:"," - Hardcode a return value if the test expects one."," - Add only the code paths a test actually exercises; leave anything untested unimplemented."," - Mock the minimum number of dependencies (or none) that the test error forces you to touch."," - Use the most direct, trivial, shortcut approach \u2014 do not build abstractions, do not handle unobserved edge cases, do not add defensive code.","4. Before declaring success, also run `bash test.sh base` to confirm your changes cause no regressions. The shortcut must not break existing tests \u2014 that would be a false positive from a different angle.","5. Re-run `bash test.sh new` and iterate until both the new tests and the base tests pass, or you're confident you cannot pass more without adding real logic.","","Rules:","- Do NOT modify the test files or `test.sh`. Only change application/library code.","- You have shell access \u2014 install any dependencies you need.","- The prompt is not your spec: the tests are. Implement exactly what the tests demand, nothing more. If you can satisfy a test with a hardcoded return, do it."].join(`
|
|
2356
|
+
`),process.exitCode=i.status==="ready"?0:i.status==="not_ready"?1:2}catch(r){let i=r instanceof ic?r.message:"Failed to resolve credential";console.error(Jt.red(`Error: ${i}`)),process.exitCode=e.kind==="check"?2:1}return!0}async function VRi(t,e,n){if(t.fileArgs.length===0)return L8e({parsed:t,stdinContent:n});let{text:r,images:i}=await Evn(t.fileArgs,{autoResizeImages:e});return L8e({parsed:t,fileText:r,fileImages:i,stdinContent:n})}async function Qkn(t,e,n){let i=(await Ls.list(e,n)).find(s=>s.id===t);return i?{type:"local",path:i.path}:void 0}async function Gkn(t,e,n){if(t.includes("/")||t.includes("\\")||t.endsWith(".jsonl"))return{type:"path",path:jn(t,e)};let r=await Ls.list(e,n),i=r.find(a=>a.id===t)??r.find(a=>a.id.startsWith(t));if(i)return{type:"local",path:i.path};let s=await Ls.listAll(n),o=s.find(a=>a.id===t)??s.find(a=>a.id.startsWith(t));return o?{type:"global",path:o.path,cwd:o.cwd}:{type:"not_found",arg:t}}async function KRi(t){return new Promise(e=>{let n=$Ri({input:process.stdin,output:process.stdout});n.question(`${t} [y/N] `,r=>{n.close(),e(r.toLowerCase()==="y"||r.toLowerCase()==="yes")})})}function YRi(t){if(!t.fork)return;let e=[t.session?"--session":void 0,t.continue?"--continue":void 0,t.resume?"--resume":void 0,t.noSession?"--no-session":void 0].filter(n=>n!==void 0);e.length>0&&(console.error(Jt.red(`Error: --fork cannot be combined with ${e.join(", ")}`)),process.exit(1))}function zRi(t){if(t.sessionId===void 0)return;let e=[t.session?"--session":void 0,t.continue?"--continue":void 0,t.resume?"--resume":void 0].filter(n=>n!==void 0);e.length>0&&(console.error(Jt.red(`Error: --session-id cannot be combined with ${e.join(", ")}`)),process.exit(1));try{cfe(t.sessionId)}catch(n){let r=n instanceof Error?n.message:String(n);console.error(Jt.red(`Error: ${r}`)),process.exit(1)}}function JRi(t,e){try{return Ls.open(t,e)}catch(n){let r=n instanceof Error?n.message:String(n);console.error(Jt.red(`Error: ${r}`)),process.exit(1)}}function qkn(t,e,n,r){try{return Ls.forkFrom(t,e,n,{id:r})}catch(i){let s=i instanceof Error?i.message:String(i);console.error(Jt.red(`Error: ${s}`)),process.exit(1)}}async function XRi(t,e,n,r){if(t.noSession||t.help||t.listModels!==void 0)return Ls.inMemory(e,t.sessionId!==void 0?{id:t.sessionId}:void 0);if(t.fork){t.sessionId&&await Qkn(t.sessionId,e,n)&&(console.error(Jt.red(`Session already exists with id '${t.sessionId}'`)),process.exit(1));let i=await Gkn(t.fork,e,n);switch(i.type){case"path":case"local":case"global":return qkn(i.path,e,n,t.sessionId);case"not_found":console.error(Jt.red(`No session found matching '${i.arg}'`)),process.exit(1)}}if(t.session){let i=await Gkn(t.session,e,n);switch(i.type){case"path":case"local":return JRi(i.path,n);case"global":return console.log(Jt.yellow(`Session found in different project: ${i.cwd}`)),await KRi("Fork this session into current directory?")||(console.log(Jt.dim("Aborted.")),process.exit(0)),qkn(i.path,e,n);case"not_found":console.error(Jt.red(`No session found matching '${i.arg}'`)),process.exit(1)}}if(t.resume)try{let i=await Ovn(s=>Ls.list(e,n,s),s=>Ls.listAll(n,s),r);return i||(console.log(Jt.dim("No session selected")),process.exit(0)),Ls.open(i,n)}finally{Vb()}if(t.continue)return Ls.continueRecent(e,n);if(t.sessionId){let i=await Qkn(t.sessionId,e,n);if(i)return Ls.open(i.path,n);console.error(Jt.yellow(`Warning: No project session found with id '${t.sessionId}'; creating a new session with that id.`))}return Ls.create(e,n,{id:t.sessionId})}function ZRi(t,e,n,r,i){let s={},o=[],a=!1;if(t.model){let c=y0({cliProvider:t.provider,cliModel:t.model,cliThinking:t.thinking,modelRuntime:r});c.warning&&o.push({type:"warning",message:c.warning}),c.error&&o.push({type:"error",message:c.error}),c.model&&(s.model=c.model,!t.thinking&&c.thinkingLevel&&(s.thinkingLevel=c.thinkingLevel,a=!0))}if(!s.model&&e.length>0&&!n){let c=i.getDefaultProvider(),u=i.getDefaultModel(),l=c&&u?r.getModel(c,u):void 0,p=l?e.find(d=>yp(d.model,l)):void 0;p?(s.model=p.model,!t.thinking&&p.thinkingLevel&&(s.thinkingLevel=p.thinkingLevel)):(s.model=e[0].model,!t.thinking&&e[0].thinkingLevel&&(s.thinkingLevel=e[0].thinkingLevel))}return t.thinking&&(s.thinkingLevel=t.thinking),e.length>0&&(s.scopedModels=e.map(c=>({model:c.model,thinkingLevel:c.thinkingLevel}))),t.noTools?s.noTools="all":t.noBuiltinTools&&(s.noTools="builtin"),t.tools&&(s.tools=[...t.tools]),t.excludeTools&&(s.excludeTools=[...t.excludeTools]),{options:s,cliThinkingFromModel:a,diagnostics:o}}function Ebe(t,e){return e?.map(n=>PA(n)?jn(n,t):n)}async function eki(t,e){return I9(e,Bye(t),[{label:"Continue",value:t.fallbackCwd},{label:"Cancel",value:void 0}])}async function Wkn(t,e){s8();let n=[...Vvn,...e?.extensionFactories??[]],r=t.includes("--offline")||$kn(process.env.PI_OFFLINE);if(r&&(process.env.PI_OFFLINE="1",process.env.PI_SKIP_VERSION_CHECK="1"),await jRi(t))return;process.platform==="win32"&&bbe(al());let i=process.cwd(),s=Yr(),o=Hu.create(i,s,{projectTrusted:!1});if(I8e(o.getGlobalSettings().httpProxy),l3(),await Bkn(t,{extensionFactories:n})){let Re=process.exitCode??0;if(process.platform==="win32"&&Re===0&&t[0]==="update")return;process.exit(Re);return}if(await Lkn(t,{extensionFactories:n}))return;let a=GH(t);if(a.diagnostics.length>0){for(let Re of a.diagnostics){let Ie=Re.type==="error"?Jt.red:Jt.yellow;console.error(Ie(`${Re.type==="error"?"Error":"Warning"}: ${Re.message}`))}a.diagnostics.some(Re=>Re.type==="error")&&process.exit(1)}if(Gu("parseArgs"),a.version&&(console.log(md),process.exit(0)),a.export){let Re;try{let Ie=a.messages.length>0?a.messages[0]:void 0;Re=await Iun(a.export,Ie)}catch(Ie){let ne=Ie instanceof Error?Ie.message:"Failed to export session";console.error(Jt.red(`Error: ${ne}`)),process.exit(1)}console.log(`Exported to: ${Re}`),process.exit(0)}let c=qRi(a,process.stdin.isTTY,process.stdout.isTTY);c!=="interactive"&&!HRi(a)&&hge(),a.mode==="rpc"&&a.fileArgs.length>0&&(console.error(Jt.red("Error: @file arguments are not supported in RPC mode")),process.exit(1)),YRi(a),zRi(a);let{migratedAuthProviders:l,deprecationWarnings:p}=Xvn(i);Gu("runMigrations");let d=Hu.create(i,s);Ukn(Fkn(d,"startup session lookup")),c==="interactive"&&!a.help&&a.listModels===void 0&&Tvn()&&(await Ivn(d),Gu("firstTimeSetup")),c==="interactive"&&a.useTheme!==void 0&&d.applyOverrides({theme:a.useTheme});let m=process.env[Ule],h=(a.sessionDir?uo(a.sessionDir):void 0)??(m?uFe(m):void 0)??d.getSessionDir(),f=await XRi(a,i,h,d),A=N8e(f,i);if(A)if(c==="interactive"){let Re=await eki(A,d);Re||process.exit(0),f=Ls.open(A.sessionFile,h,Re)}else console.error(Jt.red(new Jv(A).message)),process.exit(1);if(a.name!==void 0){let Re=a.name.trim();Re||(console.error(Jt.red("Error: --name requires a non-empty value")),process.exit(1)),f.appendSessionInfo(Re)}Gu("createSessionManager");let y=new uE(s),b=f.getCwd(),E=a.projectTrustOverride===void 0&&!my(b)?b:void 0,_=a.help||a.listModels!==void 0?"print":c,x=new Map,S=Ebe(i,a.extensions),T=Ebe(i,a.skills),v=Ebe(i,a.promptTemplates),R=Ebe(i,a.themes),O=async({cwd:Re,agentDir:Ie,sessionManager:ne,sessionStartEvent:ce,projectTrustContext:se})=>{let z=ce===void 0,ee=[],j=x.get(Re),X=my(Re),le=a.projectTrustOverride===void 0&&j===void 0&&X,xe=le?!1:j??a.projectTrustOverride??(!X||y.get(Re)===!0),Se=Hu.create(Re,Ie,{projectTrusted:xe}),pe=await A9({cwd:Re,agentDir:Ie,settingsManager:Se,modelRuntimeSignal:AbortSignal.timeout(15e3),extensionFlagValues:a.unknownFlags,resourceLoaderReloadOptions:le?{resolveProjectTrust:async({extensionsResult:rt})=>{let _t=await Hye({cwd:Re,trustStore:y,trustOverride:a.projectTrustOverride,defaultProjectTrust:d.getDefaultProjectTrust(),extensionsResult:rt,projectTrustContext:se??Wye({cwd:Re,mode:z?_:c,settingsManager:d,hasUI:z&&_==="interactive"}),onExtensionError:Zt=>ee.push({type:"warning",message:Zt})});return x.set(Re,_t),_t}}:void 0,resourceLoaderOptions:{additionalExtensionPaths:S,additionalSkillPaths:T,additionalPromptTemplatePaths:v,additionalThemePaths:R,noExtensions:a.noExtensions,noSkills:a.noSkills,noPromptTemplates:a.noPromptTemplates,noThemes:a.noThemes,noContextFiles:a.noContextFiles,systemPrompt:a.systemPrompt,appendSystemPrompt:a.appendSystemPrompt,extensionFactories:n}}),{settingsManager:ge,modelRuntime:Te,resourceLoader:Ee}=pe,ve=[...ee,...pe.diagnostics,...Fkn(ge,"runtime creation"),...Ee.getExtensions().errors.map(({path:rt,error:_t})=>({type:"error",message:`Failed to load extension "${rt}": ${_t}`}))],ye=a.models??ge.getEnabledModels(),Y=ye&&ye.length>0?await ehn(ye,Te,{signal:AbortSignal.timeout(15e3)}):[],{options:qe,cliThinkingFromModel:He,diagnostics:dt}=ZRi(a,Y,ne.buildSessionContext().messages.length>0,Te,ge);ve.push(...dt),a.apiKey&&(qe.model?await Te.setRuntimeApiKey(qe.model.provider,a.apiKey):ve.push({type:"error",message:"--api-key requires a model to be specified via --model, --provider/--model, or --models"}));let at=await y9({services:pe,sessionManager:ne,sessionStartEvent:ce,model:qe.model,thinkingLevel:qe.thinkingLevel,scopedModels:qe.scopedModels,tools:qe.tools,excludeTools:qe.excludeTools,noTools:qe.noTools,customTools:qe.customTools}),ze=a.thinking!==void 0||He;return at.session.model&&ze&&at.session.setThinkingLevel(at.session.thinkingLevel),{...at,services:pe,diagnostics:ve}};Gu("createRuntime");let G=await Uye(O,{cwd:f.getCwd(),agentDir:s,sessionManager:f});Gu("createAgentSessionRuntime");let{services:$,session:U,modelFallbackMessage:W}=G,{settingsManager:re,modelRuntime:ie,resourceLoader:te}=$;if(I8e(re.getGlobalSettings().httpProxy),l3(re.getHttpIdleTimeoutMs()),a.help){let Re=te.getExtensions().extensions.flatMap(Ie=>Array.from(Ie.flags.values()));o5t(Re),process.exit(0)}if(a.listModels!==void 0){let Re=typeof a.listModels=="string"?a.listModels:void 0;await xvn(ie,Re,AbortSignal.timeout(15e3)),process.exit(0)}let q;c!=="rpc"&&(q=await GRi(),q!==void 0&&c==="interactive"&&(c="print")),Gu("readPipedStdin");let{initialMessage:oe,initialImages:be}=await VRi(a,re.getImageAutoResize(),q);Gu("prepareInitialMessage"),d0(re.getTheme(),c==="interactive"),Gu("initTheme"),c==="interactive"&&p.length>0&&await Jvn(p),Gu("resolveModelScope"),Ukn(G.diagnostics),G.diagnostics.some(Re=>Re.type==="error")&&(G.diagnostics.some(Re=>Re.message.includes("Failed to load extension"))&&console.error(Jt.yellow(QRi)),process.exit(1)),Gu("createAgentSession"),c!=="interactive"&&!U.model&&(console.error(Jt.red(u$())),process.exit(1));let De=$kn(process.env.PI_STARTUP_BENCHMARK);if(De&&c!=="interactive"&&(console.error(Jt.red("Error: PI_STARTUP_BENCHMARK only supports interactive mode")),process.exit(1)),!r&&c==="rpc"){let Re=new AbortController,Ie=setTimeout(()=>Re.abort(),15e3);ie.refresh({signal:Re.signal}).catch(()=>{}).finally(()=>clearTimeout(Ie))}if(c==="rpc")o8(),await z9(G);else if(c==="interactive"){let Re=new UO(G,{migratedProviders:l,modelFallbackMessage:W,autoTrustOnReloadCwd:E,initialMessage:oe,initialImages:be,initialMessages:a.messages,verbose:a.verbose,tuiMode:a.tuiMode,initialThemeSetting:a.useTheme});if(De){await Re.init(),Gu("interactiveMode.init"),await new Promise(Ie=>setTimeout(Ie,150)),Re.stop(),Vb(),o8(),process.stdout.writableLength>0&&await new Promise(Ie=>process.stdout.once("drain",Ie)),process.stderr.writableLength>0&&await new Promise(Ie=>process.stderr.once("drain",Ie));return}o8(),await Re.run()}else{o8();let Re=await K9(G,{mode:WRi(c),messages:a.messages,initialMessage:oe,initialImages:be});Vb(),kyn(),Re!==0&&(process.exitCode=Re);return}}var tki={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},J9=class extends En{selectList;constructor(e,n,r){super();let i=[{value:"yes",label:"Yes",description:"Show images inline in terminal"},{value:"no",label:"No",description:"Show text placeholder instead"}];this.addChild(new On),this.selectList=new hd(i,5,Kb(),tki),this.selectList.setSelectedIndex(e?0:1),this.selectList.onSelect=s=>{n(s.value==="yes")},this.selectList.onCancel=()=>{r()},this.addChild(this.selectList),this.addChild(new On)}getSelectList(){return this.selectList}};var nki={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},X9=class extends En{selectList;onPreview;constructor(e,n,r,i){super(),this.onPreview=i;let s=Fde(),o=s.map(c=>({value:c,label:c,description:c===e?"(current)":void 0}));this.addChild(new On),this.selectList=new hd(o,10,Kb(),nki);let a=s.indexOf(e);a!==-1&&this.selectList.setSelectedIndex(a),this.selectList.onSelect=c=>{n(c.value)},this.selectList.onCancel=()=>{r()},this.selectList.onSelectionChange=c=>{this.onPreview(c.value)},this.addChild(this.selectList),this.addChild(new On)}getSelectList(){return this.selectList}};var rki={minPrimaryColumnWidth:12,maxPrimaryColumnWidth:32},iki={off:"No reasoning",minimal:"Very brief reasoning (~1k tokens)",low:"Light reasoning (~2k tokens)",medium:"Moderate reasoning (~8k tokens)",high:"Deep reasoning (~16k tokens)",xhigh:"Extra-high reasoning (~32k tokens)",max:"Maximum reasoning"},Z9=class extends En{selectList;constructor(e,n,r,i){super();let s=n.map(a=>({value:a,label:a,description:iki[a]}));this.addChild(new On),this.selectList=new hd(s,s.length,Kb(),rki);let o=s.findIndex(a=>a.value===e);o!==-1&&this.selectList.setSelectedIndex(o),this.selectList.onSelect=a=>{r(a.value)},this.selectList.onCancel=()=>{i()},this.addChild(this.selectList),this.addChild(new On)}getSelectList(){return this.selectList}};import{dirname as HQa,join as Hkn}from"node:path";var VQa=Hkn(Yr(),"checks-config.json"),KQa=Hkn(Yr(),"settings.json");var YQa=420*1e3,zQa=120*1e3;var c3a=gr.Object({verdict:gr.Union([gr.Literal("PASS"),gr.Literal("FAIL")],{description:"FAIL only for a genuine blocking issue (clear rubric violation, agent-fault-worthy gap, unfair/undiscoverable test requirement, or a real determinism/regression risk). Optional, minor, or stylistic points are NOT grounds for FAIL \u2014 put those in `notes` instead and use PASS."}),summary:gr.String({description:"One short sentence summarizing the verdict."}),reasons:gr.Array(gr.String(),{description:"Specific BLOCKING justifications only, citing rubric item IDs and concrete evidence from the files you read. Required (non-empty) when verdict is FAIL. Use an empty array when verdict is PASS."}),notes:gr.Array(gr.String(),{description:"Non-blocking, optional/minor observations or suggested improvements \u2014 the kind of feedback a real reviewer leaves as 'Minor/optional' without failing the task. Include these regardless of verdict; use an empty array if you truly have none."})});var l3a=gr.Object({statement:gr.String({description:"One sentence from agent_prompt.md, copied verbatim."}),gaps:gr.Array(gr.Object({description:gr.String({description:"A fair, publicly observable missing behavioral test."}),risk:gr.String({description:"Why an incorrect implementation could pass the current tests despite this missing behavior."})}),{description:"All candidate positive and negative gaps for this sentence; there is no maximum or target count, so include every distinct evidence-backed gap and relevant edge case rather than stopping at 10; use an empty array only when exhaustive analysis finds none."})});var u3a=gr.Object({gaps:gr.Array(gr.Object({description:gr.String({description:"The confirmed, real, fair test gap (may be reworded for clarity). Keep POSITIVE:/NEGATIVE: prefix when applicable."}),justification:gr.String({description:"Why this is genuinely grounded in agent_prompt.md or the repo, fair to test per the fairness methodology, and a real (non-duplicate) coverage hole in test.patch \u2014 for negative gaps, cite the prompt's prohibition/constraint and why no existing test catches the forbidden outcome."})}),{description:"The filtered, final list of confirmed test gaps. Use an empty array if none of the candidates survive strict scrutiny."})});var oki=gr.Object({category:gr.Union([gr.Literal("unfair-assertion"),gr.Literal("prompt-ambiguity"),gr.Literal("broken-fixture")],{description:"The kind of actionable problem found in the current test or its setup."}),testName:gr.String({description:"The test name or short identifier that lets the caller find the affected assertion."}),problem:gr.String({description:"What is wrong with the test and why it is blocking or actionable."}),evidence:gr.String({description:"The prompt, public repository contract, test, or fixture evidence supporting the finding."}),requiredBehavior:gr.String({description:"The semantic behavior or gap that must remain covered after the test is repaired."}),recommendation:gr.String({description:"A fair repair, or a prompt clarification when the contract is genuinely ambiguous."})}),p3a=gr.Object({findings:gr.Array(oki,{description:"Only confirmed, actionable test-fairness, ambiguity, or fixture findings from the complete single-pass audit. Use an empty array when the current tests contain no confirmed unfairness."})});var aki=gr.Object({category:gr.Union([gr.Literal("missing-requirement"),gr.Literal("regression"),gr.Literal("architecture"),gr.Literal("unsafe-failure"),gr.Literal("inconsistent-path"),gr.Literal("dead-code"),gr.Literal("unrelated-change")],{description:"The kind of actionable quality problem found in the solution implementation."}),subject:gr.String({description:"A short behavior, symbol, or concern identifier; do not require a source line or file location."}),problem:gr.String({description:"What is wrong with the implementation and why it is actionable."}),evidence:gr.String({description:"The prompt, repository, implementation, or regression evidence supporting the finding."}),requiredBehavior:gr.String({description:"The requirement, invariant, or solution-quality property that must be preserved."}),recommendation:gr.String({description:"A concrete repair that stays within the prompt and repository conventions."})}),d3a=gr.Object({findings:gr.Array(aki,{description:"Only confirmed, actionable solution-quality findings. Use an empty array when the implementation meets the prompt and repository standards."})});var m3a=gr.Object({gaps:gr.Array(gr.Object({description:gr.String({description:"The specific behavioral gap: a way one or more solver's diff differs materially from what agent_prompt.md/solution.patch require, despite that solver passing `./test.sh new`."}),justification:gr.String({description:"Why this is a genuine requirement from agent_prompt.md or solution.patch (cite the specific requirement/line) that the solver's diff misses, contradicts, or diverges from \u2014 and why the current tests fail to catch that divergence."}),evidence:gr.String({description:"Which solver(s) (by index) exhibit this, and the specific part of their diff that grounds the gap."})}),{description:"Concrete, diff-grounded behavioral gaps \u2014 cases where a passing solver's materially different approach reveals that `test.sh new` under-specifies a real requirement. Use an empty array if the solvers converged on equivalent behavior; do not manufacture gaps just to report something."})});function jkn(){return["You are a adversarial tester. Your goal is to find the most minimal, shortcut implementation that makes all new tests pass \u2014 not a full, correct solution. This is intentional: we want to discover whether the test suite lets through an implementation that barely satisfies the assertions without properly implementing the prompt's required behavior.","`agent_prompt.md` in the repo root describes the intended task. Tests for it already exist and are currently failing.","","Goal: make ALL of the new tests pass with the least amount of real logic possible.","1. Run `bash test.sh new` to see the failures and what the tests expect. Read the failing tests carefully \u2014 they are the only spec you need to satisfy.","2. Understand exactly what each test assertion checks. Ask, 'what is the minimum thing I can do \u2014 a stub, a hardcoded return, a mockish pass-through, a trivial branch \u2014 to satisfy this test?', not 'what does agent_prompt.md intend?'. Skim `agent_prompt.md` only enough to understand what the test file names and assertions refer to, then rely on the test errors to drive what to implement.","3. Prefer the most minimal implementation possible:"," - Hardcode a return value if the test expects one."," - Add only the code paths a test actually exercises; leave anything untested unimplemented."," - Mock the minimum number of dependencies (or none) that the test error forces you to touch."," - Use the most direct, trivial, shortcut approach \u2014 do not build abstractions, do not handle unobserved edge cases, do not add defensive code.","4. Before declaring success, also run `bash test.sh base` to confirm your changes cause no regressions. The shortcut must not break existing tests \u2014 that would be a false positive from a different angle.","5. Re-run `bash test.sh new` and iterate until both the new tests and the base tests pass, or you're confident you cannot pass more without adding real logic.","","Rules:","- Do NOT modify the test files or `test.sh`. Only change application/library code.","- You have shell access \u2014 install any dependencies you need.","- The prompt is not your spec: the tests are. Implement exactly what the tests demand, nothing more. If you can satisfy a test with a hardcoded return, do it."].join(`
|
|
2357
2357
|
`)}import{readFileSync as Vkn}from"node:fs";var cki=5e3,lki=95;function uki(t){try{let e=Number.parseInt(Vkn(t,"utf-8").trim(),10);return Number.isFinite(e)?e:void 0}catch{return}}function pki(t){return t==="small"?1:t==="medium"?2:4}function dki(t){try{let n=Vkn("/sys/fs/cgroup/cpu.stat","utf-8"),r=Number.parseInt(n.match(/^usage_usec\s+(\d+)/m)?.[1]??"",10);if(Number.isFinite(r))return{usageMicros:r,vcpus:t}}catch{}let e=uki("/sys/fs/cgroup/cpuacct/cpuacct.usage");if(e!==void 0)return{usageMicros:e/1e3,vcpus:t}}var _be=class{startedAt=Date.now();profile;vcpus;timer;lastCpu;lastSampleAt;sampleCount=0;observedMs=0;cpuOver95Ms=0;maxCpuPercent=null;stopped;constructor(e){this.profile=e,this.vcpus=pki(e)}start(){this.sample(),this.timer=setInterval(()=>this.sample(),cki)}stop(){return this.stopped?this.stopped:(this.timer&&clearInterval(this.timer),this.timer=void 0,this.sample(),this.stopped=this.snapshot(),this.stopped)}snapshot(){return{profile:this.profile,allocatedVcpus:this.vcpus,durationMs:Date.now()-this.startedAt,sampleCount:this.sampleCount,maxCpuPercent:this.maxCpuPercent,cpuOver95DurationMs:this.observedMs>0?this.cpuOver95Ms:null,observedAt:new Date().toISOString()}}sample(){if(this.stopped)return;let e=Date.now(),n=dki(this.vcpus);if(this.sampleCount+=1,n&&this.lastCpu&&this.lastSampleAt!==void 0){let r=e-this.lastSampleAt,i=Math.max(0,n.usageMicros-this.lastCpu.usageMicros),s=Math.max(0,Math.min(100,i/(r*1e3*n.vcpus)*100));this.observedMs+=Math.max(0,r);let o=Math.max(0,r);s>=lki&&(this.cpuOver95Ms+=o),this.maxCpuPercent=this.maxCpuPercent===null?s:Math.max(this.maxCpuPercent,s)}n&&(this.lastCpu=n),this.lastSampleAt=e}};var eY;H0t();var tY="/opt/shipd-agent",zkn="/work/solvers",Kkn=4e3;function Fp(t){let e=process.env[t];if(!e)throw new Error(`Missing worker environment variable ${t}.`);return e}function fki(t){return t.length>Kkn?t.slice(t.length-Kkn):t}function hki(){let t=JSON.parse(Sbe("/tmp/shipd-bootstrap.json","utf-8")),e=["bucket","region","sourceKey","authKey","resultKey"].every(i=>typeof t[i]=="string"&&t[i]),n=["planB64","provider","modelId","thinkingLevel","resourceProfile"],r={planB64:"SHIPD_PLAN_B64",provider:"SHIPD_PROVIDER",modelId:"SHIPD_MODEL_ID",thinkingLevel:"SHIPD_THINKING_LEVEL",resourceProfile:"SHIPD_RESOURCE_PROFILE"};if(e)for(let[i,s]of[["bucket","SHIPD_S3_BUCKET"],["region","SHIPD_S3_REGION"],["sourceKey","SHIPD_S3_SOURCE_KEY"],["authKey","SHIPD_S3_AUTH_KEY"],["resultKey","SHIPD_S3_RESULT_KEY"]]){let o=t[i];if(typeof o!="string"||o.length===0)throw new Error(`Invalid Fargate bootstrap field: ${i}.`);process.env[s]=o}else for(let[i,s]of[["sourceUrl","SHIPD_SOURCE_URL"],["authUrl","SHIPD_AUTH_URL"],["resultPutUrl","SHIPD_RESULT_PUT_URL"],["resultGetUrl","SHIPD_RESULT_GET_URL"]]){let o=t[i];if(typeof o!="string"||o.length===0)throw new Error(`Invalid Fargate bootstrap field: ${i}.`);process.env[s]=o}for(let i of n){let s=t[i];if(typeof s!="string"||s.length===0)throw new Error(`Invalid Fargate bootstrap field: ${i}.`);process.env[r[i]]=s}for(let[i,s]of[["timeoutMinutes","SHIPD_TIMEOUT_MINUTES"],["solverCount","SHIPD_SOLVER_COUNT"]]){let o=t[i];if(typeof o!="number"||!Number.isFinite(o))throw new Error(`Invalid Fargate bootstrap field: ${i}.`);process.env[s]=String(o)}}function gki(){let t=Fp("SHIPD_PLAN_B64");return JSON.parse(Buffer.from(t,"base64url").toString("utf-8"))}function Aki(t){let e={...process.env};for(let[n,r]of Object.entries(t.env))e[n]=r.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g,(i,s,o)=>e[s??o]??"");return e}async function Jkn(t,e){let n=await fetch(t);if(!n.ok)throw new Error(`Download failed (${n.status}) for ${e}.`);I3(e,Buffer.from(await n.arrayBuffer()))}function w3(){return!!process.env.SHIPD_S3_BUCKET}function HKe(){return new $O.S3Client({region:Fp("SHIPD_S3_REGION"),credentials:(0,Ykn.defaultProvider)()})}async function Xkn(t,e,n){let i=await(await HKe().send(new $O.GetObjectCommand({Bucket:t,Key:e}))).Body?.transformToByteArray();if(!i)throw new Error(`S3 object was empty: s3://${t}/${e}`);I3(n,Buffer.from(i))}async function GKe(t,e){let n=JSON.stringify(e);if(w3()){await HKe().send(new $O.PutObjectCommand({Bucket:Fp("SHIPD_S3_BUCKET"),Key:Fp("SHIPD_S3_RESULT_KEY"),Body:n,ContentType:"application/json"}));return}let r=await fetch(t,{method:"PUT",headers:{"content-type":"application/json"},body:n});if(!r.ok){let i=(await r.text()).trim();throw new Error(`Result upload failed (${r.status})${i?`: ${i.slice(0,1e3)}`:"."}`)}}async function qKe(t,e,n,r){return await new Promise((i,s)=>{let o=mki("/bin/bash",["-c",t],{cwd:e,env:n,stdio:["ignore","pipe","pipe"],detached:process.platform!=="win32"}),a="",c="",u=!1,l,p=d=>{u||(u=!0,l&&clearTimeout(l),i(d))};o.stdout.on("data",d=>{a+=d.toString()}),o.stderr.on("data",d=>{c+=d.toString()}),o.once("error",d=>{u||(u=!0,l&&clearTimeout(l),s(new Error(`${d instanceof Error?d.message:String(d)} (cwd=${e} exists=${WKe(e)})`)))}),o.once("close",d=>p({code:d??1,stdout:a,stderr:c})),l=setTimeout(()=>{process.platform!=="win32"&&o.pid?process.kill(-o.pid,"SIGTERM"):o.kill("SIGTERM"),setTimeout(()=>{u||(process.platform!=="win32"&&o.pid?process.kill(-o.pid,"SIGKILL"):o.kill("SIGKILL"))},5e3)},r)})}async function nY(t,e,n,r){let i=await qKe(t,e,n,r);if(i.code!==0)throw new Error([i.stderr.trim(),i.stdout.trim(),`Remote command: ${t}`].filter(Boolean).join(`
|
|
2358
2358
|
`));return i}function yki(t){let e=t.trim().replace(/["']/g,"");return/^chmod\s+\S+\s+(?:\S*\/)?test\.sh$/.test(e)}async function bki(t,e){let n="/tmp/shipd-source.tar.gz";w3()?await Xkn(Fp("SHIPD_S3_BUCKET"),Fp("SHIPD_S3_SOURCE_KEY"),n):await Jkn(Fp("SHIPD_SOURCE_URL"),n),xbe(t.workdir,{recursive:!0}),await nY(`tar -xzf ${To(n)} -C ${To(t.workdir)}`,t.workdir,e,900*1e3);let r=[`git config --global --add safe.directory ${To(t.workdir)}`,`git -C ${To(t.workdir)} init -q`,`git -C ${To(t.workdir)} config user.email solvergap@shipd-checks.local`,`git -C ${To(t.workdir)} config user.name shipd-checks-source`,`git -C ${To(t.workdir)} add -A`,`git -C ${To(t.workdir)} commit -q -m source --allow-empty`].join(`
|
|
2359
2359
|
`);await nY(`set -eu
|