@rulemetric/cli 0.14.2 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-5PMTNNA6.js → chunk-2U6PAYCD.js} +1 -1
- package/dist/{chunk-6AAAHV2B.js → chunk-3H44B6PB.js} +1 -1
- package/dist/chunk-4GOXEEXZ.js +1 -0
- package/dist/{chunk-H4QPAEEA.js → chunk-5GFEEYHM.js} +1 -1
- package/dist/{chunk-RYCVPQYK.js → chunk-5IL3EEIE.js} +1 -1
- package/dist/{chunk-VCUW2NAP.js → chunk-5Z6XXOJL.js} +1 -1
- package/dist/{chunk-Q36QSFSB.js → chunk-6QMIDH6X.js} +1 -1
- package/dist/{chunk-H2FMAJUJ.js → chunk-7LE2W3WP.js} +1 -1
- package/dist/{chunk-6TGFU6RU.js → chunk-7LFCZI64.js} +1 -1
- package/dist/{chunk-7H4HJ2RV.js → chunk-BU3ZGLQG.js} +1 -1
- package/dist/{chunk-QENSCK77.js → chunk-CIKQXFQ2.js} +1 -1
- package/dist/{chunk-ISFPPDDB.js → chunk-D5XLTSRV.js} +1 -1
- package/dist/{chunk-RR7V5CK5.js → chunk-EE4TZAZI.js} +1 -1
- package/dist/{chunk-T47SFA5X.js → chunk-FADINV4H.js} +1 -1
- package/dist/{chunk-DVU5PHPM.js → chunk-FG343JM3.js} +1 -1
- package/dist/chunk-GJHFIQVO.js +28 -0
- package/dist/{chunk-LB24UKHZ.js → chunk-GYKYJJNF.js} +1 -1
- package/dist/{chunk-DXNUCWUX.js → chunk-HXOQUYG3.js} +1 -1
- package/dist/{chunk-HM63AB2C.js → chunk-IFIWDL7G.js} +1 -1
- package/dist/chunk-ISEUEYSC.js +1 -0
- package/dist/chunk-JIW2PCHU.js +1 -0
- package/dist/chunk-JNLDISBA.js +4 -0
- package/dist/{chunk-FS3TAQAE.js → chunk-JOXTWLLK.js} +1 -1
- package/dist/chunk-JU5ZNXPK.js +1 -0
- package/dist/chunk-KFNFLMUR.js +3 -0
- package/dist/{chunk-7MTYUTUN.js → chunk-KR36ZDGN.js} +1 -1
- package/dist/{chunk-O4K4M5G6.js → chunk-LJE5J3EW.js} +1 -1
- package/dist/{chunk-PXYK4MBX.js → chunk-LLXC5SRC.js} +1 -1
- package/dist/{chunk-WIKCYUZC.js → chunk-OAETRNTE.js} +1 -1
- package/dist/{chunk-KOYHJFB3.js → chunk-PDXHRF4E.js} +1 -1
- package/dist/{chunk-F5PJN2EY.js → chunk-Q7IDLOSP.js} +1 -1
- package/dist/{chunk-ZK3ACE4T.js → chunk-T7HZZ4DJ.js} +1 -1
- package/dist/{chunk-5VNEHPGC.js → chunk-TQM7MF5C.js} +1 -1
- package/dist/{chunk-EBWV4SUS.js → chunk-U3PIBPHT.js} +1 -1
- package/dist/chunk-UNVURR4E.js +1 -0
- package/dist/{chunk-VXNICAVG.js → chunk-VUNJGZPP.js} +1 -1
- package/dist/{chunk-J6RQ5AH2.js → chunk-W6MMJRFZ.js} +1 -1
- package/dist/{chunk-XZW5ZHFC.js → chunk-WQFR2LOY.js} +1 -1
- package/dist/chunk-WVNTUKED.js +1 -0
- package/dist/{chunk-XIOYV5A7.js → chunk-X3BBFDRD.js} +1 -1
- package/dist/{chunk-7BCZDVIU.js → chunk-XCH4HPEZ.js} +1 -1
- package/dist/{chunk-RSVNQ2XI.js → chunk-YXMAGC53.js} +1 -1
- package/dist/chunk-ZMVTSYD4.js +1 -0
- package/dist/commands/diagnostics.js +1 -1
- package/dist/commands/evals/agent.js +1 -1
- package/dist/commands/evals/auto-run.js +1 -1
- package/dist/commands/evals/benchmark.js +1 -1
- package/dist/commands/evals/compare.js +1 -1
- package/dist/commands/evals/optimize-description.js +1 -1
- package/dist/commands/evals/optimize.js +1 -1
- package/dist/commands/evals/refine-cases.js +1 -1
- package/dist/commands/evals/run.js +1 -1
- package/dist/commands/evals/validate-judge.js +1 -1
- package/dist/commands/sessions/list.js +1 -1
- package/dist/dashboard/Dashboard.js +1 -1
- package/dist/dashboard/data.js +1 -1
- package/dist/{dist-GSHUC7UU.js → dist-OVXV2FFO.js} +1 -1
- package/dist/lib/agent-loop.js +1 -1
- package/dist/lib/codex-exec.js +1 -1
- package/dist/lib/eval-analyzer.js +1 -1
- package/dist/lib/eval-benchmark.js +1 -1
- package/dist/lib/eval-candidate-run.js +1 -1
- package/dist/lib/eval-case-generator.js +1 -1
- package/dist/lib/eval-conversation-handler.js +1 -1
- package/dist/lib/eval-executor.js +1 -1
- package/dist/lib/eval-grader.js +1 -1
- package/dist/lib/eval-meta-judge.js +1 -1
- package/dist/lib/eval-resume.js +1 -1
- package/dist/lib/eval-run-batch.js +1 -1
- package/dist/lib/eval-trigger-tester.js +1 -1
- package/dist/lib/evolution-cost.js +1 -1
- package/dist/lib/evolution-enrolment.js +1 -1
- package/dist/lib/instruction-proposer.js +1 -1
- package/dist/lib/instruction-restoration.js +1 -0
- package/dist/lib/jobs/handlers/cron-eval-autorun.js +1 -1
- package/dist/lib/jobs/handlers/cron-instruction-evolution.js +1 -1
- package/dist/lib/jobs/handlers/cron-refine-cases.js +1 -1
- package/dist/lib/jobs/handlers/cron-refresh-pricing.js +1 -1
- package/dist/lib/jobs/handlers/cron-suggest-instructions.js +1 -1
- package/dist/lib/jobs/handlers/distill-memories.js +1 -1
- package/dist/lib/jobs/handlers/process-changelog.js +1 -1
- package/dist/lib/jobs/handlers/process-conversation.js +1 -1
- package/dist/lib/jobs/handlers/process-eval.js +1 -1
- package/dist/lib/jobs/handlers/process-insights.js +1 -1
- package/dist/lib/jobs/handlers/process-judge-review.js +1 -1
- package/dist/lib/jobs/handlers/process-launch.js +1 -1
- package/dist/lib/jobs/handlers/process-memory-ab.js +1 -1
- package/dist/lib/jobs/handlers/process-run-cleanup.js +1 -1
- package/dist/lib/jobs/handlers/process-session-goal.js +1 -1
- package/dist/lib/judge-review-runner.js +1 -1
- package/dist/lib/llm-client.js +1 -1
- package/dist/lib/manual-tasks.js +1 -1
- package/dist/lib/measurement-llm.js +1 -1
- package/dist/lib/optimize-compare.js +1 -1
- package/dist/lib/projects/workspace/worktree.js +1 -1
- package/dist/lib/refine-cases.js +1 -1
- package/dist/lib/study-fixture.js +1 -0
- package/oclif.manifest.json +1 -1
- package/package.json +4 -4
- package/dist/chunk-3NWJ7CZ2.js +0 -1
- package/dist/chunk-FBSZ6KCM.js +0 -1
- package/dist/chunk-H33XYL7O.js +0 -1
- package/dist/chunk-Q776YUBD.js +0 -1
- package/dist/chunk-SG4UDDHB.js +0 -4
- package/dist/chunk-T75KAEJO.js +0 -25
- package/dist/chunk-VBXL7XO7.js +0 -1
- package/dist/chunk-ZTQUGAZG.js +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as f}from"./chunk-
|
|
1
|
+
import{c as f}from"./chunk-D5XLTSRV.js";import{a as l}from"./chunk-5RBLIVBF.js";import{b as g,e as k}from"./chunk-GIXHG5FK.js";import{a as m}from"./chunk-ZLLER3HP.js";async function C(w,i={}){let R=i.removeWorktreeFn??f,t=i.log??(e=>process.stderr.write(`[process_run_cleanup] ${e}
|
|
2
2
|
`)),j=i.getRunDetail??(async e=>{try{return await k(`/api/runs/${e}`)}catch(r){if(r instanceof g&&r.statusCode===404)return null;throw r}}),{runId:o}=w,n=await j(o);if(!n)throw new l(`Run ${o} not found`);if(!n.run.projectPath)throw new l(`Run ${o} has no projectPath; cannot resolve a repo root for worktree cleanup`);let a=n.run.projectPath,$=n.sessions.filter(e=>e.endedAt!=null),s=[],u=0,c=0,p=0,d=0,h=new Set;for(let e of $)if(!(!e.projectPath||e.projectPath===a)&&!h.has(e.projectPath)){h.add(e.projectPath);try{let r=await R({repoRoot:a,worktreePath:e.projectPath});r.removed?(u++,s.push({sessionId:e.id,worktreePath:e.projectPath,status:"removed"}),t(`removed worktree ${e.projectPath} (session ${e.id})`)):r.reason==="dirty"?(c++,s.push({sessionId:e.id,worktreePath:e.projectPath,status:"skipped-dirty"}),t(`skipped dirty worktree ${e.projectPath} (session ${e.id}) \u2014 uncommitted changes`)):(p++,s.push({sessionId:e.id,worktreePath:e.projectPath,status:"absent"}),t(`worktree absent ${e.projectPath} (session ${e.id})`))}catch(r){let P=r instanceof Error?r.message:String(r);d++,s.push({sessionId:e.id,worktreePath:e.projectPath,status:"error",error:P.slice(0,1e3)}),t(`error removing worktree ${e.projectPath} (session ${e.id}): ${P}`)}}return t(`run ${o} cleanup: removed=${u} skippedDirty=${c} absent=${p} errored=${d}`),{runId:o,repoRoot:a,removed:u,skippedDirty:c,absent:p,errored:d,worktrees:s}}m(C,"processRunCleanup");export{C as a};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as D,c as j}from"./chunk-6UEFCMR2.js";import{a as G}from"./chunk-
|
|
1
|
+
import{b as D,c as j}from"./chunk-6UEFCMR2.js";import{a as G}from"./chunk-FG343JM3.js";import{d as J}from"./chunk-JNLDISBA.js";import{b as B,c as R,d as N,e as z}from"./chunk-GPBN4ROE.js";import{e as f,g as T}from"./chunk-GIXHG5FK.js";import{a as p}from"./chunk-ZLLER3HP.js";function W(r,a,s){return s?r.reviewerModel===s||r.reviewerModel===`${a}:${s}`:r.reviewerEngine===a}p(W,"reviewMatchesReviewer");var C=100;function Z(r){let a=new Set;return r.forEach((s,d)=>{s.method!=="deterministic"&&a.add(d)}),a}p(Z,"llmExpectationIndexes");var w=class extends Error{constructor(s,d){super(d);this.reason=s}static{p(this,"JudgeReviewSkip")}};async function oe(r){let a=r.log??(()=>{}),s=r.warn??a,d=r.targetId,K=r.parallel??3,U=r.timeoutMs??12e4,v=await f(`/api/eval-targets/${d}`),u=(await f(`/api/eval-targets/${d}/annotations?limit=500`)).filter(e=>e.judgeMethod==="llm");if(u.length===0)throw new w("no-labels",`No human labels on "${v.name}" yet \u2014 label some runs in the Review tab first.`);let n;try{n=z({engineFlag:r.engineFlag??"auto",modelFlag:r.modelFlag,availability:N(),judgeModels:[...new Set(u.map(e=>e.judgeModel).filter(e=>e!=null))]})}catch(e){throw new w("no-engine",e instanceof Error?e.message:String(e))}a(`Reviewer: ${n.rationale}`);let c=0,b=u;if(r.skipReviewed){let e=await f(`/api/eval-targets/${d}/judge-reviews`),t=new Set(e.filter(i=>W(i,n.engine,r.modelFlag)).map(i=>`${i.evalRunId}:${i.expectationIndex}`));if(b=u.filter(i=>!t.has(`${i.evalRunId}:${i.expectationIndex}`)),c=u.length-b.length,b.length===0)return{targetName:v.name,reviewer:n,judgeModels:[],reviewerModel:n.model??`${n.engine} (CLI default)`,report:j([],0),persisted:0,alreadyReviewed:c,deferredPartialRuns:0}}let y=new Map;for(let e=0;;e+=C){let t=await f(`/api/eval-targets/${d}/runs?limit=${C}&offset=${e}`);for(let i of t)y.set(i.id,i);if(t.length<C)break}let q=await f(`/api/eval-targets/${d}/evals`),X=new Map(q.map(e=>[e.id,e.prompt])),o=new Map;for(let e of b){let t=o.get(e.evalRunId)??[];t.push(e),o.set(e.evalRunId,t)}let P=new Map;for(let e of u){let t=P.get(e.evalRunId)??new Set;t.add(e.expectationIndex),P.set(e.evalRunId,t)}let x=0;for(let[e]of[...o]){let t=y.get(e)?.grading?.expectations;if(!t)continue;let i=Z(t),g=P.get(e)??new Set;[...i].every(h=>g.has(h))||(o.delete(e),x+=1)}if(x>0&&a(`${x} partially-labeled run(s) deferred \u2014 a run is re-graded once, after all its assertions are labeled.`),o.size===0)return{targetName:v.name,reviewer:n,judgeModels:[],reviewerModel:n.model??`${n.engine} (CLI default)`,report:j([],0),persisted:0,alreadyReviewed:c,deferredPartialRuns:x};if(n.engine==="codex"&&n.model){let e=await J({prompt:"Reply with exactly: OK",model:n.model,timeout:6e4});if(e.error&&B(e.error)){if(n.model===R)throw new w("preflight-failed",`Codex fallback model ${R} is also unrunnable: ${e.error}`);s(`Your codex model "${n.model}" can't run on the installed CLI/account \u2014 falling back to ${R}.`),n={...n,model:R}}else if(e.error)throw new w("preflight-failed",`Codex preflight failed: ${e.error}`)}let S=[...o.values()].flat(),Y=[...new Set(S.map(e=>e.judgeModel).filter(e=>e!=null))];a(`Re-grading ${o.size} annotated run(s) / ${S.length} assertion(s) on "${v.name}"`+(c?` (${c} already reviewed \u2014 skipped)`:"")+".");let $=[],I=0,k=new Set,m=r.limit!=null?[...o.entries()].slice(0,Math.max(1,r.limit)):[...o.entries()];m.length<o.size&&a(`Sampling ${m.length} of ${o.size} annotated runs (limit).`);let H=0,Q=p(async()=>{for(;;){let e=H++;if(e>=m.length)return;let[t,i]=m[e],g=y.get(t),h=g?.grading?.expectations,O=g?.outputs?.transcript,F=g?X.get(g.evalId):void 0;if(!g||!h?.length||!O||!F){I+=i.length,s(`run ${t.slice(0,8)}: missing output/expectations/prompt \u2014 skipped`);continue}let M=await G({prompt:F,output:O,expectations:h.map(l=>l.text),model:n.model??void 0,timeout:U,engine:n.engine});M.judge_model&&k.add(M.judge_model);for(let l of i){let L=h[l.expectationIndex],A=M.expectations[l.expectationIndex];if(!L||!A||L.text!==l.expectationText){I+=1;continue}if(M.judge_model==null&&A.method==="llm"){I+=1;continue}$.push({runId:t,expectationIndex:l.expectationIndex,text:l.expectationText,humanPassed:D(l.verdict,l.judgePassed),judgeAPassed:l.judgePassed,judgeBPassed:A.passed})}a(` ${e+1}/${m.length} re-graded`)}},"workerFn");await Promise.all(Array.from({length:Math.max(1,Math.min(K,m.length))},Q));let V=j($,I),_=[...k][0]??n.model??`${n.engine} (CLI default)`,E=0;if($.length>0)try{E=(await T(`/api/eval-targets/${d}/judge-reviews`,{reviewerEngine:n.engine,reviewerModel:_,verdicts:$.map(t=>({evalRunId:t.runId,expectationIndex:t.expectationIndex,expectationText:t.text,judgePassed:t.judgeAPassed,humanPassed:t.humanPassed,reviewerPassed:t.judgeBPassed}))})).upserted,a(`Persisted ${E} reviewer verdict(s) \u2014 disagreements appear on the Review tab.`)}catch(e){s(`Could not persist reviewer verdicts: ${e instanceof Error?e.message:e}`)}return{targetName:v.name,reviewer:n,judgeModels:Y,reviewerModel:_,report:V,persisted:E,alreadyReviewed:c,deferredPartialRuns:x}}p(oe,"runJudgeReviewPass");export{W as a,Z as b,w as c,oe as d};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as P}from"./chunk-JP6ULOEX.js";import{d as k}from"./chunk-JNLDISBA.js";import{c as b,d as _}from"./chunk-GPBN4ROE.js";import{a as u}from"./chunk-ZLLER3HP.js";import{spawn as M}from"node:child_process";var E=["claude","codex","pi"];function N(e,t=process.env){if(e){if(E.includes(e))return e;throw new Error(`Eval engine "${String(e)}" is not known (expected one of: ${E.join(", ")})`)}let r=t.RULEMETRIC_EVAL_ENGINE?.trim().toLowerCase();if(!r)return"claude";if(E.includes(r))return r;throw new Error(`RULEMETRIC_EVAL_ENGINE="${t.RULEMETRIC_EVAL_ENGINE}" is not a known engine (expected one of: ${E.join(", ")})`)}u(N,"resolveEvalEngine");function S(e,t=process.env){return e?.trim()||t.RULEMETRIC_CODEX_MODEL?.trim()||_().codexConfiguredModel||b}u(S,"resolveCodexEvalModel");function h(e){try{let t=JSON.parse(e),r=t.result??t.content??e,a=t.usage?.total_tokens??(t.usage?.input_tokens??0)+(t.usage?.output_tokens??0)+(t.usage?.cache_creation_input_tokens??0)+(t.usage?.cache_read_input_tokens??0),n;if(t.modelUsage&&typeof t.modelUsage=="object"){let o=-1;for(let[l,d]of Object.entries(t.modelUsage)){let i=typeof d?.outputTokens=="number"?d.outputTokens:0;i>o&&(o=i,n=l)}}return{output:r,totalTokens:a,model:n,...t.usage&&typeof t.usage=="object"&&!Array.isArray(t.usage)?{usage:t.usage}:{}}}catch{return{output:e,totalTokens:0}}}u(h,"parseClaudeJsonOutput");function F(e){let{prompt:t,targetContent:r,systemPrompt:a,model:n}=e,o=["-p",t,"--output-format","json","--settings",JSON.stringify({disableAllHooks:!0,...e.writableFixture?{permissions:{blockReadsOutsideWorkingDirectories:!0},sandbox:{enabled:!0,failIfUnavailable:!0,autoAllowBashIfSandboxed:!0,allowUnsandboxedCommands:!1,excludedCommands:[],filesystem:{disabled:!1},network:{allowedDomains:[],strictAllowlist:!0}}}:{}})];e.writableFixture&&o.push("--safe-mode","--restricted","--strict-mcp-config","--tools","Read,Write,Edit,Bash","--permission-mode","acceptEdits","--allowedTools","Read,Write,Edit,Bash");let l=r??a;return l&&o.push(e.appendTarget?"--append-system-prompt":"--system-prompt",l),n&&o.push("--model",n),o}u(F,"buildClaudeArgs");function I(e,t,r,a){let n=t.trim()||r.trim()||a.trim()||"(no output on stderr or stdout)";return`Exit code ${e}: ${n.slice(0,1e3)}`}u(I,"describeExitFailure");async function U(e){let{prompt:t,targetContent:r,systemPrompt:a,workDir:n,timeout:o,model:l}=e,d=r??a,i=await k({prompt:t,systemPrompt:d,model:S(l),writableFixture:e.writableFixture,timeout:o,workDir:n});return{output:i.output,exitCode:i.exitCode,durationMs:i.durationMs,totalTokens:i.usage?.totalTokens??0,model:i.model,engine:"codex",delivery:d?"prompt_prefix":"none",error:i.error}}u(U,"executeCodexArm");async function j(e){let t=e.targetContent??e.systemPrompt,r=await P({prompt:e.prompt,...e.appendTarget?{appendSystemPrompt:t}:{systemPrompt:t},ignoreContextFiles:e.ignoreContextFiles,model:e.model,timeout:e.timeout,workDir:e.workDir});return{output:r.output,exitCode:r.exitCode,durationMs:r.durationMs,totalTokens:r.usage?.totalTokens??0,model:r.model,provider:r.provider,costUsd:r.costUsd,engine:"pi",delivery:t?"system_prompt":"none",error:r.error}}u(j,"executePiArm");async function J(e){let{prompt:t,targetContent:r,systemPrompt:a,workDir:n=process.cwd(),timeout:o=12e4,model:l}=e,d=N(e.engine);if(d==="codex")return U({...e,workDir:n,timeout:o});if(d==="pi")return j({...e,workDir:n,timeout:o});let i=F({prompt:t,targetContent:r,systemPrompt:a,model:l,appendTarget:e.appendTarget,writableFixture:e.writableFixture}),g=r??a?"system_prompt":"none",x=Date.now();return new Promise(f=>{let c=e.writableFixture?Object.fromEntries(Object.entries(process.env).filter(([s])=>["HOME","PATH","USER","LOGNAME","SHELL","TMPDIR","LANG","LC_ALL","TZ","SSL_CERT_FILE","NODE_EXTRA_CA_CERTS","ANTHROPIC_API_KEY","CLAUDE_CODE_OAUTH_TOKEN","CLAUDE_CONFIG_DIR"].includes(s))):{...process.env};delete c.CLAUDECODE,delete c.HTTPS_PROXY;let D=["/opt/homebrew/bin","/usr/local/bin"],C=(c.PATH??"").split(":").filter(Boolean),v=D.filter(s=>!C.includes(s));v.length&&(c.PATH=[...C,...v].join(":"));let p=M("claude",i,{cwd:n,env:c,stdio:["ignore","pipe","pipe"]}),m="",T="";p.stdout.on("data",s=>{m+=s.toString()}),p.stderr.on("data",s=>{T+=s.toString()});let w=setTimeout(()=>{p.kill("SIGTERM"),f({output:m,exitCode:null,durationMs:Date.now()-x,totalTokens:0,engine:"claude",delivery:g,error:`Timed out after ${o}ms`})},o);p.on("close",s=>{clearTimeout(w);let R=Date.now()-x,{output:y,totalTokens:A,model:O,usage:L}=h(m);f({output:y,exitCode:s,durationMs:R,totalTokens:A,usage:L,model:O,engine:"claude",delivery:g,error:s!==0?I(s,T,y,m):void 0})}),p.on("error",s=>{clearTimeout(w),f({output:"",exitCode:null,durationMs:Date.now()-x,totalTokens:0,engine:"claude",delivery:g,error:`Failed to spawn claude: ${s.message}`})})})}u(J,"executeEval");export{N as a,S as b,h as c,F as d,I as e,J as f};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as u,c as d}from"./chunk-
|
|
1
|
+
import{b as u,c as d}from"./chunk-EE4TZAZI.js";import{b as g}from"./chunk-HXOQUYG3.js";import{e as m,f as p,h as l}from"./chunk-GIXHG5FK.js";import{a as s}from"./chunk-ZLLER3HP.js";async function x(f,R){let r=s(e=>R?.logger?.info?.(e)??console.log(e),"log"),{evalTargetId:n}=f,i=`[cron_refine_cases] ${n}`,t=await m(`/api/eval-targets/${n}`);if(!(t.metadata?.autoRefineCases===!0))return r(`${i} not opted in (metadata.autoRefineCases)`),{skipped:"not-opted-in",reason:`"${t.name}" has not opted into automatic case refinement. Set metadata.autoRefineCases=true to let the loop cull cases that carry no treatment signal, or run \`rulemetric evals refine-cases ${n}\` by hand.`,targetName:t.name};let C=await m(`/api/eval-targets/${n}/judge-calibration`),a=u(C.caseDiscrimination);if(a.refused)return r(`${i} ${a.refused}: ${a.summary}`),{skipped:a.refused,reason:a.summary,targetName:t.name};r(`${i} ${a.summary}`);let o=await d(a,{generate:s(e=>g({content:t.content,name:t.name,feedback:e}),"generate"),createCase:s(e=>p(`/api/eval-targets/${n}/evals`,{name:e.name,prompt:e.prompt,expectations:e.expectations}),"createCase"),retireCase:s(async(e,y)=>{await l(`/api/eval-targets/${n}/evals/${e}`,{retire:!0,retiredReason:y})},"retireCase"),log:r});r(`${i} ${o.summary}`);let{skipped:c,...$}=o;return{...$,targetName:t.name,...c?{skipped:c,reason:o.summary}:{}}}s(x,"cronRefineCases");export{x as a};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{c as E,n as m}from"./chunk-
|
|
1
|
+
import{c as E,n as m}from"./chunk-GJHFIQVO.js";import{a as d}from"./chunk-GIXHG5FK.js";import{a as c}from"./chunk-ZLLER3HP.js";import*as p from"node:fs";import*as u from"node:path";import*as _ from"node:os";function T(){if(process.env.RULEMETRIC_API_KEY||process.env.RULEMETRIC_ACCESS_TOKEN)return;let s=u.join(_.homedir(),".config","rulemetric","env");C(s)||C(u.join(process.cwd(),".env.local"))}c(T,"ensureEnv");function C(s){try{let t=p.readFileSync(s,"utf-8");for(let n of t.split(`
|
|
2
2
|
`)){let e=n.trim();if(!e||e.startsWith("#"))continue;let o=e.indexOf("=");if(o<0)continue;let r=e.slice(0,o).trim(),i=e.slice(o+1).trim();process.env[r]||(process.env[r]=i)}return!!(process.env.RULEMETRIC_API_KEY||process.env.RULEMETRIC_ACCESS_TOKEN)}catch{return!1}}c(C,"loadEnvFile");T();async function I(s){let t={totalSessions:0,totalCalls:0,totalInputTokens:0,totalOutputTokens:0,totalCacheReadTokens:0,totalCacheWriteTokens:0,totalCostUSD:0,providers:{}},n=await m(s);t.providers={};for(let a of n)t.providers[a.provider]=(t.providers[a.provider]||0)+1;let e=new E,o=n.filter(a=>a.provider==="claude");for(let a of o)try{let h=p.readdirSync(a.path).filter(f=>f.endsWith(".jsonl"));t.totalSessions+=h.length;for(let f of h){let v=p.readFileSync(u.join(a.path,f),"utf-8"),R=e.parse(v);for(let l of R.events)l.tokenUsage&&(t.totalCalls++,t.totalInputTokens+=l.tokenUsage.input,t.totalOutputTokens+=l.tokenUsage.output,t.totalCacheReadTokens+=l.tokenUsage.cacheRead??0,t.totalCacheWriteTokens+=l.tokenUsage.cacheWrite??0)}}catch{}let r=15,i=75;return t.totalCostUSD=Math.round((t.totalInputTokens/1e6*r+t.totalOutputTokens/1e6*i+t.totalCacheReadTokens/1e6*(r*.1)+t.totalCacheWriteTokens/1e6*(r*1.25))*100)/100,t}c(I,"loadLocalStats");async function U(s){let t=process.env.RULEMETRIC_API_URL??d,n=process.env.RULEMETRIC_API_KEY,e=process.env.RULEMETRIC_ACCESS_TOKEN,o=n??e;if(!o)return null;let r=new URLSearchParams;s&&r.set("projectPath",s);try{let i=await fetch(`${t}/api/insights/compute?${r}`,{headers:{Authorization:`Bearer ${o}`},signal:AbortSignal.timeout(5e3)});return i.ok?await i.json():null}catch{return null}}c(U,"loadApiInsights");async function g(s){let t=process.env.RULEMETRIC_API_URL??d,n=process.env.RULEMETRIC_API_KEY??process.env.RULEMETRIC_ACCESS_TOKEN;if(!n)return null;let e=new URLSearchParams;s&&e.set("projectPath",s);try{let o=await fetch(`${t}/api/insights/linked-instructions?${e}`,{headers:{Authorization:`Bearer ${n}`},signal:AbortSignal.timeout(5e3)});return o.ok?await o.json():null}catch{return null}}c(g,"loadLinkedInstructions");export{I as a,U as b,g as c};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{g as E}from"./chunk-
|
|
1
|
+
import{g as E}from"./chunk-XCH4HPEZ.js";import{b,e as y,f as k,h as M}from"./chunk-GIXHG5FK.js";import{a as u}from"./chunk-ZLLER3HP.js";var v=50,I=24e3,P=3,R=3,C=40,N=4e3,x=new Set(["fact","decision","correction","convention"]),L=`You are distilling DURABLE, PROJECT-SPECIFIC knowledge from an AI coding session so a future agent working on the SAME project starts smarter.
|
|
2
2
|
|
|
3
3
|
Extract ONLY facts / decisions / corrections / conventions that will STILL be true and useful in FUTURE sessions \u2014 architecture facts, deliberate design decisions, corrections of a wrong approach, or project conventions.
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{f as p}from"./chunk-
|
|
1
|
+
import{f as p}from"./chunk-4GOXEEXZ.js";import{a as l}from"./chunk-ZLLER3HP.js";var k=[{name:"git-commit-helper",description:"Writes conventional commit messages and PR descriptions from a diff"},{name:"sql-query-optimizer",description:"Analyzes slow SQL queries and proposes indexes and rewrites"},{name:"i18n-string-extractor",description:"Finds hardcoded UI strings and extracts them into translation files"}],T=`You are an AI coding assistant with access to a set of optional skills. When a user request matches a skill's description, you invoke that skill before answering; when no skill applies, you answer directly without one. Descriptions are your ONLY information about each skill.
|
|
2
2
|
|
|
3
3
|
{{CATALOG}}
|
|
4
4
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as $}from"./chunk-
|
|
1
|
+
import{b as $}from"./chunk-KFNFLMUR.js";import{e as w,f as k}from"./chunk-GIXHG5FK.js";import{a as u}from"./chunk-ZLLER3HP.js";function h(e){if(e.length===0)return{mean:0,stddev:0,min:0,max:0};let n=e.reduce((s,a)=>s+a,0)/e.length,o=e.reduce((s,a)=>s+(a-n)**2,0)/e.length;return{mean:Math.round(n*1e3)/1e3,stddev:Math.round(Math.sqrt(o)*1e3)/1e3,min:Math.min(...e),max:Math.max(...e)}}u(h,"computeStats");var x="with_target",E="without_target";function _(e){let n=e.grading.summary?.pass_rate;return typeof n=="number"&&n>=1}u(_,"fullPass");function b(e){return e.grading.summary?.pass_rate!=null}u(b,"hasGrading");function R(e){let n=e.timing.total_tokens;return typeof n=="number"&&n>0?n:void 0}u(R,"tokensOf");function v(e){let n=e.timing.duration_ms;return typeof n=="number"&&!isNaN(n)?n/1e3:void 0}u(v,"secondsOf");function y(e,n){let o={};for(let s of e)(o[n(s)]??=[]).push(s);return o}u(y,"groupBy");function C(e,n){let o=y(e.filter(b),i=>i.evalId),s=y(n.filter(b),i=>i.evalId),a=u((i,l)=>i.runNumber-l.runNumber,"byRun"),t=[];for(let i of Object.keys(o)){let l=o[i].sort(a),d=(s[i]??[]).sort(a);for(let r=0;r<Math.min(l.length,d.length);r++){let c={withScore:_(l[r])?1:0,withoutScore:_(d[r])?1:0},f=R(l[r]),g=R(d[r]);f!=null&&g!=null&&(c.withCost=f,c.withoutCost=g);let p=v(l[r]),m=v(d[r]);p!=null&&m!=null&&(c.withLatency=p,c.withoutLatency=m),t.push(c)}}return t}u(C,"pairRunsByEval");function T(e){let n=e.filter(r=>r.status==="completed");if(n.length===0)return{runSummary:{},verdict:null,notes:["No completed runs found"],totalRuns:0};let o=y(n,r=>r.configuration),s={},a=[];for(let[r,c]of Object.entries(o)){let f=c.filter(b).map(m=>m.grading.summary.pass_rate),g=c.map(v).filter(m=>m!=null),p=c.map(R).filter(m=>m!=null);s[r]={},f.length>0&&(s[r].pass_rate=h(f)),g.length>0&&(s[r].time_seconds=h(g)),p.length>0&&(s[r].tokens=h(p))}let t=null,i=o[x]??[],l=o[E]??[],d=C(i,l);if(d.length>0){if(t=$(d),!t.sufficient)a.push(t.insufficientReason??"Insufficient data for a significance verdict.");else if(t.significant){let r=t.delta>=0?"improves":"reduces",c=t.pValue!=null?`, McNemar p=${t.pValue.toFixed(4)}`:"";a.push(`Target ${r} the pass rate by ${Math.abs(t.delta*100).toFixed(0)}% (95% CI ${(t.ci.lower*100).toFixed(0)}\u2013${(t.ci.upper*100).toFixed(0)}%, n=${t.nWith}${c}).`)}else a.push(`No significant effect on pass rate (95% CI ${(t.ci.lower*100).toFixed(0)}\u2013${(t.ci.upper*100).toFixed(0)}%, n=${t.nWith}).`);t.costDelta!=null&&Math.round(t.costDelta)!==0&&a.push(`Token cost delta: ${t.costDelta>=0?"+":""}${Math.round(t.costDelta)} tokens/task.`),t.latencyDelta!=null&&Math.abs(t.latencyDelta)>1&&a.push(`Target ${t.latencyDelta>0?"adds":"saves"} ${Math.abs(t.latencyDelta).toFixed(1)}s/task.`)}for(let r of Object.values(s))if(r.pass_rate&&r.pass_rate.stddev>.2){a.push(`High pass-rate variance (stddev=${r.pass_rate.stddev.toFixed(2)}) \u2014 results may be unreliable.`);break}return{runSummary:s,verdict:t,notes:a,totalRuns:n.length}}u(T,"summarizeRuns");async function S(e,n){let o=n?`&iteration=${n}`:"",s=100,a=[];for(let t=0;t<1e5;t+=s){let i=await w(`/api/eval-targets/${e}/runs?limit=${s}&offset=${t}&activeCasesOnly=1${o}`);if(a.push(...i),i.length<s)break}return T(a)}u(S,"aggregateBenchmark");async function B(e,n,o){return k(`/api/eval-targets/${e}/benchmarks`,{iteration:n,runSummary:o.runSummary,notes:o.notes})}u(B,"postBenchmark");export{T as a,S as b,B as c};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{h as E}from"./chunk-
|
|
1
|
+
import{h as E}from"./chunk-XCH4HPEZ.js";import{a as r}from"./chunk-ZLLER3HP.js";var g="<<<FILE-CONTENT-BEGIN>>>",m="<<<FILE-CONTENT-END>>>",b="<RATIONALE>",R="</RATIONALE>",u="<PROPOSED_INSTRUCTION>",p="</PROPOSED_INSTRUCTION>",d=.5,f=3;function y(e){let t=e.immutableSections.length>0?e.immutableSections.map(s=>` - ${s}`).join(`
|
|
2
2
|
`):" (none)",o=e.evidence.priorDecisions.length>0?["6. You have edited this file before. The attempts are listed below with"," how each was judged. Do not re-propose an edit that was MEASURED and"," rejected: it was replayed against this exact file and did not beat it,"," so measuring it again spends the same budget for the same answer. An"," attempt marked NOT MEASURED is different \u2014 the gate stopped it before"," it earned a verdict, so whether it would have helped is still unknown."]:[],n=e.currentContent.trim().length,i=` It is currently ${n} characters. Your proposal must stay between ${Math.ceil(n*d)} and ${Math.floor(n*f)} characters \u2014 outside that it is discarded unmeasured as a truncation or runaway rewrite.`;return["You are improving an AI coding assistant instruction file so that it scores","better on a fixed set of evaluation cases.","",`The file is a ${e.targetType} named "${e.targetName}".`,i,"","RULES",`0. The current file is EXACTLY the text between ${g} and`,` ${m} in the data message. Headings after the closing`," sentinel (underperforming cases, notes, prior attempts) are evidence",' ABOUT the file \u2014 they are not in the file, and "removing" one of them'," is not an edit. Do not include the sentinels in your output.","1. Return the COMPLETE new file, not a diff, not a patch, not a summary,"," and not an excerpt. Everything you omit will be DELETED from the file.","2. Preserve everything you are not deliberately changing, byte for byte.","3. Make a focused edit. You are one step in a measured loop: a small change"," that can be attributed beats a rewrite that cannot.","4. Do not edit these sections or anything nested under them \u2014 an edit that"," touches them is refused downstream and the whole proposal is wasted:",t,"5. Do not add meta-commentary about the evaluation, the loop, or this"," prompt to the file. The file is read by other agents as instructions.",...o,"","OUTPUT FORMAT \u2014 exactly this, with no text before or after:",b,"One or two sentences: what you changed and which evidence motivated it.",R,u,"The complete new file content.",p].join(`
|
|
3
3
|
`)}r(y,"buildProposerSystemPrompt");var h=r(e=>`${e>=0?"+":"-"}${Math.abs(e*100).toFixed(1)}pp`,"signedPp");function O(e){let t=/^\d{4}-\d{2}-\d{2}/.exec(e.at??"")?.[0]??"undated",o;if(e.measured){let i=e.measured;o=`MEASURED against this exact file and ${e.decision==="promote"?"ACCEPTED":"REJECTED"}: ${h(i.delta)} (CI ${h(i.ciLower)} to ${h(i.ciUpper)}, ${i.nPairs} paired cases)`}else o=`NOT MEASURED \u2014 the gate refused it, so its merit is still unknown: ${e.refusals.length>0?e.refusals.join("; "):"no reason recorded"}`;let n=[`- ${t} \u2014 ${o}`];return e.decision==="promote"&&n.push(e.applied?" The file WAS rewritten by this decision.":" Dry run: the file was NOT rewritten, so this edit is still available."),e.touched.length>0&&n.push(` Sections touched: ${e.touched.join(", ")}`),e.rationale.trim()!==""&&n.push(` You said at the time: ${e.rationale.trim()}`),n.join(`
|
|
4
4
|
`)}r(O,"describePriorDecision");function P(e){let t=e.evidence,o=["## CURRENT FILE CONTENT","","The file is EXACTLY the text between the two sentinel lines below \u2014","nothing before the first sentinel or after the second is part of it.","Everything after the closing sentinel is evidence ABOUT the file.","",g,e.currentContent,m,""];if(t.weakest.length>0){o.push("## CASES WHERE THIS FILE CURRENTLY UNDERPERFORMS","");for(let n of t.weakest)o.push(`- ${n.name}: passes ${(n.withPassRate*100).toFixed(0)}% with the file vs ${(n.withoutPassRate*100).toFixed(0)}% without it`);o.push("")}return t.nonDiscriminating.length>0&&o.push("## CASES THAT CARRY NO SIGNAL EITHER WAY","","These score the same with and without the file. Changing the file to chase","them is unlikely to move anything.","",...t.nonDiscriminating.map(n=>`- ${n}`),""),t.priorDecisions.length>0&&o.push("## WHAT YOU ALREADY PROPOSED FOR THIS FILE, AND HOW IT WAS JUDGED","","Newest first. Every attempt listed here was made against the file above,","byte for byte. Attempts against a different version of the file are not","shown, because a verdict earned by different text says nothing about this","one.","",...t.priorDecisions.map(O),""),t.notes.length>0&&o.push("## NOTES","",...t.notes.map(n=>`- ${n}`),""),o.join(`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as l}from"./chunk-
|
|
1
|
+
import{b as l}from"./chunk-KFNFLMUR.js";import{a as r}from"./chunk-ZLLER3HP.js";var u=r(n=>{let t=n.grading.summary?.pass_rate;return typeof t=="number"?t:null},"passRateOf"),a=r(n=>(u(n)??0)>=1,"fullPass");function f(n,t){let i=new Map(n.filter(e=>u(e)!=null).map(e=>[e.evalName,e])),o=[];for(let e of t){if(u(e)==null)continue;let s=i.get(e.evalName);s&&o.push({withScore:a(e)?1:0,withoutScore:a(s)?1:0})}return o}r(f,"pairVersionResults");function d(n,t){let i=f(n,t);return i.length===0?null:l(i,{baseline:"prior-version"})}r(d,"buildVersionVerdict");function m(n,t,i){let o=`v${i} vs v${t}`;if(!n.sufficient)return`${o}: ${n.insufficientReason??"insufficient data"} \u2014 no effect claimed`;let e=n.delta>=0?"+":"",s=`95% CI ${(n.ci.lower*100).toFixed(0)}\u2013${(n.ci.upper*100).toFixed(0)}%`,c=n.significant?"significant":"not significant";return`${o}: ${e}${(n.delta*100).toFixed(0)}% pass rate (${s}, n=${n.nWith} paired, ${c})`}r(m,"formatVersionVerdict");export{f as a,d as b,m as c};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as X}from"./chunk-HOQPVOMF.js";import{b as D}from"./chunk-GIRPEMTW.js";import{a as x}from"./chunk-MODXEGCU.js";import{e as J,g as B}from"./chunk-
|
|
1
|
+
import{c as X}from"./chunk-HOQPVOMF.js";import{b as D}from"./chunk-GIRPEMTW.js";import{a as x}from"./chunk-MODXEGCU.js";import{e as J,g as B}from"./chunk-XCH4HPEZ.js";import{e as w,f as R}from"./chunk-GIXHG5FK.js";import{c as H,d as U}from"./chunk-X6CF5KTW.js";import{a as u}from"./chunk-ZLLER3HP.js";import{readFileSync as q,realpathSync as V}from"node:fs";import y from"node:path";import A from"node:os";function Q(s){let n=y.resolve(s);if(n===y.resolve(A.homedir()))return!1;let a=y.parse(n).root;if(n===a)return!1;try{let o=V(A.tmpdir());if(V(n)===o)return!1}catch{}return!0}u(Q,"isScorableProjectPath");var Z=5,ee=Number(process.env.RULEMETRIC_MAX_SUGGESTION_PROJECTS??10),te=48,ne=.5,O=400,oe=3,re=.6,se=1;function ae(s){let n=s.bloated??[],a=new Set([...s.harmful.map(o=>o.id),...s.candidates.map(o=>o.id)]);return n.filter(o=>!a.has(o.id)).slice(0,se).map(o=>({instructionId:o.id,estimatedTokens:o.estimatedTokens,topProjectId:o.topProjectId??null,score:.55,reason:`Costs ~${o.estimatedTokens} tokens every session and measures neutral across ${o.exposures} exposed session(s) \u2014 enough data to detect an effect, and none found. Consider shortening "${o.name}" rather than removing it.`+(o.containsSafetyLanguage?" CAUTION: it contains guardrail language (destructive-command or credential rules) \u2014 preserve those lines when shortening.":"")}))}u(ae,"buildTrimProposals");async function ie(s,n,a){let o=[],i=0;for(let d of s)try{await a("/api/instruction-experiments",{instructionId:d.instructionId,projectPath:n,source:"groom"}),i++}catch(g){let m=g instanceof Error?g.message:String(g);o.push({...d,reason:`${d.reason} (not measurable by withholding: ${m})`})}return{nominated:i,unmeasurable:o}}u(ie,"nominateRemovals");function ce(s){let n=[];for(let o of s.harmful){let i=o.verdict.delta;n.push({instructionId:o.id,score:Math.min(.95,.75+Math.abs(i)),topProjectId:o.topProjectId??null,reason:`Measured harmful: sessions using "${o.name}" scored ${(i*100).toFixed(1)}pp worse across ${o.exposures} exposed session(s). Observational \u2014 review before archiving.`})}let a=new Set(s.harmful.map(o=>o.id));for(let o of s.candidates)a.has(o.id)||n.push({instructionId:o.id,score:re,topProjectId:o.topProjectId??null,reason:`Unused: "${o.name}" is ${o.reason} (${o.totalExposures} lifetime exposure(s)) but still costs context budget every session.`});return n.slice(0,oe)}u(ce,"buildRemovalProposals");function le(){let s=y.join(A.homedir(),".config","rulemetric","skills-registry.json");try{let n=q(s,"utf-8"),a=JSON.parse(n),o=new Date(a.generatedAt).getTime();return Number.isNaN(o)?"unknown":Date.now()-o>te*60*60*1e3?"stale":"fresh"}catch{return"unknown"}}u(le,"observeSkillsRegistry");var Re=u(async(s,n)=>{let a=J(),o=a!=="none";o?n.logger.info(`Scoring backend: ${a}`):n.logger.warn("No LLM backend available (claude CLI missing and ANTHROPIC_API_KEY unset); skipping relevance scoring. Removal/trim proposals still run \u2014 they need no LLM.");let i;try{i=(await w("/api/sessions/project-paths?limit="+ee)).projectPaths}catch(e){n.logger.warn(`Failed to fetch project paths: ${e instanceof Error?e.message:String(e)}`);return}if(i.length===0){n.logger.info("No recent project paths; nothing to score");return}let d=new Map;try{let e=await w("/api/projects?limit=200");for(let t of e.projects??[])t.primaryCheckoutPath&&d.set(x(t.primaryCheckoutPath),t.id)}catch(e){n.logger.warn(`Failed to fetch projects for id resolution: ${e instanceof Error?e.message:String(e)}`)}let g=new Map;try{let e=await w(`/api/catalog?limit=200&proposable=1&contentPreview=${O}`);for(let t of e)g.set(t.id,{id:t.id,name:t.name,description:t.description??"",tags:t.tags??[],contentPreview:(t.contentPreview??"").slice(0,O)})}catch(e){n.logger.warn(`Failed to fetch catalog: ${e instanceof Error?e.message:String(e)}`)}try{let e=await w("/api/instructions?limit=100");for(let t of e.instructions??[])g.has(t.id)||g.set(t.id,{id:t.id,name:t.name,description:t.description??"",tags:t.tags??[],contentPreview:(t.content??"").slice(0,O)})}catch(e){n.logger.warn(`Failed to fetch personal instructions: ${e instanceof Error?e.message:String(e)}`)}let m=[],p=[];try{let e=await w("/api/insights/groom-candidates");if(!e.captureHealthy)n.logger.info(`Grooming paused: ${e.reason??"capture unhealthy"}`);else{m=ce(e),p=ae(e);let t=e.safetyGuarded+e.harmfulSafetyGuarded;n.logger.info(`Removal proposals: ${m.length} (${e.harmful.length} measured-harmful, ${e.candidates.length} never-used, ${t} withheld by the safety allowlist); trim proposals: ${p.length} (${(e.bloated??[]).length} measured-neutral and expensive, ${e.trimSafetyFlagged??0} flagged as containing guardrail language)`)}}catch(e){n.logger.warn(`Failed to fetch groom candidates: ${e instanceof Error?e.message:String(e)}`)}let b=[...g.values()];if(b.length===0&&m.length===0&&p.length===0){n.logger.info("No candidate instructions and nothing to retire; nothing to score");return}n.logger.info(`Scoring ${b.length} candidates across ${i.length} project(s)`);let M=0,l=null,I=new Set;for(let e of i)try{let t=x(e);if(!Q(t)){n.logger.info(`Skipping ${t}: not a project directory (home/root)`);continue}let f=D(t),k=o&&f.length>0;f.length===0&&n.logger.info(`${t}: insufficient language signals; removal/trim only`);let v=X(t),z={name:y.basename(t),description:v.description,languages:f,topics:v.topics,dependencies:v.dependencies},E=k?U(b):[];k&&n.logger.info(`Scoring ${b.length} candidates for ${t} in ${E.length} batch(es)`);let C=[],$=0;for(let r of E)try{let c=await B(H(z,r),"",4096);if(!c){$++;continue}let T=c.recommendations??[];for(let P of T)typeof P.instructionId=="string"&&typeof P.score=="number"&&typeof P.reason=="string"&&C.push({instructionId:P.instructionId,score:P.score,reason:P.reason})}catch(c){$++,n.logger.warn(`Batch failed for ${t}: ${c instanceof Error?c.message:String(c)}`)}$>0&&n.logger.warn(`${$}/${E.length} batch(es) failed for ${t} (backend ${a}); suggestions are partial`),k&&C.length===0&&n.logger.warn(`No usable LLM output for ${t} (backend ${a})`);let K=C.filter(r=>r.score>=ne).sort((r,c)=>c.score-r.score).slice(0,Z),_=d.get(t),W=l===null||l===t;l===null&&(l=t);let N=u(r=>r.topProjectId?r.topProjectId===_:W,"placeHere"),F=m.filter(N),{nominated:L,unmeasurable:G}=await ie(F,t,R);L>0&&n.logger.info(`${t}: ${L} removal candidate(s) nominated for randomised withholding instead of the feed`);let h=[...K.map(r=>({instructionId:r.instructionId,score:r.score,reason:r.reason,kind:"add"})),...G.map(({topProjectId:r,...c})=>({...c,kind:"remove"})),...p.filter(N).map(({estimatedTokens:r,topProjectId:c,...T})=>({...T,kind:"trim"}))];if(h.length===0){n.logger.info(`Nothing to suggest for ${t}`);continue}await R("/api/instruction-suggestions/batch-upsert",{projectPath:t,..._?{projectId:_}:{},suggestions:h}),n.logger.info(`${t}: ${h.filter(r=>r.kind==="add").length} add + ${h.filter(r=>r.kind==="remove").length} remove + ${h.filter(r=>r.kind==="trim").length} trim`);for(let r of h)r.kind!=="add"&&I.add(r.instructionId);let Y=new Set(G.map(r=>r.instructionId));for(let r of F)Y.has(r.instructionId)||I.add(r.instructionId);M++}catch(t){n.logger.warn(`Failed to score ${e}: ${t instanceof Error?t.message:String(t)}`)}let j=[...m.filter(e=>!I.has(e.instructionId)),...p.filter(e=>!I.has(e.instructionId)).map(({estimatedTokens:e,...t})=>t)];if(j.length>0&&l)try{let e=new Set(p.map(t=>t.instructionId));await R("/api/instruction-suggestions/batch-upsert",{projectPath:l,...d.get(l)?{projectId:d.get(l)}:{},suggestions:j.map(({topProjectId:t,...f})=>({...f,kind:e.has(f.instructionId)?"trim":"remove"}))}),n.logger.info(`Orphan sweep: ${j.length} proposal(s) whose project was not scored this run placed on ${l}`)}catch(e){n.logger.warn(`Orphan sweep failed: ${e instanceof Error?e.message:String(e)}`)}let S=le();if(S==="unknown")n.logger.warn("Skills registry unreadable or has no usable generatedAt; leaving suggestion staleness unchanged");else try{await R("/api/instruction-suggestions/mark-stale",{stale:S==="stale"}),S==="stale"?n.logger.warn("Skills registry is stale (>48h); marked catalog-skill suggestions stale"):n.logger.info("Skills registry is fresh; cleared staleness on catalog-skill suggestions")}catch{}n.logger.info(`Done: scored ${M}/${i.length} projects`)},"cronSuggestInstructions");export{Q as a,ae as b,ie as c,ce as d,Re as e};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{x as w}from"./chunk-
|
|
1
|
+
import{x as w}from"./chunk-GJHFIQVO.js";import{a as m}from"./chunk-N7ODX6PO.js";import{a as s}from"./chunk-ZLLER3HP.js";import{spawn as g}from"node:child_process";import d from"node:fs";import b from"node:path";function c(e,t){return new Promise((r,n)=>{let o=g("git",e,{cwd:t,stdio:["ignore","pipe","pipe"],env:m()}),i="",f="";o.stdout.on("data",a=>{i+=a.toString()}),o.stderr.on("data",a=>{f+=a.toString()}),o.on("error",a=>n(new Error(`git ${e.join(" ")} failed to spawn: ${a.message}`))),o.on("close",a=>{a===0?r({code:a,stdout:i,stderr:f}):n(new Error(`git ${e.join(" ")} exited ${a}: ${f.trim()||i.trim()}`))})})}s(c,"runGit");async function k(e,t){if(!t||!t.trim())throw new Error('invalid branch name "": branch must be a non-empty git refname');if(t.startsWith("-"))throw new Error(`invalid branch name "${t}": must not start with "-" (git would parse it as an option)`);if(/\s/.test(t))throw new Error(`invalid branch name "${t}": must not contain whitespace`);try{await c(["check-ref-format","--branch",t],e)}catch{throw new Error(`invalid branch name "${t}": not a valid git refname`)}}s(k,"assertValidBranch");function h(e){let t=b.resolve(e);try{return d.realpathSync(t)}catch{return t}}s(h,"canonical");function y(e){let t=[],r=null;for(let n of e.split(`
|
|
2
2
|
`))n.startsWith("worktree ")?(r&&t.push(r),r={path:n.slice(9).trim()}):n.startsWith("branch ")&&r&&(r.branch=n.slice(7).trim().replace(/^refs\/heads\//,""));return r&&t.push(r),t}s(y,"parseWorktreeList");async function v(e,t){try{return await c(["show-ref","--verify","--quiet",`refs/heads/${t}`],e),!0}catch{return!1}}s(v,"branchExists");async function B(e){let{repoRoot:t,branch:r,baseRef:n,allowExistingBranch:o=!1}=e;await k(t,r);let i=w({repoRoot:t,branch:r,basePath:e.basePath}),f=await c(["worktree","list","--porcelain"],t),a=y(f.stdout),p=a.find(u=>u.branch===r);if(p)return{path:h(p.path),branch:r,created:!1};let l=a.find(u=>h(u.path)===i);if(l)return{path:h(l.path),branch:l.branch??r,created:!1};if(await v(t,r)){if(!o)throw new Error(`branch "${r}" already exists with no worktree; refusing to clobber (pass allowExistingBranch:true to attach a worktree onto it)`);return await c(["worktree","add",i,r],t),{path:h(i),branch:r,created:!0}}return await c(["worktree","add",i,"-b",r,n],t),{path:h(i),branch:r,created:!0}}s(B,"ensureWorktree");async function S(e){let{repoRoot:t,worktreePath:r}=e;if(!d.existsSync(r))return{removed:!1,reason:"absent"};let n=!1;try{n=(await c(["status","--porcelain"],r)).stdout.trim().length>0}catch{n=!1}if(n)return{removed:!1,reason:"dirty"};try{return await c(["worktree","remove",r],t),{removed:!0}}catch(o){let i=o instanceof Error?o.message:String(o);if(/not a working tree|No such file or directory|not a valid path|is not a working tree/i.test(i))return{removed:!1,reason:"absent"};throw o}}s(S,"removeWorktree");export{c as a,B as b,S as c};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as m}from"./chunk-
|
|
1
|
+
import{b as m}from"./chunk-OAETRNTE.js";import{a as g}from"./chunk-ZLLER3HP.js";var p=5;function b(t){let r=g((e,f)=>({retire:[],survivingCases:0,replacementsRequired:!1,refused:e,summary:f}),"none");if(!t||t.cases.length===0&&t.unpairedCases.length===0)return r("no-discrimination-data","No case-discrimination data yet \u2014 the target needs runs in BOTH cohorts before any case can be judged dead.");let c=[...t.cases.filter(e=>!e.discriminating).map(e=>({evalId:e.evalId,name:e.name,feedback:{name:e.name,withPassRate:e.withPassRate,withoutPassRate:e.withoutPassRate,reason:e.note}})),...t.unpairedCases.map(e=>({evalId:e.evalId,name:e.name,feedback:{name:e.name,withPassRate:e.withPassRate??0,withoutPassRate:e.withoutPassRate,reason:"runs in only one cohort (no with-vs-without comparison possible)"}}))];if(c.length===0)return r("all-discriminating","Every case discriminates \u2014 nothing to retire.");let s=new Map(t.cases.map(e=>[e.evalId,e.separation])),o=[...c].sort((e,f)=>(s.get(e.evalId)??-1)-(s.get(f.evalId)??-1)).slice(0,p),u=c.length-o.length,d=t.total+t.unpaired,l=d-o.length,i=l<m,n=`${o.length} of ${d} live case(s) carry no treatment signal`+(u>0?` (${u} more over the ${p}-per-run cap)`:"")+(i?`; retiring them leaves ${l}, below the ${m}-case evolution floor, so replacements must be generated first`:"");return{retire:o,survivingCases:l,replacementsRequired:i,refused:null,summary:n}}g(b,"planCaseRefinement");async function v(t,r){let h=r.log??(()=>{}),c=g((n,e)=>({retired:0,generated:0,skipped:n,summary:e,retiredNames:[],generatedNames:[]}),"empty");if(t.refused)return c(t.refused,t.summary);let s=await r.generate(t.retire.map(n=>n.feedback)),a=[];for(let n of s??[]){let e=await r.createCase(n);a.push(e.name),h(` + ${e.name} (${e.id})`)}let o=t.survivingCases+t.retire.length+a.length,u=Math.max(0,o-m),d=t.retire.slice(0,Math.min(t.retire.length,u)),l=t.retire.length-d.length;if(d.length===0)return{retired:0,generated:a.length,skipped:s===null?"no-llm-backend":"no-replacements-generated",summary:`${t.summary}. `+(s===null?"No local LLM backend available, so nothing was retired":`The generator produced ${a.length} usable replacement(s), not enough to retire anything`)+` \u2014 dropping below the ${m}-case floor would silently disenrol the target from the nightly loop.`,retiredNames:[],generatedNames:a};let i=[];for(let n of d)await r.retireCase(n.evalId,n.feedback.reason),i.push(n.name),h(` retired ${n.name}`);return{retired:i.length,generated:a.length,skipped:null,summary:`Retired ${i.length} non-discriminating case(s), added ${a.length} replacement(s)`+(l>0?`; held ${l} back to stay at the ${m}-case floor (they remain condemned and will be retired once replacements exist)`:"")+". The replacements have no runs yet \u2014 the next autorun batch builds their depth.",retiredNames:i,generatedNames:a}}g(v,"executeCaseRefinement");export{p as a,b,v as c};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as w}from"./chunk-SWSOEYC7.js";import{a as C}from"./chunk-KGURGIZ2.js";import{a as M}from"./chunk-
|
|
1
|
+
import{f as w}from"./chunk-SWSOEYC7.js";import{a as C}from"./chunk-KGURGIZ2.js";import{a as M}from"./chunk-FG343JM3.js";import{a as x,f as b}from"./chunk-4GOXEEXZ.js";import{d as k}from"./chunk-GPBN4ROE.js";import{f as v}from"./chunk-GIXHG5FK.js";import{f as y}from"./chunk-XQYAVSUQ.js";import{a as m}from"./chunk-ZLLER3HP.js";function $(t,e={}){let i=e.engine??(e.model||t.engine==="pi"?"claude":t.engine);return{engine:i,model:e.model??(i===t.engine?t.model:void 0)}}m($,"selectEvalJudge");function _(t){let e=$(t.actor,t.pin??{});if(!t.available.includes(e.engine))throw new Error(`configured grader unavailable: ${e.engine}`);if(e.engine==="codex"&&!e.model?.trim())throw new Error("Codex grader requires a model pin");return e}m(_,"resolveMeasurementJudge");function A(t,e){let i=t.measurement?y.parse(t.measurement):void 0,r=i?.engine??x(t.engine),o=i?i.model??void 0:t.model;if(!e){let s=k();e=[...s.claudeBin?["claude"]:[],...s.codexBin?["codex"]:[],...s.piBin?["pi"]:[]]}if(!e.includes(r))throw new Error(`configured actor unavailable: ${r}`);let u=t.skipGrading?$({engine:r,model:o}):_({actor:{engine:r,model:o},pin:t.graderEngine||t.graderModel?{engine:t.graderEngine,model:t.graderModel}:null,available:e});return{engine:r,model:o,graderEngine:u.engine,graderModel:u.model,...i?{measurement:i}:{}}}m(A,"resolveMeasurementJob");async function R(t,e,i=()=>{}){let{eval_:r,configuration:o,targetContent:u,runNumber:s}=t;i(`[${o}] ${r.name} run#${s} \u2014 executing...`);let l=x(e.engine),g=w({targetType:e.targetType,targetContent:u,targetName:e.targetName,engine:l}),c={...e.executionKey?{executionKey:e.executionKey}:{},deliveryRegime:`${e.targetType??"prompt"}:${l}:${g.methodology}`,...e.measurement?{measurement:e.measurement}:{},methodology:g.methodology,delivery:g.delivery,isolated:g.isWorktree,...e.candidateContentHash?{candidateContentHash:e.candidateContentHash}:{},...g.leakedFiles.length?{leakedFiles:g.leakedFiles}:{}};g.isWorktree||i(`[${o}] ${r.name} run#${s} \u2014 \u26A0 no git worktree; running without repo context`),g.leakedFiles.length&&i(`[${o}] ${r.name} run#${s} \u2014 \u26A0 CONTAMINATED: ${g.leakedFiles.join(", ")} survived the strip`);try{let n=await b({prompt:r.prompt,targetContent:g.systemPrompt,workDir:g.workDir,timeout:e.timeout,model:e.model,engine:l});if(n.error){let d=C(n.error);return i(`[${o}] ${r.name} run#${s} \u2014 FAILED (${d.kind}): ${n.error}`),{evalId:r.id,evalTargetId:e.targetId,evalTargetVersion:e.targetVersion,configuration:o,runNumber:s,iteration:e.iteration,status:"failed",outputs:{error:n.error,failureKind:d.kind,failureClass:d.class,...c,engine:n.engine??l,model:n.model??null,...n.provider?{provider:n.provider}:{},...n.costUsd!=null?{costUsd:n.costUsd}:{}},timing:{duration_ms:n.durationMs,total_tokens:n.totalTokens},grading:{},failure:d}}i(`[${o}] ${r.name} run#${s} \u2014 completed in ${(n.durationMs/1e3).toFixed(1)}s`);let a={};if(!e.skipGrading&&r.expectations.length>0){i(`[${o}] ${r.name} run#${s} \u2014 grading...`);let d=await M({prompt:r.prompt,output:n.output,expectations:r.expectations,...$({engine:l,model:e.model},{engine:e.graderEngine,model:e.graderModel}),timeout:e.timeout});a=d,i(`[${o}] ${r.name} run#${s} \u2014 grading done: pass_rate=${d.summary.pass_rate==null?"n/a (all assertions errored)":`${(d.summary.pass_rate*100).toFixed(0)}%`}`)}return{evalId:r.id,evalTargetId:e.targetId,evalTargetVersion:e.targetVersion,configuration:o,runNumber:s,iteration:e.iteration,status:"completed",outputs:{transcript:n.output,...c,engine:n.engine??l,...n.provider?{provider:n.provider}:{},model:n.model??null,...n.costUsd!=null?{costUsd:n.costUsd}:{}},timing:{duration_ms:n.durationMs,total_tokens:n.totalTokens,total_duration_seconds:n.durationMs/1e3},grading:a}}finally{g.cleanup()}}m(R,"executeAndGradeCase");async function B(t){let{cases:e,targetContent:i,concurrency:r,runNumber:o,opts:u,skipBaseline:s,onLog:l=m(()=>{},"onLog")}=t,g=s?["with_target"]:["with_target","without_target"],c=[];for(let a of e)for(let d of g)c.push({eval_:a,configuration:d,targetContent:d==="with_target"?i:void 0,runNumber:o});let n=[];for(let a=0;a<c.length;a+=Math.max(1,r)){let d=c.slice(a,a+Math.max(1,r)),h=await Promise.all(d.map(f=>R(f,u,l)));n.push(...h);let p=[];for(let f of h)try{await v("/api/eval-runs",f)}catch(E){p.push(E instanceof Error?E.message:String(E))}if(p.length)throw new Error(`Could not persist ${p.length} eval run(s); stopped further execution: ${p.join("; ")}`)}try{await v(`/api/eval-targets/${u.targetId}/label-state`,{})}catch(a){l(` \u26A0 label-state notification skipped: ${a instanceof Error?a.message:String(a)}`)}return{completed:n.filter(a=>a.status==="completed").length,failed:n.filter(a=>a.status==="failed").length,results:n}}m(B,"runBatchAndPost");export{$ as a,_ as b,A as c,R as d,B as e};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as w,b as S}from"./chunk-CDY7TQFZ.js";import{f as A}from"./chunk-
|
|
1
|
+
import{a as w,b as S}from"./chunk-CDY7TQFZ.js";import{f as A}from"./chunk-4GOXEEXZ.js";import{d as G}from"./chunk-JNLDISBA.js";import{a as p}from"./chunk-ZLLER3HP.js";var j=`You are a rigorous eval grader. Your job is to evaluate whether an AI assistant's output meets a set of expectations.
|
|
2
2
|
|
|
3
3
|
You will receive:
|
|
4
4
|
1. The original prompt that was given to the AI
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import{a as l,b as Lt}from"./chunk-ZLLER3HP.js";var Xe=["claude_code","cursor","vscode_copilot","copilot_agent","rulemetric_mcp","codex","pi","opencode","antigravity"],Ye=["user_message","assistant_message","assistant_response","tool_call","tool_result","thinking","error"];var Jt=new Set(["","unknown","<synthetic>"]);function Gt(e){if(typeof e!="string")return null;let t=e.trim();return Jt.has(t)?null:t}l(Gt,"resolveEventModel");var C=class{static{l(this,"ClaudeCodeAdapter")}tool="claude_code";parse(t){let n=t.split(`
|
|
2
|
+
`).filter(c=>c.trim()),o=[];for(let c of n)try{o.push(JSON.parse(c))}catch{}let s=o.filter(c=>c.type==="user"||c.type==="assistant"),r=null,i=null,u={},a=o.find(c=>c.type==="user");a&&(r=a.cwd??null,i=a.gitBranch??null,a.version&&(u.claudeCodeVersion=a.version),a.sessionId&&(u.sessionId=a.sessionId));let p=o.find(c=>c.type==="assistant");p?.message?.model&&(u.model=p.message.model);let m=[],f=0;for(let c of s){let y=c.timestamp??new Date().toISOString();if(c.type==="user"){let h=c.message?.content;if(typeof h=="string")m.push({sequence:f++,eventType:"user_message",content:h,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:y,metadata:{}});else if(Array.isArray(h))for(let _ of h)_.type==="tool_result"&&m.push({sequence:f++,eventType:"tool_result",content:typeof _.content=="string"?_.content:JSON.stringify(_.content),toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:y,metadata:{toolUseId:_.tool_use_id}})}else if(c.type==="assistant"){let h=Array.isArray(c.message?.content)?c.message.content:[],_=c.message?.usage,I=_?{input:_.input_tokens??0,output:_.output_tokens??0,cacheRead:_.cache_read_input_tokens??0,cacheWrite:_.cache_creation_input_tokens??0}:null,T={};c.message?.model&&(T.model=c.message.model);let x=Gt(c.message?.model);c.message?.stop_reason&&(T.stopReason=c.message.stop_reason),c.requestId&&(T.requestId=c.requestId),_?.service_tier&&(T.serviceTier=_.service_tier),_?.speed&&(T.speed=_.speed),_?.cache_creation&&(T.cacheCreationDetail=_.cache_creation),_?.server_tool_use&&(T.serverToolUse=_.server_tool_use);for(let S of h)S.type==="text"?m.push({sequence:f++,eventType:"assistant_message",content:S.text??"",toolName:null,toolInput:null,toolOutput:null,tokenUsage:I,model:x,timestamp:y,metadata:T}):S.type==="thinking"?m.push({sequence:f++,eventType:"thinking",content:S.thinking??"",toolName:null,toolInput:null,toolOutput:null,tokenUsage:I,model:x,timestamp:y,metadata:T}):S.type==="tool_use"&&m.push({sequence:f++,eventType:"tool_call",content:null,toolName:S.name??"unknown",toolInput:S.input??null,toolOutput:null,tokenUsage:I,model:x,timestamp:y,metadata:{...T,toolUseId:S.id}})}}let d=m.map(c=>c.timestamp).sort(),g=new Date().toISOString();return{tool:"claude_code",projectPath:r,gitBranch:i,startedAt:d[0]??g,endedAt:d[d.length-1]??null,events:m,metadata:u}}};var A=class{static{l(this,"CursorAdapter")}tool="cursor";parse(t){let n=Lt("better-sqlite3"),o=new n(t,{readonly:!0});try{let s=o.prepare("SELECT value FROM ItemTable WHERE key = 'composer.composerData'").get();return s?this.parseComposerJson(s.value):this.emptySession()}finally{o.close()}}parseComposerJson(t){let n;try{n=JSON.parse(t)}catch{return this.emptySession()}let o=Object.values(n.allComposers??{});if(o.length===0)return this.emptySession();let s=o.sort((p,m)=>{let f=p.createdAt?new Date(p.createdAt).getTime():0;return(m.createdAt?new Date(m.createdAt).getTime():0)-f})[0],r=s.conversation??[],i=[];for(let p=0;p<r.length;p++){let m=r[p],f=m.createdAt??new Date().toISOString();i.push({sequence:p,eventType:m.type===1?"user_message":"assistant_message",content:m.text,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:f,metadata:{}})}let u=i.map(p=>p.timestamp).sort(),a=new Date().toISOString();return{tool:"cursor",projectPath:null,gitBranch:null,startedAt:u[0]??a,endedAt:u[u.length-1]??null,events:i,metadata:{composerId:s.composerId}}}emptySession(){return{tool:"cursor",projectPath:null,gitBranch:null,startedAt:new Date().toISOString(),endedAt:null,events:[],metadata:{}}}};var N=class{static{l(this,"VSCodeCopilotAdapter")}tool="vscode_copilot";parse(t){let n;try{n=JSON.parse(t)}catch{return this.emptySession()}let o=n.requests??[],s=[],r=0;for(let a of o){let p=a.timestamp?new Date(a.timestamp).toISOString():new Date().toISOString();if(s.push({sequence:r++,eventType:"user_message",content:a.message,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:p,metadata:{}}),a.response){let m=a.response.timestamp?new Date(a.response.timestamp).toISOString():p;s.push({sequence:r++,eventType:"assistant_message",content:a.response.message,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:m,metadata:{}})}}let i=s.map(a=>a.timestamp).sort(),u=new Date().toISOString();return{tool:"vscode_copilot",projectPath:null,gitBranch:null,startedAt:i[0]??u,endedAt:i[i.length-1]??null,events:s,metadata:{...n.requesterUsername&&{username:n.requesterUsername},...n.customTitle&&{title:n.customTitle}}}}emptySession(){return{tool:"vscode_copilot",projectPath:null,gitBranch:null,startedAt:new Date().toISOString(),endedAt:null,events:[],metadata:{}}}};var P=class{static{l(this,"CopilotAgentAdapter")}tool="copilot_agent";parse(t){let n;try{n=JSON.parse(t)}catch{return this.emptySession()}let o=n.requests??[],s=[],r=0;for(let a of o){let p=a.timestamp?new Date(a.timestamp).toISOString():new Date().toISOString();if(s.push({sequence:r++,eventType:"user_message",content:a.message,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:p,metadata:{}}),a.toolCalls)for(let m of a.toolCalls){let f=m.timestamp?new Date(m.timestamp).toISOString():p;s.push({sequence:r++,eventType:"tool_call",content:null,toolName:m.name??"unknown",toolInput:m.input??null,toolOutput:m.output??null,tokenUsage:null,timestamp:f,metadata:{}})}if(a.response){let m=a.response.timestamp?new Date(a.response.timestamp).toISOString():p;s.push({sequence:r++,eventType:"assistant_message",content:a.response.message,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:m,metadata:{}})}}let i=s.map(a=>a.timestamp).sort(),u=new Date().toISOString();return{tool:"copilot_agent",projectPath:null,gitBranch:null,startedAt:i[0]??u,endedAt:i[i.length-1]??null,events:s,metadata:{...n.requesterUsername&&{username:n.requesterUsername},...n.customTitle&&{title:n.customTitle},...n.agentMode!=null&&{agentMode:n.agentMode}}}}emptySession(){return{tool:"copilot_agent",projectPath:null,gitBranch:null,startedAt:new Date().toISOString(),endedAt:null,events:[],metadata:{}}}};var D=class{static{l(this,"RuleMetricMcpAdapter")}tool="rulemetric_mcp";parse(t){let n;try{n=JSON.parse(t)}catch{return this.emptySession()}let s=(n.events??[]).map((i,u)=>({sequence:i.sequence??u,eventType:this.normalizeEventType(i.eventType),content:i.content??null,toolName:i.toolName??null,toolInput:i.toolInput??null,toolOutput:i.toolOutput??null,tokenUsage:i.tokenUsage??null,timestamp:i.timestamp??new Date().toISOString(),metadata:i.metadata??{}})),r=new Date().toISOString();return{tool:"rulemetric_mcp",projectPath:n.projectPath??null,gitBranch:n.gitBranch??null,startedAt:n.startedAt??s[0]?.timestamp??r,endedAt:n.endedAt??s[s.length-1]?.timestamp??null,events:s,metadata:n.metadata??{}}}normalizeEventType(t){return t&&["user_message","assistant_message","tool_call","tool_result","thinking","error"].includes(t)?t:"assistant_message"}emptySession(){return{tool:"rulemetric_mcp",projectPath:null,gitBranch:null,startedAt:new Date().toISOString(),endedAt:null,events:[],metadata:{}}}};function Bt(e){try{return JSON.parse(e)}catch{return e}}l(Bt,"safeJsonParse");function tt(e,t){return Array.isArray(e)?e.filter(n=>n.type&&t.includes(n.type)).map(n=>n.text??"").filter(Boolean).join(`
|
|
3
|
+
|
|
4
|
+
`):""}l(tt,"textFromBlocks");function Ft(e){if(!e)return null;let t=e.cached_input_tokens??0,n=Math.max(0,(e.input_tokens??0)-t),o=(e.output_tokens??0)+(e.reasoning_output_tokens??0);return n===0&&o===0&&t===0?null:{input:n,output:o,cacheRead:t,cacheWrite:0}}l(Ft,"tokenUsageFromCodex");function Ht(e){if(!e)return new Date().toISOString();let t=new Date(e);return Number.isFinite(t.getTime())?t.toISOString():new Date().toISOString()}l(Ht,"normalizeTimestamp");function et(){return{sequence:0,model:null,prevCumulativeTotal:0,callNames:{}}}l(et,"freshCodexState");var b=class{static{l(this,"CodexAdapter")}tool="codex";parse(t){let n=et(),{events:o,projectPath:s,gitBranch:r,metadata:i}=this.parseLines(t,n),u=o.map(p=>p.timestamp).sort(),a=new Date().toISOString();return{tool:"codex",projectPath:s,gitBranch:r,startedAt:u[0]??a,endedAt:u[u.length-1]??null,events:o,metadata:i}}parseAppend(t,n){let o={...n,callNames:{...n.callNames}},{events:s}=this.parseLines(t,o);return{events:s,state:o}}parseLines(t,n){let o=t.split(`
|
|
5
|
+
`).filter(m=>m.trim()),s=[],r={},i=n.callNames,u=null,a=null,p=null;for(let m of o){let f;try{f=JSON.parse(m)}catch{continue}let d=f.payload;if(!d)continue;let g=Ht(f.timestamp);if(f.type==="session_meta"){p=d.session_id??d.id??p,u=d.cwd??u,d.git_branch&&(a=d.git_branch),d.model&&(n.model=d.model),r.sessionId=p,r.codexSessionId=p,r.originator=d.originator,r.source=d.source,r.modelProvider=d.model_provider,r.codexCliVersion=d.cli_version;continue}if(f.type==="turn_context"){u=d.cwd??u,d.model&&(n.model=d.model,r.model=d.model);continue}if(f.type==="response_item"&&d.type==="message"){if(d.role==="user"){let c=tt(d.content,["input_text"]);if(!c)continue;s.push({sequence:n.sequence++,eventType:"user_message",content:c,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:g,metadata:{}})}else if(d.role==="assistant"){let c=tt(d.content,["output_text"]);if(!c)continue;s.push({sequence:n.sequence++,eventType:"assistant_message",content:c,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,model:n.model,timestamp:g,metadata:n.model?{model:n.model}:{}})}continue}if(f.type==="response_item"&&d.type==="function_call"){let c=d.name??"unknown";d.call_id&&(i[d.call_id]=c);let y=typeof d.arguments=="string"?Bt(d.arguments):{};s.push({sequence:n.sequence++,eventType:"tool_call",content:null,toolName:c,toolInput:y&&typeof y=="object"&&!Array.isArray(y)?y:{arguments:y},toolOutput:null,tokenUsage:null,model:n.model,timestamp:g,metadata:{callId:d.call_id}});continue}if(f.type==="response_item"&&d.type==="function_call_output"){let c=d.call_id?i[d.call_id]??null:null;s.push({sequence:n.sequence++,eventType:"tool_result",content:d.output??null,toolName:c,toolInput:null,toolOutput:d.output==null?null:{output:d.output},tokenUsage:null,model:n.model,timestamp:g,metadata:{callId:d.call_id}});continue}if(f.type==="event_msg"&&d.type==="token_count"){let c=d.info,y=c?.total_token_usage?.total_tokens??0;if(y>0&&y===n.prevCumulativeTotal)continue;y>0&&(n.prevCumulativeTotal=y);let h=Ft(c?.last_token_usage??c?.total_token_usage);if(!h)continue;let _=c?.model??c?.model_name??n.model;s.push({sequence:n.sequence++,eventType:"assistant_response",content:null,toolName:null,toolInput:null,toolOutput:null,tokenUsage:h,model:_??null,timestamp:g,metadata:{codexEventType:"token_count",..._?{model:_}:{},reasoningOutputTokens:c?.last_token_usage?.reasoning_output_tokens??0,usage:{input_tokens:h.input,output_tokens:h.output,cache_read_input_tokens:h.cacheRead??0,cache_creation_input_tokens:h.cacheWrite??0}}})}}return{events:s,projectPath:u,gitBranch:a,sessionId:p,metadata:r}}};function nt(e,t){let n=e??(typeof t=="number"?new Date(t).toISOString():""),o=new Date(n);return Number.isFinite(o.getTime())?o.toISOString():new Date().toISOString()}l(nt,"timestamp");function st(e){return Array.isArray(e.content)?e.content:[]}l(st,"blocks");function ot(e){return typeof e.content=="string"?e.content:st(e).filter(t=>t.type==="text").map(t=>t.text??"").filter(Boolean).join(`
|
|
6
|
+
|
|
7
|
+
`)}l(ot,"messageText");function Wt(e){if(!e)return null;let t={input:Math.max(0,e.input??0),output:Math.max(0,e.output??0),cacheRead:Math.max(0,e.cacheRead??0),cacheWrite:Math.max(0,e.cacheWrite??0)};return Object.values(t).some(n=>n>0)?t:null}l(Wt,"usageOf");var E=class{static{l(this,"PiAdapter")}tool="pi";parse(t){let n=[],o={},s=null,r=null,i=null,u=null,a=l(f=>{n.push({sequence:n.length,...f})},"push");for(let f of t.split(`
|
|
8
|
+
`)){if(!f.trim())continue;let d;try{d=JSON.parse(f)}catch{continue}if(d.type==="session"){r||(r=nt(d.timestamp)),s=d.cwd??s,o.sessionId=d.id,o.piSessionId=d.id,o.sessionVersion=d.version;continue}if(d.type==="model_change"){i=d.provider??i,u=d.modelId??u,i&&(o.provider=i),u&&(o.model=u);continue}if(d.type!=="message"||!d.message)continue;let g=d.message,c=nt(d.timestamp,g.timestamp);if(i=g.provider??i,u=g.model??u,i&&(o.provider=i),u&&(o.model=u),g.role==="user"){let h=ot(g);if(!h)continue;a({eventType:"user_message",content:h,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,timestamp:c,metadata:{}});continue}if(g.role==="toolResult"){let h=ot(g);a({eventType:"tool_result",content:h||null,toolName:g.toolName??null,toolInput:null,toolOutput:{content:h,details:g.details??null,isError:g.isError??!1},tokenUsage:null,model:u,timestamp:c,metadata:{toolCallId:g.toolCallId,isError:g.isError??!1}});continue}if(g.role!=="assistant")continue;if(g.stopReason==="error"||g.stopReason==="aborted"){a({eventType:"error",content:g.errorMessage??`Pi stopped with ${g.stopReason}`,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,model:u,timestamp:c,metadata:{provider:i,stopReason:g.stopReason}});continue}for(let h of st(g))h.type==="thinking"&&h.thinking?a({eventType:"thinking",content:h.thinking,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,model:u,timestamp:c,metadata:{provider:i}}):h.type==="text"&&h.text?a({eventType:"assistant_message",content:h.text,toolName:null,toolInput:null,toolOutput:null,tokenUsage:null,model:u,timestamp:c,metadata:{provider:i}}):h.type==="toolCall"&&h.name&&a({eventType:"tool_call",content:null,toolName:h.name,toolInput:h.arguments??{},toolOutput:null,tokenUsage:null,model:u,timestamp:c,metadata:{provider:i,toolCallId:h.id}});let y=Wt(g.usage);y&&a({eventType:"assistant_response",content:null,toolName:null,toolInput:null,toolOutput:null,tokenUsage:y,model:u,timestamp:c,metadata:{piEventType:"assistant_usage",provider:i,responseId:g.responseId,stopReason:g.stopReason,costUsd:g.usage?.cost?.total,usage:{input_tokens:y.input,output_tokens:y.output,cache_read_input_tokens:y.cacheRead??0,cache_creation_input_tokens:y.cacheWrite??0}}})}let p=n.map(f=>f.timestamp).sort(),m=new Date().toISOString();return{tool:"pi",projectPath:s,gitBranch:null,startedAt:r??p[0]??m,endedAt:p[p.length-1]??null,events:n,metadata:o}}};var zt={claude_code:l(()=>new C,"claude_code"),cursor:l(()=>new A,"cursor"),vscode_copilot:l(()=>new N,"vscode_copilot"),copilot_agent:l(()=>new P,"copilot_agent"),rulemetric_mcp:l(()=>new D,"rulemetric_mcp"),codex:l(()=>new b,"codex"),pi:l(()=>new E,"pi")};function Kt(e){let t=zt[e];if(!t)throw new Error(`Unknown session tool: ${e}`);return t()}l(Kt,"getAdapter");function Vt(e){let t=e.trim();if(t.startsWith("{")){let n=t.split(`
|
|
9
|
+
`)[0],o=null;try{o=JSON.parse(n)}catch{try{o=JSON.parse(t)}catch{}}if(o){if(o.type==="user"||o.type==="assistant")return"claude_code";if(o.type==="session"&&typeof o.id=="string"&&typeof o.cwd=="string"&&typeof o.version=="number")return"pi";if(Array.isArray(o.events)&&!o.requests&&!o.allComposers)return"rulemetric_mcp";if(Array.isArray(o.requests))return o.requests.some(r=>Array.isArray(r.toolCalls))||o.agentMode?"copilot_agent":"vscode_copilot";if(o.allComposers)return"cursor"}if(!o)try{let s=t.split(`
|
|
10
|
+
`).filter(r=>r.trim());if(s.length>1){let r=JSON.parse(s[0]);if(r.type==="user"||r.type==="assistant")return"claude_code"}}catch{}}return null}l(Vt,"detectTool");import{readdir as H,stat as W}from"fs/promises";import{basename as Xt,join as w}from"path";import{homedir as R}from"os";var Yt={"claude-opus-4-7":"Opus 4.7","claude-opus-4-6":"Opus 4.6","claude-opus-4-5":"Opus 4.5","claude-opus-4-1":"Opus 4.1","claude-opus-4":"Opus 4","claude-sonnet-4-6":"Sonnet 4.6","claude-sonnet-4-5":"Sonnet 4.5","claude-sonnet-4":"Sonnet 4","claude-3-7-sonnet":"Sonnet 3.7","claude-3-5-sonnet":"Sonnet 3.5","claude-haiku-4-5":"Haiku 4.5","claude-3-5-haiku":"Haiku 3.5"};function Zt(){return process.env.CLAUDE_CONFIG_DIR||w(R(),".claude")}l(Zt,"getClaudeDir");function Qt(){return w(Zt(),"projects")}l(Qt,"getProjectsDir");function te(){return process.platform==="darwin"?w(R(),"Library","Application Support","Claude","local-agent-mode-sessions"):process.platform==="win32"?w(R(),"AppData","Roaming","Claude","local-agent-mode-sessions"):w(R(),".config","Claude","local-agent-mode-sessions")}l(te,"getDesktopSessionsDir");async function ee(e){let t=[];async function n(o,s){if(s>8)return;let r=await H(o).catch(()=>[]);for(let i of r){if(i==="node_modules"||i===".git")continue;let u=w(o,i);if((await W(u).catch(()=>null))?.isDirectory())if(i==="projects"){let p=await H(u).catch(()=>[]);for(let m of p){let f=w(u,m);(await W(f).catch(()=>null))?.isDirectory()&&t.push(f)}}else await n(u,s+1)}}return l(n,"walk"),await n(e,0),t}l(ee,"findDesktopProjectDirs");var rt={name:"claude",displayName:"Claude Code",modelDisplayName(e){let t=e.replace(/@.*$/,"").replace(/-\d{8}$/,"");for(let[n,o]of Object.entries(Yt))if(t.startsWith(n))return o;return t},toolDisplayName(e){return e},async discoverSessions(){let e=[],t=Qt();try{let o=await H(t);for(let s of o){let r=w(t,s);(await W(r).catch(()=>null))?.isDirectory()&&e.push({path:r,project:s,provider:"claude"})}}catch{}let n=await ee(te());for(let o of n)e.push({path:o,project:Xt(o),provider:"claude"});return e},createSessionParser(){return{async*parse(){}}}};import{readdir as $,readFile as at,stat as ne}from"fs/promises";import{basename as oe,join as O}from"path";import{homedir as se}from"os";var re={"gpt-5.3-codex":"GPT-5.3 Codex","gpt-5.4-mini":"GPT-5.4 Mini","gpt-5.4":"GPT-5.4","gpt-5":"GPT-5","gpt-4o-mini":"GPT-4o Mini","gpt-4o":"GPT-4o"},it={exec_command:"Bash",read_file:"Read",write_file:"Edit",apply_diff:"Edit",apply_patch:"Edit",spawn_agent:"Agent",close_agent:"Agent",wait_agent:"Agent",read_dir:"Glob"};function ae(){return process.env.CODEX_HOME??O(se(),".codex")}l(ae,"getCodexDir");function ie(e){return e.replace(/^\//,"").replace(/\//g,"-")}l(ie,"sanitizeProject");async function le(e){try{let n=(await at(e,"utf-8")).split(`
|
|
11
|
+
`)[0];return n?.trim()?JSON.parse(n):null}catch{return null}}l(le,"readFirstLine");async function ce(e){let t=await le(e);if(!t)return{valid:!1};let n=t.type==="session_meta"&&typeof t.payload?.originator=="string"&&t.payload.originator.toLowerCase().startsWith("codex");return{valid:n,meta:n?t:void 0}}l(ce,"isValidCodexSession");async function ue(e){let t=O(e,"sessions"),n=[],o;try{o=await $(t)}catch{return n}for(let s of o){if(!/^\d{4}$/.test(s))continue;let r=O(t,s),i=await $(r).catch(()=>[]);for(let u of i){if(!/^\d{2}$/.test(u))continue;let a=O(r,u),p=await $(a).catch(()=>[]);for(let m of p){if(!/^\d{2}$/.test(m))continue;let f=O(a,m),d=await $(f).catch(()=>[]);for(let g of d){if(!g.startsWith("rollout-")||!g.endsWith(".jsonl"))continue;let c=O(f,g);if(!(await ne(c).catch(()=>null))?.isFile())continue;let{valid:h,meta:_}=await ce(c);if(!h||!_)continue;let I=_.payload?.cwd??"unknown";n.push({path:c,project:ie(I),provider:"codex"})}}}}return n}l(ue,"discoverSessionsInDir");function pe(e,t){return e?.info?.model??e?.info?.model_name??t??"gpt-5"}l(pe,"resolveModel");function de(e,t){return{async*parse(){let n;try{n=await at(e.path,"utf-8")}catch{return}let o=n.split(`
|
|
12
|
+
`).filter(g=>g.trim()),s,r="",i=0,u=0,a=0,p=0,m=0,f=[],d="";for(let g of o){let c;try{c=JSON.parse(g)}catch{continue}if(c.type==="session_meta"){r=c.payload?.session_id??oe(e.path,".jsonl"),s=c.payload?.model;continue}if(c.type==="response_item"&&c.payload?.type==="function_call"){let y=c.payload.name??"";f.push(it[y]??y);continue}if(c.type==="response_item"&&c.payload?.type==="message"&&c.payload?.role==="user"){let y=(c.payload.content??[]).filter(h=>h.type==="input_text").map(h=>h.text??"").filter(Boolean);y.length>0&&(d=y.join(" "));continue}if(c.type==="event_msg"&&c.payload?.type==="token_count"){let y=c.payload.info;if(!y)continue;let h=y.total_token_usage?.total_tokens??0;if(h>0&&h===i)continue;i=h;let _=y.last_token_usage,I=0,T=0,x=0,S=0;if(_)I=_.input_tokens??0,T=_.cached_input_tokens??0,x=_.output_tokens??0,S=_.reasoning_output_tokens??0;else if(h>0){let v=y.total_token_usage;if(!v)continue;I=(v.input_tokens??0)-u,T=(v.cached_input_tokens??0)-a,x=(v.output_tokens??0)-p,S=(v.reasoning_output_tokens??0)-m}if(!_){let v=y.total_token_usage;v&&(u=v.input_tokens??0,a=v.cached_input_tokens??0,p=v.output_tokens??0,m=v.reasoning_output_tokens??0)}if(I+T+x+S===0)continue;let Mt=Math.max(0,I-T),qt=pe(c.payload,s),Q=c.timestamp??"",F=`codex:${e.path}:${Q}:${h}`;if(t.has(F))continue;t.add(F),yield{provider:"codex",model:qt,inputTokens:Mt,outputTokens:x,cacheCreationInputTokens:0,cacheReadInputTokens:T,cachedInputTokens:T,reasoningTokens:S,costUSD:0,tools:f,bashCommands:[],timestamp:Q,speed:"standard",deduplicationKey:F,userMessage:d,sessionId:r},f=[],d=""}}}}}l(de,"createParser");var lt={name:"codex",displayName:"Codex",modelDisplayName(e){for(let[t,n]of Object.entries(re))if(e.startsWith(t))return n;return e},toolDisplayName(e){return it[e]??e},async discoverSessions(){return ue(ae())},createSessionParser(e,t){return de(e,t)}};import{readdir as me,readFile as ct,stat as fe}from"fs/promises";import{basename as ut,dirname as he,join as z}from"path";import{homedir as ge}from"os";var ye={"gpt-4.1-nano":"GPT-4.1 Nano","gpt-4.1-mini":"GPT-4.1 Mini","gpt-4.1":"GPT-4.1","gpt-4o-mini":"GPT-4o Mini","gpt-4o":"GPT-4o","gpt-5-mini":"GPT-5 Mini","gpt-5":"GPT-5","claude-sonnet-4-5":"Sonnet 4.5","claude-sonnet-4":"Sonnet 4","claude-3-7-sonnet":"Sonnet 3.7","claude-3-5-sonnet":"Sonnet 3.5","o4-mini":"o4-mini",o3:"o3"},pt={bash:"Bash",read_file:"Read",write_file:"Edit",edit_file:"Edit",create_file:"Write",delete_file:"Delete",search_files:"Grep",find_files:"Glob",list_directory:"LS",web_search:"WebSearch",fetch_webpage:"WebFetch",github_repo:"GitHub"},_e=Object.entries(ye).sort((e,t)=>t[0].length-e[0].length);function Se(){return z(ge(),".copilot","session-state")}l(Se,"getCopilotSessionStateDir");function Te(e){let t=e.match(/^cwd:\s*(.+)$/m);return t?.[1]&&t[1].replace(/\s*#.*$/,"").replace(/^['"]|['"]$/g,"").trim()||null}l(Te,"parseCwd");function Ie(e,t){return{async*parse(){let n;try{n=await ct(e.path,"utf-8")}catch{return}let o=ut(he(e.path)),s=n.split(`
|
|
13
|
+
`).filter(u=>u.trim()),r="",i="";for(let u of s){let a;try{a=JSON.parse(u)}catch{continue}if(a.type==="session.model_change"){r=a.data.newModel??r;continue}if(a.type==="user.message"){i=a.data.content??"";continue}if(a.type==="assistant.message"){let{messageId:p,outputTokens:m,toolRequests:f=[]}=a.data;if(m===0||!r)continue;let d=`copilot:${o}:${p}`;if(t.has(d))continue;t.add(d);let g=f.map(c=>c.name??"").filter(Boolean).map(c=>pt[c]??c);yield{provider:"copilot",model:r,inputTokens:0,outputTokens:m,cacheCreationInputTokens:0,cacheReadInputTokens:0,cachedInputTokens:0,reasoningTokens:0,costUSD:0,tools:g,bashCommands:[],timestamp:a.timestamp??"",speed:"standard",deduplicationKey:d,userMessage:i,sessionId:o},i=""}}}}}l(Ie,"createParser");async function ve(e){let t=[],n;try{n=await me(e)}catch{return t}for(let o of n){let s=z(e,o,"events.jsonl");if(!(await fe(s).catch(()=>null))?.isFile())continue;let i=o;try{let u=await ct(z(e,o,"workspace.yaml"),"utf-8"),a=Te(u);a&&(i=ut(a))}catch{}t.push({path:s,project:i,provider:"copilot"})}return t}l(ve,"discoverSessionsInDir");var dt={name:"copilot",displayName:"GitHub Copilot",modelDisplayName(e){for(let[t,n]of _e)if(e===t||e.startsWith(t+"-"))return n;return e},toolDisplayName(e){return pt[e]??e},async discoverSessions(){return ve(Se())},createSessionParser(e,t){return Ie(e,t)}};import{readdir as mt,readFile as ht,stat as ft}from"fs/promises";import{basename as gt,join as K}from"path";import{homedir as xe}from"os";var we={"gpt-5.4":"GPT-5.4","gpt-5.4-mini":"GPT-5.4 Mini","gpt-5":"GPT-5","gpt-4o":"GPT-4o","gpt-4o-mini":"GPT-4o Mini"},yt={bash:"Bash",read:"Read",edit:"Edit",write:"Write",glob:"Glob",grep:"Grep",task:"Agent",dispatch_agent:"Agent",fetch:"WebFetch",search:"WebSearch",todo:"TodoWrite",patch:"Patch"},ke=Object.entries(we).sort((e,t)=>t[0].length-e[0].length);function Oe(){return K(xe(),".pi","agent","sessions")}l(Oe,"getPiSessionsDir");async function Ce(e){try{let n=(await ht(e,"utf-8")).split(`
|
|
14
|
+
`)[0];return n?.trim()?JSON.parse(n):null}catch{return null}}l(Ce,"readFirstEntry");function Ae(e){return e.split(/[;&|]+/).map(t=>t.trim().split(/\s+/)[0]).filter(Boolean)}l(Ae,"extractBashCommands");async function Ne(e){let t=[],n;try{n=await mt(e)}catch{return t}for(let o of n){let s=K(e,o);if(!(await ft(s).catch(()=>null))?.isDirectory())continue;let i;try{i=await mt(s)}catch{continue}for(let u of i){if(!u.endsWith(".jsonl"))continue;let a=K(s,u);if(!(await ft(a).catch(()=>null))?.isFile())continue;let m=await Ce(a);if(!m||m.type!=="session")continue;let f=m.cwd??o;t.push({path:a,project:gt(f),provider:"pi"})}}return t}l(Ne,"discoverSessionsInDir");function Pe(e,t){return{async*parse(){let n;try{n=await ht(e.path,"utf-8")}catch{return}let o=n.split(`
|
|
15
|
+
`).filter(i=>i.trim()),s=gt(e.path,".jsonl"),r="";for(let[i,u]of o.entries()){let a;try{a=JSON.parse(u)}catch{continue}if(a.type==="session"){s=a.id??s;continue}if(a.type!=="message")continue;let p=a.message;if(!p)continue;if(p.role==="user"){let S=(p.content??[]).filter(k=>k.type==="text").map(k=>k.text??"").filter(Boolean);S.length>0&&(r=S.join(" "));continue}if(p.role!=="assistant"||!p.usage)continue;let{input:m,output:f,cacheRead:d,cacheWrite:g}=p.usage;if(m===0&&f===0)continue;let c=p.model??"gpt-5",y=p.responseId??"",h=`pi:${e.path}:${y||a.id||a.timestamp||String(i)}`;if(t.has(h))continue;t.add(h);let _=(p.content??[]).filter(S=>S.type==="toolCall"&&S.name),I=_.map(S=>yt[S.name]??S.name),T=_.filter(S=>S.name==="bash").flatMap(S=>{let k=S.arguments?.command;return typeof k=="string"?Ae(k):[]}),x=a.timestamp??"";yield{provider:"pi",model:c,inputTokens:m,outputTokens:f,cacheCreationInputTokens:g,cacheReadInputTokens:d,cachedInputTokens:d,reasoningTokens:0,costUSD:0,tools:I,bashCommands:T,timestamp:x,speed:"standard",deduplicationKey:h,userMessage:r,sessionId:s},r=""}}}}l(Pe,"createParser");var _t={name:"pi",displayName:"Pi",modelDisplayName(e){for(let[t,n]of ke)if(e.startsWith(t))return n;return e},toolDisplayName(e){return yt[e]??e},async discoverSessions(){return Ne(Oe())},createSessionParser(e,t){return Pe(e,t)}};var xt=[rt,lt,dt,_t],St=null,Tt=!1;async function wt(){if(Tt)return St;Tt=!0;try{let{cursor:e}=await import("./cursor-T7AMCMKS.js");return St=e,e}catch{return null}}l(wt,"loadCursor");var It=null,vt=!1;async function kt(){if(vt)return It;vt=!0;try{let{opencode:e}=await import("./opencode-QRJ3BH23.js");return It=e,e}catch{return null}}l(kt,"loadOpenCode");async function Ot(){let[e,t]=await Promise.all([wt(),kt()]),n=[...xt];return e&&n.push(e),t&&n.push(t),n}l(Ot,"getAllProviders");async function De(e){let t=await Ot(),n=e&&e!=="all"?t.filter(s=>s.name===e):t,o=[];for(let s of n){let r=await s.discoverSessions();o.push(...r)}return o}l(De,"discoverAllSessions");async function be(e){return e==="cursor"?await wt()??void 0:e==="opencode"?await kt()??void 0:xt.find(t=>t.name===e)}l(be,"getProvider");import{spawn as Z}from"node:child_process";import{randomUUID as Ue}from"node:crypto";import{writeFile as At}from"node:fs/promises";import{tmpdir as Nt}from"node:os";import{join as Pt}from"node:path";import{spawn as Ee}from"node:child_process";function V(e){return`rm-${e.trim().replace(/[^A-Za-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"session"}`}l(V,"sanitizeTmuxName");function X(e){let t=[...e.runId?[`RULEMETRIC_RUN_ID=${e.runId}`]:[],...e.scopedConfirmation?[`RULEMETRIC_SCOPED_CONFIRMATION_ID=${e.scopedConfirmation.id}`,`RULEMETRIC_SCOPED_TASK_ID=${e.scopedConfirmation.taskId}`,`RULEMETRIC_SCOPED_CONFIGURATION_HASH=${e.scopedConfirmation.configurationHash}`]:[]],n=t.length?["env",...t,"claude"]:["claude"];return e.resumeSessionId&&n.push("--resume",e.resumeSessionId),e.model&&n.push("--model",e.model),["new-session","-d","-s",e.sessionName,"-c",e.projectPath,"--",...n]}l(X,"buildTmuxLaunchArgs");function U(e,t,n={}){return n.literal===!1?["send-keys","-t",e,t]:["send-keys","-t",e,"-l","--",t]}l(U,"buildTmuxSendKeysArgs");function Re(e){return["has-session","-t",e]}l(Re,"buildTmuxHasSessionArgs");function j(e){return`tmux attach -t ${e}`}l(j,"buildTmuxAttachCommand");function $e(){let e=["/opt/homebrew/bin","/usr/local/bin"],t=(process.env.PATH??"").split(":").filter(Boolean),n=e.filter(o=>!t.includes(o));return n.length===0?process.env:{...process.env,PATH:[...t,...n].join(":")}}l($e,"tmuxSpawnEnv");function Y(e){return new Promise(t=>{let n=Ee("tmux",e,{stdio:["ignore","ignore","pipe"],env:$e()}),o="";n.stderr.on("data",s=>{o+=s.toString()}),n.on("close",s=>t({code:s,stderr:o})),n.on("error",s=>t({code:null,stderr:s.message}))})}l(Y,"runTmux");async function Ct(){return(await Y(["-V"])).code===0}l(Ct,"isTmuxAvailable");var Dt=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,je=/^[a-f0-9]{64}$/;function Me(e){if(e){if(Dt.test(e.id)&&je.test(e.configurationHash)&&e.taskId.length>0&&e.taskId.length<=500)return e;console.warn("[claude-code-launcher] dropping invalid scoped confirmation identity")}}l(Me,"validateScopedConfirmation");function qe(e){if(e!==void 0){if(Dt.test(e))return e;console.warn(`[claude-code-launcher] dropping non-uuid runId (RULEMETRIC_RUN_ID not injected): ${JSON.stringify(e)}`)}}l(qe,"validateRunId");function M(e){return`'${e.replace(/'/g,"'\\''")}'`}l(M,"shellSingleQuote");var q=class{static{l(this,"ClaudeCodeLauncher")}options;tool="claude_code";constructor(t={}){this.options=t}capabilities={headless:!0,interactive:!0,remoteSpawn:!0};async launch(t){let n=Ue(),o={...t,runId:qe(t.runId),scopedConfirmation:Me(t.scopedConfirmation)};return o.mode==="headless"?this.launchHeadless(o,n):this.launchInteractive(o,n)}async launchHeadless(t,n){let o=["-p",t.prompt??"","--output-format","json"];t.systemPrompt&&o.push("--system-prompt",t.systemPrompt),t.model&&o.push("--model",t.model);let s={...process.env};return delete s.CLAUDECODE,delete s.HTTPS_PROXY,t.runId&&(s.RULEMETRIC_RUN_ID=t.runId),t.scopedConfirmation&&(s.RULEMETRIC_SCOPED_CONFIRMATION_ID=t.scopedConfirmation.id,s.RULEMETRIC_SCOPED_TASK_ID=t.scopedConfirmation.taskId,s.RULEMETRIC_SCOPED_CONFIGURATION_HASH=t.scopedConfirmation.configurationHash),new Promise(r=>{let i=Z("claude",o,{cwd:t.projectPath,env:s,stdio:["ignore","pipe","pipe"]}),u="",a="";i.stdout.on("data",m=>{u+=m.toString()}),i.stderr.on("data",m=>{a+=m.toString()});let p=t.timeout?setTimeout(()=>{i.kill("SIGTERM")},t.timeout):null;i.on("close",m=>{p&&clearTimeout(p);let f=u;try{let d=JSON.parse(u);f=d.result??d.content??u}catch{}r({sessionId:n,pid:i.pid,exitCode:m,output:f,error:m!==0?a:void 0})}),i.on("error",m=>{p&&clearTimeout(p),r({sessionId:n,error:`Failed to spawn claude: ${m.message}`})})})}async launchInteractive(t,n){return await(this.options.tmuxAvailable??Ct)().catch(()=>!1)?this.launchInteractiveTmux(t,n):this.launchInteractiveTerminal(t,n,"tmux_not_found")}async launchInteractiveTmux(t,n){let o=this.options.runTmux??Y,s=V(`claude-${t.resumeSessionId??n}`),r=await o(X({sessionName:s,projectPath:t.projectPath,resumeSessionId:t.resumeSessionId,model:t.model,runId:t.runId,scopedConfirmation:t.scopedConfirmation}));if(r.code!==0)return this.launchInteractiveTerminal(t,n,"tmux_launch_failed",`tmux new-session exited ${r.code}: ${r.stderr.trim()||"no stderr"}`);let i=await this.openTerminalAttach(s,n);if(t.prompt){let u=await o(U(s,t.prompt));if(u.code!==0)return{sessionId:n,liveSendAvailable:!1,fallbackReason:"tmux_launch_failed",error:`tmux send-keys exited ${u.code}: ${u.stderr.trim()||"no stderr"}`};let a=await o(U(s,"Enter",{literal:!1}));if(a.code!==0)return{sessionId:n,liveSendAvailable:!1,fallbackReason:"tmux_launch_failed",error:`tmux send Enter exited ${a.code}: ${a.stderr.trim()||"no stderr"}`}}return{sessionId:n,pid:i.pid,liveSendAvailable:!0,...i.error?{error:i.error}:{},terminalTarget:{kind:"tmux",target:s,attachCommand:j(s),live:!0}}}async openTerminalAttach(t,n){let o=Pt(Nt(),`rulemetric-attach-${n}.command`),s=`#!/bin/zsh
|
|
16
|
+
rm -- "$0"
|
|
17
|
+
${j(t)}
|
|
18
|
+
`;return await At(o,s,{mode:493}),new Promise(r=>{let i=Z("open",["-a","Terminal",o],{stdio:["ignore","pipe","pipe"]}),u="";i.stderr.on("data",a=>{u+=a.toString()}),i.on("close",a=>{r(a===0?{pid:i.pid}:{pid:i.pid,error:`open attach exited ${a}: ${u.trim()||"no stderr"}`})}),i.on("error",a=>{r({error:`Failed to spawn open attach: ${a.message}`})})})}async launchInteractiveTerminal(t,n,o,s){let r=["claude"];t.resumeSessionId?r.push("--resume",t.resumeSessionId):t.prompt&&r.push("-p",JSON.stringify(t.prompt)),t.model&&r.push("--model",t.model);let i=r.join(" "),u=Pt(Nt(),`rulemetric-launch-${n}.command`),a=t.runId?`export RULEMETRIC_RUN_ID=${M(t.runId)}
|
|
19
|
+
`:"",p=t.scopedConfirmation?`export RULEMETRIC_SCOPED_CONFIRMATION_ID=${M(t.scopedConfirmation.id)}
|
|
20
|
+
export RULEMETRIC_SCOPED_TASK_ID=${M(t.scopedConfirmation.taskId)}
|
|
21
|
+
export RULEMETRIC_SCOPED_CONFIGURATION_HASH=${M(t.scopedConfirmation.configurationHash)}
|
|
22
|
+
`:"",m=`#!/bin/zsh
|
|
23
|
+
rm -- "$0"
|
|
24
|
+
cd ${JSON.stringify(t.projectPath)} || exit
|
|
25
|
+
`+a+p+`${i}
|
|
26
|
+
`;return await At(u,m,{mode:493}),new Promise(f=>{let d=Z("open",["-a","Terminal",u],{stdio:["ignore","pipe","pipe"]}),g="";d.stderr.on("data",c=>{g+=c.toString()}),d.on("close",c=>{if(c===0)f({sessionId:n,pid:d.pid,liveSendAvailable:!1,fallbackReason:o,...s?{error:s}:{}});else{let y=g.trim()||"no stderr";f({sessionId:n,pid:d.pid,liveSendAvailable:!1,fallbackReason:o,error:s?`${s}; open exited ${c}: ${y}`:`open exited ${c}: ${y}`})}}),d.on("error",c=>{f({sessionId:n,liveSendAvailable:!1,fallbackReason:o,error:`Failed to spawn open: ${c.message}`})})})}};import{spawn as bt}from"node:child_process";import{randomUUID as Le}from"node:crypto";var L=class{static{l(this,"CodexLauncher")}tool="codex";capabilities={headless:!0,interactive:!0,remoteSpawn:!0};async launch(t){let n=Le();return t.mode==="headless"?this.launchHeadless(t,n):this.launchInteractive(t,n)}launchHeadless(t,n){let o=["-q",t.prompt??""];return t.model&&o.push("--model",t.model),new Promise(s=>{let r=bt("codex",o,{cwd:t.projectPath,stdio:["ignore","pipe","pipe"]}),i="",u="";r.stdout.on("data",p=>{i+=p.toString()}),r.stderr.on("data",p=>{u+=p.toString()});let a=t.timeout?setTimeout(()=>{r.kill("SIGTERM")},t.timeout):null;r.on("close",p=>{a&&clearTimeout(a),s({sessionId:n,pid:r.pid,exitCode:p,output:i,error:p!==0?u:void 0})}),r.on("error",p=>{a&&clearTimeout(a),s({sessionId:n,error:`Failed to spawn codex: ${p.message}`})})})}launchInteractive(t,n){let o=["codex"];t.prompt&&o.push(JSON.stringify(t.prompt));let s=`cd ${JSON.stringify(t.projectPath)} && ${o.join(" ")}`,r=bt("osascript",["-e",`tell application "Terminal" to do script ${JSON.stringify(s)}`],{stdio:"ignore",detached:!0});return r.unref(),Promise.resolve({sessionId:n,pid:r.pid})}};import{spawn as Et}from"node:child_process";import{randomUUID as Je}from"node:crypto";function Ge(e){let t=e.mode==="headless"?["--print","--mode","json","--no-session"]:[];return e.systemPrompt&&t.push("--system-prompt",e.systemPrompt),e.model&&t.push("--model",e.model),e.prompt&&t.push(e.prompt),t}l(Ge,"buildPiLaunchArgs");function Be(e){let t;for(let o of e.split(`
|
|
27
|
+
`))if(o.trim())try{let s=JSON.parse(o);if(s.type!=="agent_end"||!Array.isArray(s.messages))continue;t=s.messages.filter(r=>r.role==="assistant").at(-1)}catch{}if(!t)return{output:e};if(t.stopReason==="error"||t.stopReason==="aborted")return{output:"",error:`Pi provider error: ${t.errorMessage??t.stopReason}`};let n=t.content?.filter(o=>o.type==="text"&&typeof o.text=="string").map(o=>o.text).join(`
|
|
28
|
+
`)??"";return n?{output:n}:{output:e}}l(Be,"parsePiLaunchOutput");var J=class{static{l(this,"PiLauncher")}tool="pi";capabilities={headless:!0,interactive:!0,remoteSpawn:!0};async launch(t){let n=Je(),o=Ge(t);if(t.mode==="interactive"){let s=["pi",...o].map(u=>JSON.stringify(u)).join(" "),r=`cd ${JSON.stringify(t.projectPath)} && ${s}`,i=Et("osascript",["-e",`tell application "Terminal" to do script ${JSON.stringify(r)}`],{stdio:"ignore",detached:!0});return i.unref(),{sessionId:n,pid:i.pid}}return new Promise(s=>{let r=Et("pi",o,{cwd:t.projectPath,stdio:["ignore","pipe","pipe"]}),i="",u="";r.stdout.on("data",p=>{i+=p.toString()}),r.stderr.on("data",p=>{u+=p.toString()});let a=t.timeout?setTimeout(()=>r.kill("SIGTERM"),t.timeout):null;r.on("close",p=>{a&&clearTimeout(a);let m=Be(i);s({sessionId:n,pid:r.pid,exitCode:p,output:m.output,error:m.error??(p!==0?u.trim()||i.trim()||`pi exited ${p}`:void 0)})}),r.on("error",p=>{a&&clearTimeout(a),s({sessionId:n,error:`Failed to spawn pi: ${p.message}`})})})}};import{spawn as Rt}from"node:child_process";import{randomUUID as Fe}from"node:crypto";var G=class{static{l(this,"AiderLauncher")}tool="aider";capabilities={headless:!0,interactive:!0,remoteSpawn:!0};async launch(t){let n=Fe();return t.mode==="headless"?this.launchHeadless(t,n):this.launchInteractive(t,n)}launchHeadless(t,n){let o=["--message",t.prompt??"","--yes"];return t.model&&o.push("--model",t.model),new Promise(s=>{let r=Rt("aider",o,{cwd:t.projectPath,stdio:["ignore","pipe","pipe"]}),i="",u="";r.stdout.on("data",p=>{i+=p.toString()}),r.stderr.on("data",p=>{u+=p.toString()});let a=t.timeout?setTimeout(()=>{r.kill("SIGTERM")},t.timeout):null;r.on("close",p=>{a&&clearTimeout(a),s({sessionId:n,pid:r.pid,exitCode:p,output:i,error:p!==0?u:void 0})}),r.on("error",p=>{a&&clearTimeout(a),s({sessionId:n,error:`Failed to spawn aider: ${p.message}`})})})}launchInteractive(t,n){let o=["aider"];t.model&&o.push("--model",t.model);let s=`cd ${JSON.stringify(t.projectPath)} && ${o.join(" ")}`,r=Rt("osascript",["-e",`tell application "Terminal" to do script ${JSON.stringify(s)}`],{stdio:"ignore",detached:!0});return r.unref(),Promise.resolve({sessionId:n,pid:r.pid})}};import{spawn as He}from"node:child_process";import{randomUUID as We}from"node:crypto";var B=class{static{l(this,"GenericLauncher")}tool;constructor(t){this.tool=t}capabilities={headless:!1,interactive:!0,remoteSpawn:!1};async launch(t){let n=We();if(t.mode==="headless")return{sessionId:n,error:`${this.tool} does not support headless mode`};let o=`cd ${JSON.stringify(t.projectPath)} && echo "Session ${n} \u2014 tool: ${this.tool}" && exec $SHELL`,s=He("osascript",["-e",`tell application "Terminal" to do script ${JSON.stringify(o)}`],{stdio:"ignore",detached:!0});return s.unref(),{sessionId:n,pid:s.pid}}};var $t={claude_code:l(()=>new q,"claude_code"),codex:l(()=>new L,"codex"),pi:l(()=>new J,"pi"),aider:l(()=>new G,"aider")};function ze(e){let t=$t[e];return t?t():new B(e)}l(ze,"getLauncher");function Ke(){return Object.entries($t).map(([e,t])=>({tool:e,capabilities:t().capabilities}))}l(Ke,"getAvailableLaunchers");import Ut from"node:path";function jt(e){return e.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^[-.]+|[-.]+$/g,"")||"worktree"}l(jt,"sanitizeBranch");function Ve(e){return Ut.resolve(e.basePath??Ut.join(e.repoRoot,"..",".rulemetric-worktrees",jt(e.branch)))}l(Ve,"worktreePathFor");export{Xe as a,Ye as b,C as c,A as d,N as e,P as f,D as g,et as h,b as i,E as j,Kt as k,Vt as l,Ot as m,De as n,be as o,V as p,X as q,U as r,Re as s,j as t,ze as u,Ke as v,jt as w,Ve as x};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as m,c as d}from"./chunk-
|
|
1
|
+
import{a as m,c as d}from"./chunk-KFNFLMUR.js";import{a as s}from"./chunk-ZLLER3HP.js";var h=4,i=1,_=2,f=.0641;function x(e,r=f){return!(e>0)||!(r>=0)?null:Math.sqrt((m+d)**2*r/e)}s(x,"mdeForPairs");function w(e,r=f){if(!(e>0))throw new Error("pairsForMde: mde must be > 0");if(!(r>=0))throw new Error("pairsForMde: variance must be >= 0");return Math.max(1,Math.ceil((m+d)**2*r/e**2))}s(w,"pairsForMde");var p=10,c=128;function R(e){let r=e.autoEvolvePairs;if(r==null)return{minPairs:p,configured:!1};let a=typeof r=="number"?r:typeof r=="string"?Number(r):NaN;if(!Number.isFinite(a)||a<1)return{minPairs:p,configured:!1,note:`metadata.autoEvolvePairs=${JSON.stringify(r)} is not a positive number \u2014 using the default ${p}`};let n=Math.floor(a);return{minPairs:Math.min(c,Math.max(10,n)),configured:!0,...n>c?{note:`metadata.autoEvolvePairs=${n} clamped to the ${c}-pair ceiling`}:n<10?{note:`metadata.autoEvolvePairs=${n} raised to ${10} \u2014 a controlled verdict is refused below ${10} pairs, so a smaller batch buys a certain refusal. Use metadata.autoEvolvePaused to stop the spend instead.`}:{}}}s(R,"readPairBudget");function $(e){let r=e.autoEvolvePaused;return r===!0||r==="true"}s($,"isEvolutionPaused");function O(e){let{liveCases:r,passes:a,variance:n}=e,t=Math.max(0,r)*Math.max(0,a),o=t*2,l=t*2;return{liveCases:r,passes:a,plannedPairs:t,proposalCalls:i,executorCalls:o,graderCalls:l,totalCalls:i+o+l,maxCalls:i+o+l*_,mde:x(t,n)}}s(O,"estimateEvolutionCost");function L(e){let{runs:r,plannedPairs:a,usablePairs:n,passes:t,liveCases:o,wallMs:l,variance:g}=e,b=e.proposalCalls??i,v=e.verdictPairs??n,C=r.length,E=r.filter(P=>P.status==="completed"&&P.grading?.judge_model!=null).length;return{proposalCalls:b,executorCalls:C,graderCalls:E,modelCalls:b+C+E,plannedPairs:a,usablePairs:n,verdictPairs:v,passes:t,liveCases:o,mde:x(v,g),wallMs:l}}s(L,"observedEvolutionCost");function A(e){return e==null?"n/a":`${(e*100).toFixed(1)}pp`}s(A,"pp");function D(e){return`${e.liveCases} case(s) x ${e.passes} pass(es) = ${e.plannedPairs} planned pair(s), ~${e.totalCalls} model calls (up to ${e.maxCalls}) \u2014 resolves an effect of +/-${A(e.mde)} at 80% power`}s(D,"describeEvolutionCost");export{h as a,i as b,_ as c,f as d,x as e,w as f,p as g,c as h,R as i,$ as j,O as k,L as l,A as m,D as n};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as p}from"./chunk-
|
|
1
|
+
import{b as p}from"./chunk-T7HZZ4DJ.js";import{g as l}from"./chunk-XCH4HPEZ.js";import{a}from"./chunk-ZLLER3HP.js";var g=5,h=a(e=>e==null?"n/a":`${Math.round(e*100)}%`,"pct");function b(e){return!e||e.length===0?"":`
|
|
2
2
|
|
|
3
3
|
## Prior cases that FAILED to discriminate \u2014 do NOT reproduce these
|
|
4
4
|
The cases below were run WITH and WITHOUT the instruction and did NOT separate the two
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{h as o}from"./chunk-CVPAKEEZ.js";import{g as f}from"./chunk-
|
|
1
|
+
import{h as o}from"./chunk-CVPAKEEZ.js";import{g as f}from"./chunk-XCH4HPEZ.js";import{b as y,e as m,h as d}from"./chunk-GIXHG5FK.js";import{a as S}from"./chunk-ZLLER3HP.js";var _=1800*1e3,G=300*1e3,R=10,T=`Given these messages from an AI coding session, write a 1-2 sentence summary of what the user is trying to accomplish. Focus on the goal, not the steps. No preamble.
|
|
2
2
|
|
|
3
3
|
Return strict JSON in the form: {"goalSummary": "..."}`;async function N(n,e={}){let w=e.llm??f,i=e.now??Date.now,v=e.getSession??(async s=>{try{return await o(()=>m(`/api/sessions/${s}`),{label:"session detail",idempotent:!0})}catch(t){if(t instanceof y&&t.statusCode===404)return null;throw t}}),l=e.getEvents??((s,t)=>o(()=>m(`/api/sessions/${s}/events?limit=${t.limit}&sort=${t.sort}`),{label:"session events",idempotent:!0})),P=e.saveGoal??(async(s,t)=>{await o(()=>d(`/api/sessions/${s}/enrich`,{analysis:t}),{label:"session enrich"})}),r=await v(n.sessionId);if(!r)return{skipped:"not_found"};let[A]=await l(n.sessionId,{limit:1,sort:"desc"}),h=new Date(A?.timestamp??r.startedAt).getTime();if(i()-h>_)return{skipped:"stale"};let c=r.analysis??{},g=c.goalSummaryAt?new Date(c.goalSummaryAt).getTime():0;if(g&&i()-g<G)return{skipped:"recent"};let u=(await l(n.sessionId,{limit:R*2,sort:"asc"})).filter(s=>s.content&&(s.eventType==="user_message"||s.eventType==="assistant_response")).map(s=>`${s.eventType==="user_message"?"USER":"ASSISTANT"}: ${s.content}`).join(`
|
|
4
4
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{g}from"./chunk-KFNFLMUR.js";import{e as c,f as p}from"./chunk-GIXHG5FK.js";import{a}from"./chunk-ZLLER3HP.js";import{createHash as C,randomUUID as R}from"node:crypto";import{lstatSync as u,readFileSync as b,writeFileSync as v,openSync as k,closeSync as y,fsyncSync as x,renameSync as $,unlinkSync as A}from"node:fs";import{isAbsolute as I,parse as F,join as E,dirname as P}from"node:path";var w=a(e=>C("sha256").update(e).digest("hex"),"hash");function f(e){if(!I(e))throw new Error("Restoration requires an absolute file anchor");let o=F(e).root;for(let t of e.slice(o.length).split("/"))if(o=E(o,t),u(o).isSymbolicLink())throw new Error("Restoration refuses symlink anchors");if(!u(e).isFile())throw new Error("Restoration requires a regular file");return b(e,"utf8")}a(f,"readFile");function h(e,o,t){if(f(e)!==o)return!1;let i=E(P(e),`.rulemetric-restore-${R()}`),n;try{return n=k(i,"wx",u(e).mode&511),v(n,t),x(n),y(n),n=void 0,f(e)!==o?!1:($(i,e),!0)}finally{n!==void 0&&y(n);try{A(i)}catch(s){if(s.code!=="ENOENT")throw s}}}a(h,"replaceExact");async function j(e,o){let t=await c(`/api/promotions/${o.promotionId}`),i=await c(`/api/eval-targets/${e}`),n=a(r=>({applied:!1,fileWritten:!1,reason:r}),"refuse");if(o.version!==1||o.authority!=="manual"||t.evalTargetId!==e||!t.applied||t.decision!=="promote"||i.content!==t.toContent)return n("Stale or unsupported restoration");let s=i.metadata?.immutableSections;if(!Array.isArray(s)||!s.every(r=>typeof r=="string"))return n("Explicit immutable sections are required");let S=Array.isArray(t.gates?.immutableSections)?t.gates.immutableSections.filter(r=>typeof r=="string"):[];if(g(t.toContent,t.fromContent,[...s,...S]).length)return n("Restoration would change immutable sections");let d=!1;try{if(!h(i.name,t.toContent,t.fromContent))return n("File changed; preserving human edits");if(d=!0,f(i.name)!==t.fromContent)throw new Error("Predecessor read-back failed");let r=await p(`/api/promotions/${t.id}/restore`,{authority:o.authority,reason:o.reason,expectedVersion:i.version,path:i.name,diskBeforeHash:w(t.toContent),diskAfterHash:w(t.fromContent)});return{applied:r.applied,fileWritten:!0,promotionId:r.id}}catch(r){if(!d)return n(r instanceof Error?r.message:String(r));let l=await c(`/api/eval-targets/${e}`).catch(()=>null),m=await c(`/api/promotions/${t.id}/restoration`).catch(()=>null);if(m&&l?.content===t.fromContent&&l.version===m.gates.newVersion&&f(i.name)===t.fromContent)return{applied:!0,fileWritten:!0,promotionId:m.id,reason:"Restoration verified after response failure"};if(!l||l.content===t.fromContent)throw new Error("Restoration state unknown; disk retained for reconciliation",{cause:r});return h(i.name,t.fromContent,t.toContent),n(`Restoration refused: ${r instanceof Error?r.message:String(r)}`)}}a(j,"restoreInstruction");export{j as a};
|