@rulemetric/cli 0.15.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/chunk-3WCX2SLU.js +1 -0
  2. package/dist/{chunk-LLXC5SRC.js → chunk-5A6TMSRO.js} +1 -1
  3. package/dist/{chunk-RDL4HXFL.js → chunk-5CVP5NFH.js} +1 -1
  4. package/dist/{chunk-74KE4VOX.js → chunk-65LFPUDB.js} +1 -1
  5. package/dist/{chunk-QFTAU33Y.js → chunk-7LE2W3WP.js} +1 -1
  6. package/dist/{chunk-W6MMJRFZ.js → chunk-7YZURVZD.js} +1 -1
  7. package/dist/{chunk-AFEJYDUK.js → chunk-BU3ZGLQG.js} +1 -1
  8. package/dist/{chunk-CYCH2EQC.js → chunk-D4FP5M2B.js} +1 -1
  9. package/dist/{chunk-XCH4HPEZ.js → chunk-DHIEGG4T.js} +1 -1
  10. package/dist/{chunk-5Z6XXOJL.js → chunk-E4CIJ67Z.js} +1 -1
  11. package/dist/{chunk-CIKQXFQ2.js → chunk-EFEPD4AZ.js} +1 -1
  12. package/dist/chunk-EHW2KS6R.js +1 -0
  13. package/dist/chunk-GGUXEZC3.js +1 -0
  14. package/dist/{chunk-IFIWDL7G.js → chunk-GIQ2HK3W.js} +1 -1
  15. package/dist/{chunk-TWPD3ICV.js → chunk-GYKYJJNF.js} +1 -1
  16. package/dist/{chunk-HXOQUYG3.js → chunk-HBDKOU2N.js} +1 -1
  17. package/dist/chunk-HTAHNQZJ.js +1 -0
  18. package/dist/chunk-HYQ5YKBC.js +1 -0
  19. package/dist/chunk-I6W2KC6W.js +1 -0
  20. package/dist/{chunk-ISFPPDDB.js → chunk-IG4JMWFK.js} +1 -1
  21. package/dist/{chunk-CMDOLJ23.js → chunk-ISEUEYSC.js} +1 -1
  22. package/dist/{chunk-HT6R6KR3.js → chunk-KFNFLMUR.js} +1 -1
  23. package/dist/{chunk-DYET4EYU.js → chunk-KGU2IW54.js} +1 -1
  24. package/dist/{chunk-WQFR2LOY.js → chunk-KOORMTZO.js} +1 -1
  25. package/dist/chunk-MMMT34KO.js +28 -0
  26. package/dist/chunk-OCCJEWOF.js +1 -0
  27. package/dist/{chunk-RE7RAZQ5.js → chunk-RIYVZDOQ.js} +5 -5
  28. package/dist/{chunk-JSGXFD42.js → chunk-TQM7MF5C.js} +1 -1
  29. package/dist/{chunk-EJY5GK6A.js → chunk-TSLBCZ5P.js} +1 -1
  30. package/dist/chunk-TTZWVZIW.js +1 -0
  31. package/dist/chunk-U3YPVLM3.js +1 -0
  32. package/dist/{chunk-JUBXWTJA.js → chunk-USKRCVX3.js} +1 -1
  33. package/dist/{chunk-JOXTWLLK.js → chunk-WL34G6IR.js} +1 -1
  34. package/dist/{chunk-5PMTNNA6.js → chunk-WOANSBMJ.js} +1 -1
  35. package/dist/{chunk-RYCVPQYK.js → chunk-XQCGAPLN.js} +1 -1
  36. package/dist/{chunk-7LFCZI64.js → chunk-ZKPURXUS.js} +1 -1
  37. package/dist/commands/diagnostics.js +1 -1
  38. package/dist/commands/evals/agent.js +1 -1
  39. package/dist/commands/evals/benchmark.js +1 -1
  40. package/dist/commands/evals/optimize.js +1 -1
  41. package/dist/commands/evals/refine-cases.js +1 -1
  42. package/dist/commands/sessions/list.js +1 -1
  43. package/dist/commands/suggestions/accept.js +1 -1
  44. package/dist/commands/suggestions/undo.js +1 -1
  45. package/dist/dashboard/Dashboard.js +1 -1
  46. package/dist/dashboard/data.js +1 -1
  47. package/dist/{dist-GSHUC7UU.js → dist-UAAG2IWQ.js} +1 -1
  48. package/dist/lib/agent-loop.js +1 -1
  49. package/dist/lib/eval-benchmark.js +1 -1
  50. package/dist/lib/eval-case-generator.js +1 -1
  51. package/dist/lib/eval-conversation-handler.js +1 -1
  52. package/dist/lib/evolution-cost.js +1 -1
  53. package/dist/lib/evolution-enrolment.js +1 -1
  54. package/dist/lib/instruction-proposer.js +1 -1
  55. package/dist/lib/instruction-restoration.js +1 -1
  56. package/dist/lib/instructions/acceptance/suggestion-accept.js +1 -1
  57. package/dist/lib/jobs/handlers/cron-auto-accept-suggestions.js +1 -1
  58. package/dist/lib/jobs/handlers/cron-instruction-evolution.js +1 -1
  59. package/dist/lib/jobs/handlers/cron-instruction-training.js +1 -1
  60. package/dist/lib/jobs/handlers/cron-refine-cases.js +1 -1
  61. package/dist/lib/jobs/handlers/cron-refresh-pricing.js +1 -1
  62. package/dist/lib/jobs/handlers/cron-suggest-instructions.js +1 -1
  63. package/dist/lib/jobs/handlers/distill-memories.js +1 -1
  64. package/dist/lib/jobs/handlers/finalize-scoped-launch.js +1 -0
  65. package/dist/lib/jobs/handlers/prepare-suggestion-live.js +1 -0
  66. package/dist/lib/jobs/handlers/process-changelog.js +1 -1
  67. package/dist/lib/jobs/handlers/process-conversation.js +1 -1
  68. package/dist/lib/jobs/handlers/process-eval.js +1 -1
  69. package/dist/lib/jobs/handlers/process-insights.js +1 -1
  70. package/dist/lib/jobs/handlers/process-launch.js +1 -1
  71. package/dist/lib/jobs/handlers/process-memory-ab.js +1 -1
  72. package/dist/lib/jobs/handlers/process-run-cleanup.js +1 -1
  73. package/dist/lib/jobs/handlers/process-session-goal.js +1 -1
  74. package/dist/lib/jobs/handlers/process-suggestion-eval.js +1 -0
  75. package/dist/lib/llm-client.js +1 -1
  76. package/dist/lib/manual-tasks.js +1 -1
  77. package/dist/lib/optimize-compare.js +1 -1
  78. package/dist/lib/projects/workspace/worktree.js +1 -1
  79. package/dist/lib/refine-cases.js +1 -1
  80. package/oclif.manifest.json +1 -1
  81. package/package.json +6 -6
  82. package/dist/chunk-4DA6L7KL.js +0 -1
  83. package/dist/chunk-L562Y4RN.js +0 -1
  84. package/dist/chunk-N2PP2A7M.js +0 -1
  85. package/dist/chunk-T75KAEJO.js +0 -25
  86. package/dist/chunk-V576KKH6.js +0 -1
  87. package/dist/chunk-XIOYV5A7.js +0 -1
@@ -1 +1 @@
1
- import{a as _e}from"./chunk-M7QSC64D.js";import{i as Me}from"./chunk-7LFCZI64.js";import{a as Pe}from"./chunk-CMDOLJ23.js";import{b as pe,i as me,j as ge,k as fe,l as he,m as be,n as $e}from"./chunk-TWPD3ICV.js";import{c as Re}from"./chunk-G7V4ZZZ3.js";import{a as xe,b as Se,c as De,d as Ie,e as se,f as Oe}from"./chunk-LJE5J3EW.js";import{a as re}from"./chunk-AHLVY52I.js";import{d as ke,f as Ce,g as Ee,i as Ae}from"./chunk-YXMAGC53.js";import{a as we}from"./chunk-T7HZZ4DJ.js";import{c as ye}from"./chunk-FADINV4H.js";import{b as ve}from"./chunk-SWSOEYC7.js";import{d as ue,e as ne,f as de}from"./chunk-HT6R6KR3.js";import{e as y,f as te}from"./chunk-GIXHG5FK.js";import{a as g}from"./chunk-ZLLER3HP.js";import{createHash as Ge}from"node:crypto";import{existsSync as Te,readFileSync as Ne,writeFileSync as Xe}from"node:fs";var H=g(t=>Ge("sha256").update(t).digest("hex"),"sha256"),Le=1.3,ae=4,ze=20;function Be(t,o){if(!t.configured||o<=0)return ae;let e=Math.ceil(t.minPairs*Le/o);return Math.min(ze,Math.max(ae,e))}g(Be,"passCapFor");function Qe(t,o=10,e=ae){if(t<=0)return{passes:0,expectedPairs:0,feasible:!1,reason:"no live cases"};let i=Math.ceil(o*Le),l=Math.min(e,Math.ceil(i/t)),r=l*t;return r<o?{passes:l,expectedPairs:r,feasible:!1,reason:`${t} live case(s) x ${e} passes = ${t*e} pairs at best, below the ${o} a controlled verdict requires \u2014 add cases rather than replaying these`}:{passes:l,expectedPairs:r,feasible:!0}}g(Qe,"planPasses");var Ve=60,Ye=5,We=g(t=>Array.isArray(t)?t.filter(o=>typeof o=="string"):[],"stringList"),J=g(t=>typeof t=="number"&&Number.isFinite(t)?t:null,"finite");function Ze(t,o,e=Ye){let i=[...t].filter(s=>s.fromContentHash===o).sort((s,c)=>Date.parse(c.createdAt)-Date.parse(s.createdAt)),l=[],r=new Set;for(let s of i){let c=s.toContentHash??s.id;if(r.has(c))continue;r.add(c);let d=s.verdict??null,k=J(d?.delta),M=J(d?.ci?.lower),x=J(d?.ci?.upper),S=J(d?.nWith),L=d?.sufficient===!0&&k!=null&&M!=null&&x!=null&&S!=null?{delta:k,ciLower:M,ciUpper:x,nPairs:S}:null;if(l.push({decision:typeof s.decision=="string"?s.decision:"unknown",applied:s.applied===!0,at:typeof s.createdAt=="string"?s.createdAt:"",rationale:typeof s.proposalRationale=="string"?s.proposalRationale:"",touched:We(s.touchedSections),refusals:We(s.refusals),measured:L}),l.length>=e)break}return l}g(Ze,"summarisePriorDecisions");function et(t,o){let e=o.accumulate??(t.autoEvolveAccumulate===!0||t.autoEvolveAccumulate==="true"),i=o.accumulateTargetPairs??t.autoEvolveAccumulateTarget,l=typeof i=="string"?Number.parseInt(i,10):i,r=typeof l=="number"&&Number.isInteger(l)&&l>0?l:Ve;return{enabled:e,targetPairs:r}}g(et,"readAccumulateConfig");function tt(t){let o=t.accumulateEnabled&&t.pairCount<t.targetPairs;return{apply:t.consented&&!o,peeking:o}}g(tt,"resolveApply");async function Pt(t,o){if(t.restoration)return Pe(t.evalTargetId,t.restoration);let e=g(n=>o?.logger?.info?.(n)??console.log(n),"log"),{evalTargetId:i}=t,l=t.measurement?ye(t):{},r=`[cron_instruction_evolution] ${i}`,s=await y(`/api/eval-targets/${i}`),c=s.metadata??{},d=t.measurement?JSON.stringify([l.engine,l.model,l.graderEngine,l.graderModel,s.type,ve(t.measurement.engine)]):void 0,k=null,M=!1;if(s.name.startsWith("/")&&Te(s.name))try{if(k=Ne(s.name,"utf8"),k!==s.content){let n=await te(`/api/eval-targets/${i}/sync-content`,{content:k});M=n.synced,e(`${r}: target content drifted from disk by ${Math.abs(k.length-s.content.length)} chars \u2014 synced to disk truth (v${n.version}). Prior verdicts against the old text dissolve via content-hash keying.`),s={...s,content:k,version:n.version}}}catch(n){e(`${r}: disk sync failed (${n instanceof Error?n.message:String(n)}) \u2014 measuring the stored snapshot`)}let x=!1;try{x=(await y("/api/settings/evolution-account")).paused}catch(n){e(`${r}: could not read the account switch (${n instanceof Error?n.message:String(n)}) \u2014 pausing to be safe`),x=!0}if(x)return e(`${r}: PAUSED for the whole account (profiles.evolution_paused) \u2014 no model budget spent.`),{skipped:"paused-account"};if(ge(c))return e(`${r}: PAUSED (metadata.autoEvolvePaused) \u2014 no model budget spent. Opt-in is intact.`),{skipped:"paused"};let S=_e(s);if(S)return e(`${r}: ${S.reason}`),S;let L=t.apply??(c.autoEvolveApply===!0||c.autoEvolveApply==="true"),F=nt(c);if(F==null){if(L)return e(`${r}: refusing \u2014 metadata.immutableSections is unset. Set it (use [] to explicitly protect nothing) before letting the loop edit this target unattended.`),{skipped:"immutable-sections-unset"};e(`${r}: metadata.immutableSections unset \u2014 measure-only cycle proceeds with [] (nothing protected). Writing still requires setting it explicitly.`),F=[]}let v=(await y(`/api/eval-targets/${i}/evals`)).filter(n=>!n.retiredAt);if(v.length===0)return{skipped:"no-live-cases"};let j=me(c);j.note&&e(`${r}: ${j.note}`);let C=Qe(v.length,j.minPairs,Be(j,v.length));if(!C.feasible)return e(`${r}: cannot reach a sufficient verdict \u2014 ${C.reason}`),{skipped:"cannot-reach-min-n",reason:C.reason};let Fe=fe({liveCases:v.length,passes:C.passes});e(`${r}: budget for this run \u2014 ${$e(Fe)}`);let G=await y(`/api/eval-targets/${i}/judge-calibration`);if(!G.powerCheck.adequate){let n=(G.powerCheck.reasons??[]).join("; ");return e(`${r}: not adequately powered, skipping before spending budget \u2014 ${n}`),{skipped:"not-adequate",reason:n}}let oe=de,je=Date.now()-oe*24*60*60*1e3,X=await y(`/api/eval-targets/${i}/promotions?limit=200`),ie=X.promotions.filter(n=>n.applied&&Date.parse(n.createdAt)>=je).length;if(ie>=ne)return e(`${r}: change budget looks exhausted (${ie}/${ne} applied in ${oe}d), skipping before spending budget`),{skipped:"budget-exhausted"};try{let n=await y("/api/usage/current-limits"),u=Re({limits:n,now:new Date});if(!u.ok)return e(`${r}: deferring before spending budget \u2014 ${u.reason}`),{skipped:"quota-exhausted",reason:u.reason}}catch(n){e(`${r}: quota unknown (${n instanceof Error?n.message:String(n)}) \u2014 proceeding`)}let U=ue();if(!U.green)return e(`${r}: A/A canary is RED \u2014 halting. ${U.failures.join(" | ")}`),{skipped:"canary-red",reason:U.failures.join(" | ")};let z=s.content,D=H(z),f=et(c,t),w=f.enabled?re(X.promotions,D,f.targetPairs,d):null,b,q,$=[],_=0,B=pe,p=w?null:Se(c,D,d);if(p){b=p.content,q="",B=0;try{$=await Ie({evalTargetId:i,candidateContentHash:p.hash,executionKey:d,observedKey:p.observedKey})}catch(n){return e(`${r}: could not rebuild banked pairs (${n instanceof Error?n.message:String(n)})`),{skipped:"resume-read-failed",reason:p.hash}}e(`${r}: resuming interrupted cycle \u2014 ${$.length}/${p.plannedPairs} pair(s) rebuilt from eval_runs, no proposal call spent`)}else if(w){let n=await y(`/api/promotions/${w.promotionId}`);if(H(n.toContent)!==w.candidateContentHash)return e(`${r}: stored candidate does not match its recorded hash \u2014 refusing to continue`),{skipped:"accumulation-hash-mismatch",reason:w.promotionId};b=n.toContent,q=n.proposalRationale??"",$=w.pairs,_=w.runs,B=0,e(`${r}: continuing accumulation ${w.promotionId} \u2014 ${$.length}/${f.targetPairs} pair(s) carried from ${_} prior run(s)`)}else{let n=G.caseDiscrimination?.cases??[],u=[];if(s.name.startsWith("/")){let a=s.name.slice(0,s.name.lastIndexOf("/"));try{let m=await y(`/api/insights/evidence?projectPath=${encodeURIComponent(a)}`);m.analyzedAt&&(u=[...m.friction.map(ee=>`Real-session friction (insights, ${m.analyzedAt.slice(0,10)}): ${ee}`),...m.whatWorks.map(ee=>`Working well in real sessions \u2014 do not break: ${ee}`)],u.length>0&&e(`${r}: proposer sees ${m.friction.length} friction + ${m.whatWorks.length} what-works item(s) from insights`))}catch(m){e(`${r}: insights evidence unavailable (${m instanceof Error?m.message:String(m)}) \u2014 proposing without it`)}}let N=[];try{N=Ze(X.promotions,D)}catch(a){e(`${r}: could not summarise prior decisions (${a instanceof Error?a.message:String(a)}) \u2014 proposing without them`)}N.length>0&&e(`${r}: proposer sees ${N.length} prior decision(s) against this exact body (${N.map(a=>`${a.decision}${a.measured?"/measured":""}`).join(", ")})`);let W=await Me({currentContent:s.content,targetType:s.type,targetName:s.name,immutableSections:F,evidence:{nonDiscriminating:n.filter(a=>!a.discriminating).map(a=>`${a.name??a.assertion??"unnamed"} \u2014 ${a.note}`),weakest:n.filter(a=>a.discriminating&&a.withPassRate<a.withoutPassRate).map(a=>({name:a.name??a.assertion??"unnamed",withPassRate:a.withPassRate,withoutPassRate:a.withoutPassRate})),priorDecisions:N,notes:u}},void 0,t.measurement?(a,m)=>we(t.measurement,a,m):void 0);if(!W.ok)return e(`${r}: no usable proposal \u2014 ${W.reason}`),{skipped:"no-proposal",reason:W.reason};b=W.proposal.candidateContent,q=W.proposal.rationale}let I=p?De({plannedPairs:p.plannedPairs||C.expectedPairs,carriedPairs:$.length,liveCases:v.length}):C.passes;e(`${r}: measuring ${v.length} case(s) x ${I} pass(es) = up to ${v.length*I} pairs, candidate vs prior version`+(p?` (resumed; ${$.length} pair(s) already banked)`:""));let E=[],K=[],Ue=Date.now(),le=0,Q=0;for(let n=1;n<=I;n++){let u=await Ae({cases:v,candidateContent:b,priorVersionContent:z,concurrency:t.concurrency??2,runNumber:n,opts:{targetId:i,targetVersion:s.version??1,iteration:1,timeout:t.timeout??24e4,model:t.model,graderModel:t.graderModel,graderEngine:t.graderEngine,...l,executionKey:d,skipGrading:!1,targetType:s.type,targetName:s.name,candidateContentHash:H(b)},onLog:e});if(E.push(...u.pairs),K.push(...u.results),le+=u.completed,Q+=u.failed,e(`${r}: pass ${n}/${I} \u2014 ${u.pairs.length} pair(s), running total ${E.length}`),u.abortedForQuota){e(`${r}: stopping after pass ${n}/${I} \u2014 ${u.abortedForQuota}. Remaining passes would spend against an exhausted account.`);break}}let O=ke(K),qe=p?.observedKey??w?.observedKey;if(t.measurement&&E.length>0&&(!O||$.length>0&&qe!==O))return{skipped:"incomparable-execution",reason:"Actual actor/judge models or delivery changed; recorded runs are retained, but incompatible evidence cannot be pooled or promoted."};let A=[...$,...E],T=Ce(K),V=E.length>0,h=he({runs:K,plannedPairs:C.expectedPairs,usablePairs:E.length,verdictPairs:V?A.length:E.length,proposalCalls:B,passes:I,liveCases:v.length,wallMs:Date.now()-Ue});if(e(`${r}: ${le} completed, ${Q} failed, ${E.length} usable pair(s) \u2014 spent ~${h.modelCalls} model calls (${h.proposalCalls} proposal + ${h.executorCalls} executor + >=${h.graderCalls} grader) in ${(h.wallMs/6e4).toFixed(1)} min`+(V?`; the ${h.verdictPairs} pair(s) behind this verdict resolve +/-${be(h.mde)} at 80% power`:"")),!V)return{skipped:T.infrastructureFailed?"infrastructure-failure":"no-pairs",reason:T.infrastructureFailed?`${T.infrastructureFailed} run(s) never executed (${T.summary.describe()}) \u2014 the environment failed, not the target`:`${Q} run(s) failed or were ungradeable`,cost:h};let Y=Ee({pairs:A.length,minPairs:10,accounting:T});if(Y.kind==="infrastructure-incomplete")return e(`${r}: not posting a verdict \u2014 ${Y.reason}`),await se({evalTargetId:i,meta:c,blob:Oe({executionKey:d,...O?{observedKey:O}:{},content:b,hash:H(b),priorHash:D,plannedPairs:p?.plannedPairs||C.expectedPairs,now:new Date}),log:e,tag:r}),{skipped:"infrastructure-incomplete",reason:Y.reason,cost:h};f.enabled&&e(`${r}: accumulated ${A.length}/${f.targetPairs} pair(s) over ${_+1} run(s) on one candidate`);let ce=L,{apply:Ke,peeking:Je}=tt({consented:ce,accumulateEnabled:f.enabled,pairCount:A.length,targetPairs:f.targetPairs});ce&&Je&&e(`${r}: interim readout at ${A.length}/${f.targetPairs} pairs \u2014 recording the decision but not acting until the target is reached`);let P=await te(`/api/eval-targets/${i}/promotions`,{candidateContent:b,proposalSource:"llm",proposalRationale:q,pairs:A,canaryGreen:U.green,measuredAgainstContentHash:D,immutableSections:F,apply:Ke,measurementCost:h,...f.enabled?{accumulation:{executionKey:d,...O?{observedKey:O}:{},candidateContentHash:H(b),priorContentHash:D,targetPairs:f.targetPairs,carriedPairs:$.length,runs:_+1}}:{}});e(`${r}: ${P.decision}${P.applied?" (APPLIED)":""} \u2014 ${P.rationale}`+(P.refusals.length>0?` | refusals: ${P.refusals.join("; ")}`:"")),(p||c[xe])&&await se({evalTargetId:i,meta:c,blob:null,log:e,tag:r});let Z=!1,R;if(P.applied&&s.name.startsWith("/"))try{Te(s.name)?Ne(s.name,"utf8")!==z?R="file changed since measurement started \u2014 refusing to clobber; next cycle re-syncs":(Xe(s.name,b,"utf8"),Z=!0):R="file no longer exists on disk",e(Z?`${r}: measured improvement written to ${s.name} (undo: git checkout -- ${s.name})`:`${r}: NOT written to disk \u2014 ${R}`)}catch(n){R=n instanceof Error?n.message:String(n),e(`${r}: disk write-back failed \u2014 ${R}. The eval target is updated; the file is not.`)}return{decision:P.decision,applied:P.applied,nPairs:A.length,promotionId:P.id,cost:h,diskSynced:M,...P.applied?{fileWritten:Z,...R?{fileWriteSkipped:R}:{}}:{},...f.enabled?{carriedPairs:$.length,accumulationRuns:_+1}:{}}}g(Pt,"cronInstructionEvolution");function nt(t){let o=t.immutableSections;return o==null||!Array.isArray(o)?null:o.filter(e=>typeof e=="string")}g(nt,"readImmutableSections");export{Le as a,ae as b,ze as c,Be as d,Qe as e,Ve as f,Ye as g,Ze as h,et as i,tt as j,Pt as k,nt as l};
1
+ import{a as _e}from"./chunk-M7QSC64D.js";import{i as Me}from"./chunk-ZKPURXUS.js";import{a as Pe}from"./chunk-ISEUEYSC.js";import{b as pe,i as me,j as ge,k as fe,l as he,m as be,n as $e}from"./chunk-GYKYJJNF.js";import{c as Re}from"./chunk-G7V4ZZZ3.js";import{a as xe,b as Se,c as De,d as Ie,e as se,f as Oe}from"./chunk-LJE5J3EW.js";import{a as re}from"./chunk-AHLVY52I.js";import{d as ke,f as Ce,g as Ee,i as Ae}from"./chunk-YXMAGC53.js";import{a as we}from"./chunk-T7HZZ4DJ.js";import{c as ye}from"./chunk-FADINV4H.js";import{b as ve}from"./chunk-SWSOEYC7.js";import{d as ue,e as ne,f as de}from"./chunk-KFNFLMUR.js";import{e as y,f as te}from"./chunk-GIXHG5FK.js";import{a as g}from"./chunk-ZLLER3HP.js";import{createHash as Ge}from"node:crypto";import{existsSync as Te,readFileSync as Ne,writeFileSync as Xe}from"node:fs";var H=g(t=>Ge("sha256").update(t).digest("hex"),"sha256"),Le=1.3,ae=4,ze=20;function Be(t,o){if(!t.configured||o<=0)return ae;let e=Math.ceil(t.minPairs*Le/o);return Math.min(ze,Math.max(ae,e))}g(Be,"passCapFor");function Qe(t,o=10,e=ae){if(t<=0)return{passes:0,expectedPairs:0,feasible:!1,reason:"no live cases"};let i=Math.ceil(o*Le),l=Math.min(e,Math.ceil(i/t)),r=l*t;return r<o?{passes:l,expectedPairs:r,feasible:!1,reason:`${t} live case(s) x ${e} passes = ${t*e} pairs at best, below the ${o} a controlled verdict requires \u2014 add cases rather than replaying these`}:{passes:l,expectedPairs:r,feasible:!0}}g(Qe,"planPasses");var Ve=60,Ye=5,We=g(t=>Array.isArray(t)?t.filter(o=>typeof o=="string"):[],"stringList"),J=g(t=>typeof t=="number"&&Number.isFinite(t)?t:null,"finite");function Ze(t,o,e=Ye){let i=[...t].filter(s=>s.fromContentHash===o).sort((s,c)=>Date.parse(c.createdAt)-Date.parse(s.createdAt)),l=[],r=new Set;for(let s of i){let c=s.toContentHash??s.id;if(r.has(c))continue;r.add(c);let d=s.verdict??null,k=J(d?.delta),M=J(d?.ci?.lower),x=J(d?.ci?.upper),S=J(d?.nWith),L=d?.sufficient===!0&&k!=null&&M!=null&&x!=null&&S!=null?{delta:k,ciLower:M,ciUpper:x,nPairs:S}:null;if(l.push({decision:typeof s.decision=="string"?s.decision:"unknown",applied:s.applied===!0,at:typeof s.createdAt=="string"?s.createdAt:"",rationale:typeof s.proposalRationale=="string"?s.proposalRationale:"",touched:We(s.touchedSections),refusals:We(s.refusals),measured:L}),l.length>=e)break}return l}g(Ze,"summarisePriorDecisions");function et(t,o){let e=o.accumulate??(t.autoEvolveAccumulate===!0||t.autoEvolveAccumulate==="true"),i=o.accumulateTargetPairs??t.autoEvolveAccumulateTarget,l=typeof i=="string"?Number.parseInt(i,10):i,r=typeof l=="number"&&Number.isInteger(l)&&l>0?l:Ve;return{enabled:e,targetPairs:r}}g(et,"readAccumulateConfig");function tt(t){let o=t.accumulateEnabled&&t.pairCount<t.targetPairs;return{apply:t.consented&&!o,peeking:o}}g(tt,"resolveApply");async function Pt(t,o){if(t.restoration)return Pe(t.evalTargetId,t.restoration);let e=g(n=>o?.logger?.info?.(n)??console.log(n),"log"),{evalTargetId:i}=t,l=t.measurement?ye(t):{},r=`[cron_instruction_evolution] ${i}`,s=await y(`/api/eval-targets/${i}`),c=s.metadata??{},d=t.measurement?JSON.stringify([l.engine,l.model,l.graderEngine,l.graderModel,s.type,ve(t.measurement.engine)]):void 0,k=null,M=!1;if(s.name.startsWith("/")&&Te(s.name))try{if(k=Ne(s.name,"utf8"),k!==s.content){let n=await te(`/api/eval-targets/${i}/sync-content`,{content:k});M=n.synced,e(`${r}: target content drifted from disk by ${Math.abs(k.length-s.content.length)} chars \u2014 synced to disk truth (v${n.version}). Prior verdicts against the old text dissolve via content-hash keying.`),s={...s,content:k,version:n.version}}}catch(n){e(`${r}: disk sync failed (${n instanceof Error?n.message:String(n)}) \u2014 measuring the stored snapshot`)}let x=!1;try{x=(await y("/api/settings/evolution-account")).paused}catch(n){e(`${r}: could not read the account switch (${n instanceof Error?n.message:String(n)}) \u2014 pausing to be safe`),x=!0}if(x)return e(`${r}: PAUSED for the whole account (profiles.evolution_paused) \u2014 no model budget spent.`),{skipped:"paused-account"};if(ge(c))return e(`${r}: PAUSED (metadata.autoEvolvePaused) \u2014 no model budget spent. Opt-in is intact.`),{skipped:"paused"};let S=_e(s);if(S)return e(`${r}: ${S.reason}`),S;let L=t.apply??(c.autoEvolveApply===!0||c.autoEvolveApply==="true"),F=nt(c);if(F==null){if(L)return e(`${r}: refusing \u2014 metadata.immutableSections is unset. Set it (use [] to explicitly protect nothing) before letting the loop edit this target unattended.`),{skipped:"immutable-sections-unset"};e(`${r}: metadata.immutableSections unset \u2014 measure-only cycle proceeds with [] (nothing protected). Writing still requires setting it explicitly.`),F=[]}let v=(await y(`/api/eval-targets/${i}/evals`)).filter(n=>!n.retiredAt);if(v.length===0)return{skipped:"no-live-cases"};let j=me(c);j.note&&e(`${r}: ${j.note}`);let C=Qe(v.length,j.minPairs,Be(j,v.length));if(!C.feasible)return e(`${r}: cannot reach a sufficient verdict \u2014 ${C.reason}`),{skipped:"cannot-reach-min-n",reason:C.reason};let Fe=fe({liveCases:v.length,passes:C.passes});e(`${r}: budget for this run \u2014 ${$e(Fe)}`);let G=await y(`/api/eval-targets/${i}/judge-calibration`);if(!G.powerCheck.adequate){let n=(G.powerCheck.reasons??[]).join("; ");return e(`${r}: not adequately powered, skipping before spending budget \u2014 ${n}`),{skipped:"not-adequate",reason:n}}let oe=de,je=Date.now()-oe*24*60*60*1e3,X=await y(`/api/eval-targets/${i}/promotions?limit=200`),ie=X.promotions.filter(n=>n.applied&&Date.parse(n.createdAt)>=je).length;if(ie>=ne)return e(`${r}: change budget looks exhausted (${ie}/${ne} applied in ${oe}d), skipping before spending budget`),{skipped:"budget-exhausted"};try{let n=await y("/api/usage/current-limits"),u=Re({limits:n,now:new Date});if(!u.ok)return e(`${r}: deferring before spending budget \u2014 ${u.reason}`),{skipped:"quota-exhausted",reason:u.reason}}catch(n){e(`${r}: quota unknown (${n instanceof Error?n.message:String(n)}) \u2014 proceeding`)}let U=ue();if(!U.green)return e(`${r}: A/A canary is RED \u2014 halting. ${U.failures.join(" | ")}`),{skipped:"canary-red",reason:U.failures.join(" | ")};let z=s.content,D=H(z),f=et(c,t),w=f.enabled?re(X.promotions,D,f.targetPairs,d):null,b,q,$=[],_=0,B=pe,p=w?null:Se(c,D,d);if(p){b=p.content,q="",B=0;try{$=await Ie({evalTargetId:i,candidateContentHash:p.hash,executionKey:d,observedKey:p.observedKey})}catch(n){return e(`${r}: could not rebuild banked pairs (${n instanceof Error?n.message:String(n)})`),{skipped:"resume-read-failed",reason:p.hash}}e(`${r}: resuming interrupted cycle \u2014 ${$.length}/${p.plannedPairs} pair(s) rebuilt from eval_runs, no proposal call spent`)}else if(w){let n=await y(`/api/promotions/${w.promotionId}`);if(H(n.toContent)!==w.candidateContentHash)return e(`${r}: stored candidate does not match its recorded hash \u2014 refusing to continue`),{skipped:"accumulation-hash-mismatch",reason:w.promotionId};b=n.toContent,q=n.proposalRationale??"",$=w.pairs,_=w.runs,B=0,e(`${r}: continuing accumulation ${w.promotionId} \u2014 ${$.length}/${f.targetPairs} pair(s) carried from ${_} prior run(s)`)}else{let n=G.caseDiscrimination?.cases??[],u=[];if(s.name.startsWith("/")){let a=s.name.slice(0,s.name.lastIndexOf("/"));try{let m=await y(`/api/insights/evidence?projectPath=${encodeURIComponent(a)}`);m.analyzedAt&&(u=[...m.friction.map(ee=>`Real-session friction (insights, ${m.analyzedAt.slice(0,10)}): ${ee}`),...m.whatWorks.map(ee=>`Working well in real sessions \u2014 do not break: ${ee}`)],u.length>0&&e(`${r}: proposer sees ${m.friction.length} friction + ${m.whatWorks.length} what-works item(s) from insights`))}catch(m){e(`${r}: insights evidence unavailable (${m instanceof Error?m.message:String(m)}) \u2014 proposing without it`)}}let N=[];try{N=Ze(X.promotions,D)}catch(a){e(`${r}: could not summarise prior decisions (${a instanceof Error?a.message:String(a)}) \u2014 proposing without them`)}N.length>0&&e(`${r}: proposer sees ${N.length} prior decision(s) against this exact body (${N.map(a=>`${a.decision}${a.measured?"/measured":""}`).join(", ")})`);let W=await Me({currentContent:s.content,targetType:s.type,targetName:s.name,immutableSections:F,evidence:{nonDiscriminating:n.filter(a=>!a.discriminating).map(a=>`${a.name??a.assertion??"unnamed"} \u2014 ${a.note}`),weakest:n.filter(a=>a.discriminating&&a.withPassRate<a.withoutPassRate).map(a=>({name:a.name??a.assertion??"unnamed",withPassRate:a.withPassRate,withoutPassRate:a.withoutPassRate})),priorDecisions:N,notes:u}},void 0,t.measurement?(a,m)=>we(t.measurement,a,m):void 0);if(!W.ok)return e(`${r}: no usable proposal \u2014 ${W.reason}`),{skipped:"no-proposal",reason:W.reason};b=W.proposal.candidateContent,q=W.proposal.rationale}let I=p?De({plannedPairs:p.plannedPairs||C.expectedPairs,carriedPairs:$.length,liveCases:v.length}):C.passes;e(`${r}: measuring ${v.length} case(s) x ${I} pass(es) = up to ${v.length*I} pairs, candidate vs prior version`+(p?` (resumed; ${$.length} pair(s) already banked)`:""));let E=[],K=[],Ue=Date.now(),le=0,Q=0;for(let n=1;n<=I;n++){let u=await Ae({cases:v,candidateContent:b,priorVersionContent:z,concurrency:t.concurrency??2,runNumber:n,opts:{targetId:i,targetVersion:s.version??1,iteration:1,timeout:t.timeout??24e4,model:t.model,graderModel:t.graderModel,graderEngine:t.graderEngine,...l,executionKey:d,skipGrading:!1,targetType:s.type,targetName:s.name,candidateContentHash:H(b)},onLog:e});if(E.push(...u.pairs),K.push(...u.results),le+=u.completed,Q+=u.failed,e(`${r}: pass ${n}/${I} \u2014 ${u.pairs.length} pair(s), running total ${E.length}`),u.abortedForQuota){e(`${r}: stopping after pass ${n}/${I} \u2014 ${u.abortedForQuota}. Remaining passes would spend against an exhausted account.`);break}}let O=ke(K),qe=p?.observedKey??w?.observedKey;if(t.measurement&&E.length>0&&(!O||$.length>0&&qe!==O))return{skipped:"incomparable-execution",reason:"Actual actor/judge models or delivery changed; recorded runs are retained, but incompatible evidence cannot be pooled or promoted."};let A=[...$,...E],T=Ce(K),V=E.length>0,h=he({runs:K,plannedPairs:C.expectedPairs,usablePairs:E.length,verdictPairs:V?A.length:E.length,proposalCalls:B,passes:I,liveCases:v.length,wallMs:Date.now()-Ue});if(e(`${r}: ${le} completed, ${Q} failed, ${E.length} usable pair(s) \u2014 spent ~${h.modelCalls} model calls (${h.proposalCalls} proposal + ${h.executorCalls} executor + >=${h.graderCalls} grader) in ${(h.wallMs/6e4).toFixed(1)} min`+(V?`; the ${h.verdictPairs} pair(s) behind this verdict resolve +/-${be(h.mde)} at 80% power`:"")),!V)return{skipped:T.infrastructureFailed?"infrastructure-failure":"no-pairs",reason:T.infrastructureFailed?`${T.infrastructureFailed} run(s) never executed (${T.summary.describe()}) \u2014 the environment failed, not the target`:`${Q} run(s) failed or were ungradeable`,cost:h};let Y=Ee({pairs:A.length,minPairs:10,accounting:T});if(Y.kind==="infrastructure-incomplete")return e(`${r}: not posting a verdict \u2014 ${Y.reason}`),await se({evalTargetId:i,meta:c,blob:Oe({executionKey:d,...O?{observedKey:O}:{},content:b,hash:H(b),priorHash:D,plannedPairs:p?.plannedPairs||C.expectedPairs,now:new Date}),log:e,tag:r}),{skipped:"infrastructure-incomplete",reason:Y.reason,cost:h};f.enabled&&e(`${r}: accumulated ${A.length}/${f.targetPairs} pair(s) over ${_+1} run(s) on one candidate`);let ce=L,{apply:Ke,peeking:Je}=tt({consented:ce,accumulateEnabled:f.enabled,pairCount:A.length,targetPairs:f.targetPairs});ce&&Je&&e(`${r}: interim readout at ${A.length}/${f.targetPairs} pairs \u2014 recording the decision but not acting until the target is reached`);let P=await te(`/api/eval-targets/${i}/promotions`,{candidateContent:b,proposalSource:"llm",proposalRationale:q,pairs:A,canaryGreen:U.green,measuredAgainstContentHash:D,immutableSections:F,apply:Ke,measurementCost:h,...f.enabled?{accumulation:{executionKey:d,...O?{observedKey:O}:{},candidateContentHash:H(b),priorContentHash:D,targetPairs:f.targetPairs,carriedPairs:$.length,runs:_+1}}:{}});e(`${r}: ${P.decision}${P.applied?" (APPLIED)":""} \u2014 ${P.rationale}`+(P.refusals.length>0?` | refusals: ${P.refusals.join("; ")}`:"")),(p||c[xe])&&await se({evalTargetId:i,meta:c,blob:null,log:e,tag:r});let Z=!1,R;if(P.applied&&s.name.startsWith("/"))try{Te(s.name)?Ne(s.name,"utf8")!==z?R="file changed since measurement started \u2014 refusing to clobber; next cycle re-syncs":(Xe(s.name,b,"utf8"),Z=!0):R="file no longer exists on disk",e(Z?`${r}: measured improvement written to ${s.name} (undo: git checkout -- ${s.name})`:`${r}: NOT written to disk \u2014 ${R}`)}catch(n){R=n instanceof Error?n.message:String(n),e(`${r}: disk write-back failed \u2014 ${R}. The eval target is updated; the file is not.`)}return{decision:P.decision,applied:P.applied,nPairs:A.length,promotionId:P.id,cost:h,diskSynced:M,...P.applied?{fileWritten:Z,...R?{fileWriteSkipped:R}:{}}:{},...f.enabled?{carriedPairs:$.length,accumulationRuns:_+1}:{}}}g(Pt,"cronInstructionEvolution");function nt(t){let o=t.immutableSections;return o==null||!Array.isArray(o)?null:o.filter(e=>typeof e=="string")}g(nt,"readImmutableSections");export{Le as a,ae as b,ze as c,Be as d,Qe as e,Ve as f,Ye as g,Ze as h,et as i,tt as j,Pt as k,nt as l};
@@ -1,4 +1,4 @@
1
- import{a as M}from"./chunk-5RBLIVBF.js";import{c as q}from"./chunk-GLBWNB2N.js";import{a as K,b as Y}from"./chunk-CQD2R3BA.js";import{a as A,d as N}from"./chunk-3UKZJAFS.js";import{a as j,b as k,c as V,d as D}from"./chunk-77FH6UZP.js";import{a as Z}from"./chunk-KE5K3F7J.js";import{b as W,e as B,g as T}from"./chunk-XCH4HPEZ.js";import{e as h,f as U,h as m}from"./chunk-GIXHG5FK.js";import{a as L,b as H}from"./chunk-X6CF5KTW.js";import{a as f}from"./chunk-ZLLER3HP.js";var Q=f((l,{limit:a,sort:n,eventTypes:s})=>h(`/api/sessions/${l}/events?limit=${a}&sort=${n}&eventType=${encodeURIComponent(s.join(","))}&hasContent=true`),"fetchTranscriptTurns");async function ms(l,a){let{mirrorId:n,projectPath:s,projectId:r,config:u}=l,e=f(t=>a.logger.info(t),"log");if(u?.sessionId)return es({mirrorId:n,sessionId:u.sessionId},e);e(`Processing insights job ${n}...`),await m(`/api/insights-jobs/${n}/progress`,{status:"running",progress:{step:"reading_data"}});try{let{repaired:t}=await U("/api/sessions/repair-analyzed-at",{});t>0&&e(` Repaired analyzed_at on ${t} orphan session(s).`)}catch(t){e(` Warning: analyzed_at repair failed: ${t instanceof Error?t.message:String(t)}`)}let p=20,C=200,z=15*6e4,F=3,E=Date.now()+z,I=B()==="none"?"no-llm-backend":null;if(I&&a.logger.warn?.("[process-insights] no LLM backend (no claude/codex CLI and no ANTHROPIC_API_KEY) \u2014 facet grading SKIPPED for this run; the summary below is computed from already-graded sessions only"),!I){let t=0,i=0;try{for(;t<C&&Date.now()<E;){let c=await h(`/api/sessions?needsFacets=true&graderVersion=${2}&limit=${p}&offset=${i}`);if(c.length===0)break;e(` Generating facets for ${c.length} un-analyzed sessions (drained ${t} so far)...`);for(let b=0;b<c.length&&!(t>=C||Date.now()>=E);b+=F){let R=c.slice(b,b+F);await Promise.all(R.map(async g=>{if(!(t>=C||Date.now()>=E))try{let d=await N(ss=>Q(g.id,ss));if(d.turnCount<2){t++,i++;return}let O=await T(D,d.text,4096);O&&typeof O.outcome=="string"?(await m(`/api/sessions/${g.id}/enrich`,{analysis:{source:"generated_facets",...O,graderVersion:2},...g.eventCount!=null?{analyzedEventCount:g.eventCount}:{},analyzedTurnCount:d.turnCount}),e(` Generated facets for session ${g.id} (${g.tool}, ${d.turnCount} turns)`)):i++,t++}catch(d){e(` Failed to generate facets for session ${g.id}: ${d instanceof Error?d.message:String(d)}`),t++,i++}}))}if(c.length<p)break}}catch(c){e(` Warning: facet generation failed after ${t} sessions: ${c instanceof Error?c.message:String(c)}`)}if(t>0){let c=Date.now()>=E?`time budget (${Math.round(z/6e4)}m)`:t>=C?`hard cap (${C})`:"queue empty";e(` Facet drain stopped on ${c} after ${t} session(s); the rest resume next run.`)}}let _=await ns(s,r);if(!_)throw new M("No session data found \u2014 ensure sessions are captured and enriched.");e(` Found ${_.stats.sessions} sessions, generating recommendations...`);let y=await Y({projectId:r,projectPath:s},h);_.summary+=`
1
+ import{a as M}from"./chunk-5RBLIVBF.js";import{c as q}from"./chunk-GLBWNB2N.js";import{a as K,b as Y}from"./chunk-CQD2R3BA.js";import{a as A,d as N}from"./chunk-3UKZJAFS.js";import{a as j,b as k,c as V,d as D}from"./chunk-77FH6UZP.js";import{a as Z}from"./chunk-KE5K3F7J.js";import{b as W,e as B,g as T}from"./chunk-DHIEGG4T.js";import{e as h,f as U,h as m}from"./chunk-GIXHG5FK.js";import{a as L,b as H}from"./chunk-X6CF5KTW.js";import{a as f}from"./chunk-ZLLER3HP.js";var Q=f((l,{limit:a,sort:n,eventTypes:s})=>h(`/api/sessions/${l}/events?limit=${a}&sort=${n}&eventType=${encodeURIComponent(s.join(","))}&hasContent=true`),"fetchTranscriptTurns");async function ms(l,a){let{mirrorId:n,projectPath:s,projectId:r,config:u}=l,e=f(t=>a.logger.info(t),"log");if(u?.sessionId)return es({mirrorId:n,sessionId:u.sessionId},e);e(`Processing insights job ${n}...`),await m(`/api/insights-jobs/${n}/progress`,{status:"running",progress:{step:"reading_data"}});try{let{repaired:t}=await U("/api/sessions/repair-analyzed-at",{});t>0&&e(` Repaired analyzed_at on ${t} orphan session(s).`)}catch(t){e(` Warning: analyzed_at repair failed: ${t instanceof Error?t.message:String(t)}`)}let p=20,C=200,z=15*6e4,F=3,E=Date.now()+z,I=B()==="none"?"no-llm-backend":null;if(I&&a.logger.warn?.("[process-insights] no LLM backend (no claude/codex CLI and no ANTHROPIC_API_KEY) \u2014 facet grading SKIPPED for this run; the summary below is computed from already-graded sessions only"),!I){let t=0,i=0;try{for(;t<C&&Date.now()<E;){let c=await h(`/api/sessions?needsFacets=true&graderVersion=${2}&limit=${p}&offset=${i}`);if(c.length===0)break;e(` Generating facets for ${c.length} un-analyzed sessions (drained ${t} so far)...`);for(let b=0;b<c.length&&!(t>=C||Date.now()>=E);b+=F){let R=c.slice(b,b+F);await Promise.all(R.map(async g=>{if(!(t>=C||Date.now()>=E))try{let d=await N(ss=>Q(g.id,ss));if(d.turnCount<2){t++,i++;return}let O=await T(D,d.text,4096);O&&typeof O.outcome=="string"?(await m(`/api/sessions/${g.id}/enrich`,{analysis:{source:"generated_facets",...O,graderVersion:2},...g.eventCount!=null?{analyzedEventCount:g.eventCount}:{},analyzedTurnCount:d.turnCount}),e(` Generated facets for session ${g.id} (${g.tool}, ${d.turnCount} turns)`)):i++,t++}catch(d){e(` Failed to generate facets for session ${g.id}: ${d instanceof Error?d.message:String(d)}`),t++,i++}}))}if(c.length<p)break}}catch(c){e(` Warning: facet generation failed after ${t} sessions: ${c instanceof Error?c.message:String(c)}`)}if(t>0){let c=Date.now()>=E?`time budget (${Math.round(z/6e4)}m)`:t>=C?`hard cap (${C})`:"queue empty";e(` Facet drain stopped on ${c} after ${t} session(s); the rest resume next run.`)}}let _=await ns(s,r);if(!_)throw new M("No session data found \u2014 ensure sessions are captured and enriched.");e(` Found ${_.stats.sessions} sessions, generating recommendations...`);let y=await Y({projectId:r,projectPath:s},h);_.summary+=`
2
2
 
3
3
  ${y.text}`,e(` Session evidence: ${y.sessionIds.length} usable, ${y.failedSessionIds.length} unavailable`);let S=await ts(s,e);S&&e(` Generator memory: ${S.split(`
4
4
  `).length} lines of prior-advice context`);let o={},$=[],w=k.length+1;for(let t=0;t<k.length;t++){let i=k[t];e(` [${t+1}/${w}] Generating ${i.name}...`);try{await m(`/api/insights-jobs/${n}/progress`,{status:"running",progress:{step:i.name,current:t+1,total:w,partial:{...o}}})}catch(d){e(` Warning: progress update failed for ${i.name}: ${d instanceof Error?d.message:String(d)}`)}e(` Running LLM prompt for ${i.name}...`);let c=i.usesGeneratorMemory&&S?`${_.summary}
@@ -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.scopedConfirmation&&o.push("--session-id",n,"--tools","Read,Write,Edit,Bash"),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};
@@ -0,0 +1 @@
1
+ import{b as R,c as $,f as s,g as I,i as w}from"./chunk-XXPWPKTD.js";import{c as re}from"./chunk-5TM7AOH2.js";import{b as te}from"./chunk-IEQDLURA.js";import{d as oe,e as se,f as ae}from"./chunk-KINIFUZQ.js";import{b as F}from"./chunk-U3YPVLM3.js";import{a as Y}from"./chunk-TQM7MF5C.js";import{a as q}from"./chunk-WOANSBMJ.js";import{a as U}from"./chunk-ZYGBABMZ.js";import{a as G}from"./chunk-GIQ2HK3W.js";import{a as W}from"./chunk-TTZWVZIW.js";import{c as N}from"./chunk-FZMO7XSN.js";import{a as O}from"./chunk-5A6TMSRO.js";import{a as V}from"./chunk-HYQ5YKBC.js";import{a as J}from"./chunk-KOORMTZO.js";import{b as L}from"./chunk-5RBLIVBF.js";import{a as Q}from"./chunk-Q7IDLOSP.js";import{a as x}from"./chunk-CZBO3A6B.js";import{a as ee}from"./chunk-USKRCVX3.js";import{a as X}from"./chunk-7YZURVZD.js";import{a as D}from"./chunk-PZS55PW2.js";import{a as ne}from"./chunk-QPAOX7P2.js";import{e as P}from"./chunk-EFEPD4AZ.js";import{b as K}from"./chunk-E4CIJ67Z.js";import{a as Z}from"./chunk-D4FP5M2B.js";import{a as z}from"./chunk-VUNJGZPP.js";import{a as j}from"./chunk-GGUXEZC3.js";import{b as C}from"./chunk-PIVEJTNF.js";import{k as B}from"./chunk-KGU2IW54.js";import{d as S}from"./chunk-GPBN4ROE.js";import{b as M,e as T,f as E}from"./chunk-GIXHG5FK.js";import{a as l}from"./chunk-ZLLER3HP.js";var H=null,h=null,ue={process_eval:V,process_suggestion_eval:W,process_insights:J,process_launch:F,process_send_message:U,process_conversation:O,process_session_goal:G,distill_memories:K,memory_ab:Y,process_run_cleanup:q,cron_refine_cases:ee,cron_retire_unused_skills:ne,cron_reconcile_attribution:x,cron_suggest_instructions:P,cron_refresh_skills:D,cron_refresh_pricing:X,cron_eval_autorun:z,cron_auto_accept_suggestions:Z,cron_instruction_training:j,cron_instruction_evolution:B,process_judge_review:Q,harbor_ab:N},ie=Object.keys(ue),pe=new Set([]);function ge(e=process.env){return e.DATABASE_URL?ie:ie.filter(t=>!pe.has(t))}l(ge,"availableCapabilities");var _e=3e4,fe=3e4,ve=3e4,le=500,de=1e4,ke=`thin-agent-${process.pid}`,A=null;function be(e,t,r,p){let d;try{let i=S();d={claude:i.claudeBin!=null,codex:i.codexBin!=null,pi:i.piBin!=null,codexModel:i.codexConfiguredModel}}catch{}let m;try{m=C()}catch{}let g=l(i=>E("/api/workers/heartbeat",{workerType:"cli-worker",clientName:ke,clientVersion:p,workerVersion:"0.1.0",currentJobId:null,inFlightCount:0,lastError:null,status:i,metadata:{capabilities:e,mode:"thin-agent",measurementProtocol:1,studyProtocol:1,scopedCollector:2,memorySnapshots:1,boundedAutorun:1,llmEngines:d,harborReady:m,machine:H?.summary()}}).then(c=>{let u=c?.advisory;u&&u.message!==A?(A=u.message,s(r,{event:"worker_advisory",code:u.code,message:u.message})):u||(A=null)}).catch(c=>{s(r,{event:"presence_heartbeat_error",error:c instanceof Error?c.message:String(c)})}),"send");g("alive");let f=setInterval(()=>g("alive"),ve),a=null,n=l(()=>a||(clearInterval(f),a=Promise.race([g("shutting_down"),new Promise(i=>setTimeout(i,2e3).unref())]),a),"sayGoodbye");return t.addEventListener("abort",()=>{n()},{once:!0}),{shutdown:n}}l(be,"startPresenceHeartbeat");async function we(e,t,r=S()){let p=[...r.claudeBin?["claude"]:[],...r.codexBin?["codex"]:[],...r.piBin?["pi"]:[]],d=`capabilities=${encodeURIComponent(e.join(","))}&waitMs=${t}&measurementProtocol=1&studyProtocol=1&scopedCollector=2&memorySnapshots=1&boundedAutorun=1&measurementEngines=${encodeURIComponent(p.join(","))}`,m=await T(`/api/work/next?${d}`);return m==null||typeof m=="string"?null:m}l(we,"pollForWork");function he(e,t){return{logger:{info:l(r=>t(r),"info"),warn:l(r=>t(r),"warn"),error:l(r=>t(r),"error")},job:{attempts:e}}}l(he,"makeHelpers");async function ye(e,t,r,p){let d=ue[e.kind],m=Date.now();if(s(r,{event:"claim",jobId:e.id,kind:e.kind,attempts:e.attempts}),!d){let n=`unknown kind: ${e.kind}`;s(r,{event:"fail",jobId:e.id,kind:e.kind,terminal:!0,error:n}),await E(`/api/work/${e.id}/fail`,{leaseToken:e.leaseToken,error:n,terminal:!0}).catch(()=>{});return}let g=l(()=>{s(r,{event:"heartbeat",jobId:e.id}),w(`/api/work/${e.id}/heartbeat`,{leaseToken:e.leaseToken},{budgetMs:Math.min($,Math.max(0,t-1e3)),signal:p,log:r,event:"heartbeat",jobId:e.id}).then(n=>{n.ok||s(r,{event:"heartbeat_error",jobId:e.id,attempts:n.attempts,error:n.error instanceof Error?n.error.message:String(n.error)})})},"beat"),f=setInterval(g,t);h={jobId:e.id,beat:g};let a;try{let n=he(e.attempts,r);a={kind:"complete",result:await d(e.payload,n)??{}}}catch(n){let i=H?.pausesSince(m)??[],c=ae(i),u=n instanceof Error?n.message:String(n),v=L(n),o=!v&&se(i);a={kind:"fail",message:c?`${c}; ${u}`:u,pausedDuringJob:!!c,terminal:v,hostSuspended:o}}try{if(a.kind==="complete"){s(r,{event:"complete",jobId:e.id,kind:e.kind,durationMs:Date.now()-m});let n=await w(`/api/work/${e.id}/complete`,{leaseToken:e.leaseToken,result:a.result},{budgetMs:R,signal:p,log:r,event:"complete_post",jobId:e.id});n.ok||s(r,{event:"complete_post_error",jobId:e.id,kind:e.kind,attempts:n.attempts,error:n.error instanceof Error?n.error.message:String(n.error)})}else{s(r,{event:"fail",jobId:e.id,kind:e.kind,durationMs:Date.now()-m,terminal:a.terminal,error:a.message,...a.pausedDuringJob?{pausedDuringJob:!0}:{},...a.hostSuspended?{hostSuspended:!0}:{}});let n=await w(`/api/work/${e.id}/fail`,{leaseToken:e.leaseToken,error:a.message,terminal:a.terminal,hostSuspended:a.hostSuspended},{budgetMs:R,signal:p,log:r,event:"fail_post",jobId:e.id});n.ok||s(r,{event:"fail_post_error",jobId:e.id,attempts:n.attempts,error:n.error instanceof Error?n.error.message:String(n.error)})}}finally{clearInterval(f),h=null}}l(ye,"runOne");var ce=new Set(["process_eval","process_suggestion_eval","process_conversation","process_insights","process_session_goal","distill_memories","memory_ab","cron_suggest_instructions","cron_eval_autorun","cron_instruction_evolution","process_judge_review","harbor_ab"]);async function en(e){let t=e.log??(()=>{}),r=e.pollWaitMs??_e,p=e.heartbeatIntervalMs??fe,d=e.capabilities??ge();s(t,{event:"agent_start",capabilities:d,pollWaitMs:r,heartbeatIntervalMs:p});try{let o=te();o.removed.length>0&&s(t,{event:"eval_worktrees_swept",removed:o.removed.length})}catch(o){s(t,{event:"eval_worktree_sweep_failed",error:o instanceof Error?o.message:String(o)})}H=oe({signal:e.signal,onPause:l(o=>{s(t,{event:"machine_pause",...o,jobId:h?.jobId??null}),h?.beat()},"onPause")});let m=be(d,e.signal,t,e.version);re({signal:e.signal,log:t}).catch(o=>{s(t,{event:"tt_heartbeat_fatal",error:o instanceof Error?o.message:String(o)})});let g=5*6e4,f=0,a=l(()=>{if(!e.readInstalledVersion||!e.version)return!1;let o=Date.now();if(o-f<g)return!1;f=o;let b=e.readInstalledVersion();return!!(b&&b!==e.version)},"versionDrifted"),n=new AbortController,i=n.signal;e.signal.aborted?n.abort():e.signal.addEventListener("abort",()=>n.abort(),{once:!0});let c=l(async(o,b)=>{let _=le;for(;!i.aborted;){if(a()){s(t,{event:"agent_version_drift",bootVersion:e.version,installedVersion:e.readInstalledVersion?.()??null}),n.abort(),e.onVersionDrift?.();break}let y=null;try{y=await we([...b],r)}catch(k){let me=k instanceof M?k.statusCode:void 0;if(s(t,{event:"poll_error",lane:o,status:me,error:k instanceof Error?k.message:String(k)}),!await I(_,i))break;_=Math.min(_*2,de);continue}if(!y){if(s(t,{event:"poll_204",lane:o}),!await I(_,i))break;_=Math.min(_*2,de);continue}_=le,await ye(y,p,t,i)}},"runLane"),u=d.filter(o=>ce.has(o)),v=d.filter(o=>!ce.has(o));u.length>0&&v.length>0?(s(t,{event:"agent_lanes",heavy:u.length,fast:v.length}),await Promise.all([c("heavy",u),c("fast",v)])):await c("single",d),await m.shutdown(),s(t,{event:"agent_stop"})}l(en,"runAgentLoop");export{ue as a,ie as b,ge as c,we as d,en as e};
@@ -1,4 +1,4 @@
1
- import{a as U,b as F}from"./chunk-6T6YFPBW.js";import{a as h,b as I}from"./chunk-ISYU5BMU.js";import{a as w,b as k,e as R}from"./chunk-LJRE3LZ2.js";import{d as $}from"./chunk-GYNZ3OZF.js";import{g as C,i as D,j as P}from"./chunk-UPFH72PF.js";import{e as v,f as x,i as j}from"./chunk-GIXHG5FK.js";import{D as S,F as b,G as T,o as A}from"./chunk-X6CF5KTW.js";import{a as l}from"./chunk-ZLLER3HP.js";import*as u from"node:fs";import*as m from"node:path";var O=new Set(["mcp","subagent","feature"]);function ie(e,t,n){return L(m.join(e,"CLAUDE.md"),t,n)}l(ie,"appendToCLAUDEmd");function L(e,t,n){let i=w(t),s=k(t),a=u.existsSync(e)?u.readFileSync(e,"utf8"):"";if(a.includes(i))return!1;let p=`${a.length>0&&!a.endsWith(`
1
+ import{a as U,b as F}from"./chunk-6T6YFPBW.js";import{a as h,b as I}from"./chunk-ISYU5BMU.js";import{a as $,b as k,e as R}from"./chunk-LJRE3LZ2.js";import{d as w}from"./chunk-GYNZ3OZF.js";import{g as C,i as D,j as P}from"./chunk-UPFH72PF.js";import{e as v,f as x,i as j}from"./chunk-GIXHG5FK.js";import{D as b,F as S,G as T,o as A}from"./chunk-X6CF5KTW.js";import{a as l}from"./chunk-ZLLER3HP.js";import*as u from"node:fs";import*as m from"node:path";var O=new Set(["mcp","subagent","feature"]);function ie(e,t,n){return E(m.join(e,"CLAUDE.md"),t,n)}l(ie,"appendToCLAUDEmd");function E(e,t,n){let i=$(t),s=k(t),a=u.existsSync(e)?u.readFileSync(e,"utf8"):"";if(a.includes(i))return!1;let p=`${a.length>0&&!a.endsWith(`
2
2
  `)?`
3
3
 
4
4
  `:a.length>0?`
@@ -6,7 +6,7 @@ import{a as U,b as F}from"./chunk-6T6YFPBW.js";import{a as h,b as I}from"./chunk
6
6
  ${i}
7
7
  ${n}
8
8
  ${s}
9
- `;return u.mkdirSync(m.dirname(e),{recursive:!0}),u.writeFileSync(e,a+p,"utf8"),!0}l(L,"appendBlockToFile");function E(e,t,n,i={}){return $(e,i).filter(s=>L(s.path,t,n))}l(E,"appendToAgentInstructionFiles");function _(e,t,n={}){return $(e,n).filter(i=>M(i.path,t))}l(_,"removeFromAgentInstructionFiles");function re(e,t){return M(m.join(e,"CLAUDE.md"),t)}l(re,"removeFromCLAUDEmd");function M(e,t){if(!u.existsSync(e))return!1;let n=w(t),i=k(t),s=u.readFileSync(e,"utf8"),a=s.indexOf(n);if(a===-1)return!1;let c=s.indexOf(i,a);if(c===-1)return!1;let p=s.slice(0,a),d=s.slice(c+i.length),o=(p.replace(/\n+$/,"")+`
10
- `+d.replace(/^\n+/,"")).replace(/^\n+/,"");return u.writeFileSync(e,o,"utf8"),!0}l(M,"removeBlockFromFile");function g(e,t=90){return e.length<=t?e:`${e.slice(0,t-1)}\u2026`}l(g,"truncate");function q(e){return v(`/api/instruction-suggestions/${encodeURIComponent(e)}`)}l(q,"fetchSuggestion");async function ae(e){let t=e.suggestion??await q(e.suggestionId);if(t.kind==="remove")return B(e,t);if(t.kind==="trim")return K(e,t);let n=t.instructionId;t.instructionScope==="public"&&(n=(await x(`/api/instructions/${encodeURIComponent(t.instructionId)}/promote-from-public`,{targetScope:"personal"})).instructionId);let i=await v(`/api/instructions/${encodeURIComponent(n)}`),a=i.type!=="skill"&&i.type!=="hook"&&!O.has(i.type??"")?T(i.content,r=>u.existsSync(m.join(e.dir,r))):[];if(a.length>0)return await I(e.suggestionId,e.projectPath,n,e.actor,"unresolvable_reference"),{action:"unresolvable-reference",instructionId:n,name:i.name,fileModified:!1,unresolvable:a,messages:[`Refused: ${i.name} tells the agent to run something this project does not have.`,...a.map(r=>` ${r.path} \u2014 no such file under ${e.dir}`),"Nothing was written. A confident instruction pointing at a file that is not there costs every future session the time it takes to discover that."]};let c;if(!e.force){let r=S(i.content,R(e.dir)),N=e.actor==="auto"?r.matches.length>0:r.redundant;if(!r.redundant&&r.matches.length>0&&(c=r),N){let y=r.redundant;return await I(e.suggestionId,e.projectPath,n,e.actor,y?"redundant":"partial_overlap"),{action:"redundant",instructionId:n,name:i.name,fileModified:!1,redundancy:r,partialOverlap:y?void 0:r,messages:[y?`Skipped: ${i.name} already applies here in different words \u2014 adding it would spend context to say the same thing twice.`:`Refused: ${r.matches.length} of ${r.matches.length+r.novel.length} asks in ${i.name} are already covered here, so adopting it would restate the file back at itself.`,...r.matches.map(f=>` "${g(f.directive)}"
11
- already covered by ${f.matchedSource??f.matchedId} (${(f.similarity*100).toFixed(0)}% match): "${g(f.matchedDirective)}"`),...y?[]:["Still wanted, and not adopted:",...r.novel.map(f=>` "${g(f)}"`),"Propose those on their own and they can be adopted, tracked and undone individually."],"Add it anyway with `--force` if the overlap is not real."]}}}if(i.type==="skill")return H(e,{...i,id:n});if(i.type==="hook")return F(e,{...i,id:n});if(O.has(i.type??""))return{action:"manual-required",instructionId:n,name:i.name,fileModified:!1,messages:[`Not installed: ${i.name} is a ${i.type} artifact, and installing one runs code or edits tool configuration \u2014 that always requires a human.`,` Review it: rulemetric instructions get ${n}`,"Nothing was written. This proposal will keep appearing until you act on it or dismiss it."]};let p=E(e.dir,n,i.content),d=p.length>0;await h(e.suggestionId,e.projectPath,n,e.actor);let o=d&&c?[` Note: ${c.matches.length} of ${c.matches.length+c.novel.length} asks in this rule already appear elsewhere in context; it was added for the rest.`,...c.matches.map(r=>` "${g(r.directive)}"
12
- repeats ${r.matchedSource??r.matchedId} (${(r.similarity*100).toFixed(0)}%): "${g(r.matchedDirective)}"`)]:[];return{action:d?"added":"already-present",instructionId:n,name:i.name,fileModified:d,partialOverlap:d?c:void 0,messages:d?[`Accepted: added ${i.name} to ${p.map(r=>m.relative(e.dir,r.path)).join(", ")}. It will be active starting in your next session.`,...o]:[`Already present: ${i.name} is already in CLAUDE.md (block id: ${n}).`]}}l(ae,"acceptSuggestion");async function H(e,t){if(!e.force){let o=b({name:t.name,content:t.content},D(e.dir));if(o)return await I(e.suggestionId,e.projectPath,t.id,e.actor),{action:"redundant",instructionId:t.id,name:t.name,fileModified:!1,duplicateOf:o,messages:[`Skipped: ${t.name} is already installed here as ${o.name}`+(o.reason==="name-stem"?" (same skill, different content-hash suffix).":` (${(o.similarity*100).toFixed(0)}% identical body).`),` Installed: ${P(e.dir,o.name)}`,"A second copy is not more available \u2014 it is one more thing to keep in sync."]}}let n=C({dir:e.dir,name:t.name,content:t.content,description:t.description}),i=[...n.warnings],s=[m.relative(e.dir,n.skillFile)];n.linkKind!=="none"&&s.push(m.relative(e.dir,n.linkPath));let a={boundaryClass:"inside",targets:s,requires:[],provides:[`skill:${n.dirName}`]},c={kind:"delete-paths",paths:s},p=A(a,c);if(p.length===0)try{await U({instructionId:t.id,projectPath:e.projectPath,targetPath:n.skillFile,beforeHash:"",appliedHash:"",boundaryClass:a.boundaryClass,targets:a.targets,inverse:c,requires:a.requires,provides:a.provides,applyMode:e.actor==="auto"?"auto":"human"})}catch(o){i.push(`the effect ledger did not record this install (${o instanceof Error?o.message:String(o)}) \u2014 \`suggestions undo\` will not remove it; delete ${s.join(" and ")} by hand.`)}else i.push(`no reversible inverse could be recorded (${p.map(o=>o.message).join("; ")}).`);await h(e.suggestionId,e.projectPath,t.id,e.actor);let d=[`Accepted: installed skill ${n.dirName} to ${m.relative(e.dir,n.skillFile)}.`];n.linkKind==="none"&&d.push("Claude Code will NOT see it yet \u2014 its path is taken by a directory this command did not create."),d.push("It loads on demand, so it costs no context until a task matches its description."),d.push(`Undo with: rulemetric suggestions undo ${t.id}`);for(let o of i)d.push(` Warning: ${o}`);return{action:"added",instructionId:t.id,name:t.name,fileModified:!0,messages:d}}l(H,"acceptSkill");async function K(e,t){let n=t.estimatedTokens?` It currently costs roughly ${t.estimatedTokens} tokens per session (estimated).`:"";return await h(e.suggestionId,e.projectPath,t.instructionId,e.actor),{action:"acknowledged",instructionId:t.instructionId,name:t.name,fileModified:!1,messages:[`Noted: ${t.name} is measured neutral, not harmful.${n}`,"Nothing was changed \u2014 trimming is a judgement call about which parts carry the value,","and the measurement only found the absence of a detectable effect, not which half to cut.",` View it: rulemetric instructions get ${t.instructionId}`," Then edit CLAUDE.md (or the instruction) and let the next measurement cycle re-check it.","This suggestion will stop re-surfacing."]}}l(K,"acknowledgeTrim");async function B(e,t){let n=_(e.dir,t.instructionId).length>0;await j(`/api/instructions/${encodeURIComponent(t.instructionId)}`);let i=t.estimatedTokens?` Frees roughly ${t.estimatedTokens} tokens of context per session (estimated).`:"",s=n?[`Retired: removed ${t.name} from CLAUDE.md and archived it.${i}`]:[`Archived ${t.name}.${i}`,"CLAUDE.md was not modified \u2014 no rulemetric-managed block for this instruction was found in this directory. If you added it by hand, remove it yourself."];return s.push("Undo with: rulemetric instructions restore "+t.instructionId),await h(e.suggestionId,e.projectPath,t.instructionId,e.actor),{action:n?"retired":"archived-only",instructionId:t.instructionId,name:t.name,fileModified:n,messages:s}}l(B,"acceptRemoval");export{ie as a,L as b,E as c,_ as d,re as e,M as f,q as g,ae as h};
9
+ `;return u.mkdirSync(m.dirname(e),{recursive:!0}),u.writeFileSync(e,a+p,"utf8"),!0}l(E,"appendBlockToFile");function N(e,t,n,i={}){return w(e,i).filter(s=>E(s.path,t,n))}l(N,"appendToAgentInstructionFiles");function _(e,t,n={}){return w(e,n).filter(i=>L(i.path,t))}l(_,"removeFromAgentInstructionFiles");function re(e,t){return L(m.join(e,"CLAUDE.md"),t)}l(re,"removeFromCLAUDEmd");function L(e,t){if(!u.existsSync(e))return!1;let n=$(t),i=k(t),s=u.readFileSync(e,"utf8"),a=s.indexOf(n);if(a===-1)return!1;let c=s.indexOf(i,a);if(c===-1)return!1;let p=s.slice(0,a),d=s.slice(c+i.length),o=(p.replace(/\n+$/,"")+`
10
+ `+d.replace(/^\n+/,"")).replace(/^\n+/,"");return u.writeFileSync(e,o,"utf8"),!0}l(L,"removeBlockFromFile");function g(e,t=90){return e.length<=t?e:`${e.slice(0,t-1)}\u2026`}l(g,"truncate");function q(e){return v(`/api/instruction-suggestions/${encodeURIComponent(e)}`)}l(q,"fetchSuggestion");async function ae(e){let t=e.suggestion??await q(e.suggestionId);if(t.kind==="remove")return B(e,t);if(t.kind==="trim")return K(e,t);if(t.broadAdoptionAllowed===!1)throw new Error("Scoped study owns delivery; no broad adoption authority");let n=t.instructionId;t.instructionScope==="public"&&(n=(await x(`/api/instructions/${encodeURIComponent(t.instructionId)}/promote-from-public`,{targetScope:"personal"})).instructionId);let i=await v(`/api/instructions/${encodeURIComponent(n)}`),a=i.type!=="skill"&&i.type!=="hook"&&!O.has(i.type??"")?T(i.content,r=>u.existsSync(m.join(e.dir,r))):[];if(a.length>0)return await I(e.suggestionId,e.projectPath,n,e.actor,"unresolvable_reference"),{action:"unresolvable-reference",instructionId:n,name:i.name,fileModified:!1,unresolvable:a,messages:[`Refused: ${i.name} tells the agent to run something this project does not have.`,...a.map(r=>` ${r.path} \u2014 no such file under ${e.dir}`),"Nothing was written. A confident instruction pointing at a file that is not there costs every future session the time it takes to discover that."]};let c;if(!e.force){let r=b(i.content,R(e.dir)),M=e.actor==="auto"?r.matches.length>0:r.redundant;if(!r.redundant&&r.matches.length>0&&(c=r),M){let y=r.redundant;return await I(e.suggestionId,e.projectPath,n,e.actor,y?"redundant":"partial_overlap"),{action:"redundant",instructionId:n,name:i.name,fileModified:!1,redundancy:r,partialOverlap:y?void 0:r,messages:[y?`Skipped: ${i.name} already applies here in different words \u2014 adding it would spend context to say the same thing twice.`:`Refused: ${r.matches.length} of ${r.matches.length+r.novel.length} asks in ${i.name} are already covered here, so adopting it would restate the file back at itself.`,...r.matches.map(f=>` "${g(f.directive)}"
11
+ already covered by ${f.matchedSource??f.matchedId} (${(f.similarity*100).toFixed(0)}% match): "${g(f.matchedDirective)}"`),...y?[]:["Still wanted, and not adopted:",...r.novel.map(f=>` "${g(f)}"`),"Propose those on their own and they can be adopted, tracked and undone individually."],"Add it anyway with `--force` if the overlap is not real."]}}}if(i.type==="skill")return H(e,{...i,id:n});if(i.type==="hook")return F(e,{...i,id:n});if(O.has(i.type??""))return{action:"manual-required",instructionId:n,name:i.name,fileModified:!1,messages:[`Not installed: ${i.name} is a ${i.type} artifact, and installing one runs code or edits tool configuration \u2014 that always requires a human.`,` Review it: rulemetric instructions get ${n}`,"Nothing was written. This proposal will keep appearing until you act on it or dismiss it."]};let p=N(e.dir,n,i.content),d=p.length>0;await h(e.suggestionId,e.projectPath,n,e.actor);let o=d&&c?[` Note: ${c.matches.length} of ${c.matches.length+c.novel.length} asks in this rule already appear elsewhere in context; it was added for the rest.`,...c.matches.map(r=>` "${g(r.directive)}"
12
+ repeats ${r.matchedSource??r.matchedId} (${(r.similarity*100).toFixed(0)}%): "${g(r.matchedDirective)}"`)]:[];return{action:d?"added":"already-present",instructionId:n,name:i.name,fileModified:d,partialOverlap:d?c:void 0,messages:d?[`Accepted: added ${i.name} to ${p.map(r=>m.relative(e.dir,r.path)).join(", ")}. It will be active starting in your next session.`,...o]:[`Already present: ${i.name} is already in CLAUDE.md (block id: ${n}).`]}}l(ae,"acceptSuggestion");async function H(e,t){if(!e.force){let o=S({name:t.name,content:t.content},D(e.dir));if(o)return await I(e.suggestionId,e.projectPath,t.id,e.actor),{action:"redundant",instructionId:t.id,name:t.name,fileModified:!1,duplicateOf:o,messages:[`Skipped: ${t.name} is already installed here as ${o.name}`+(o.reason==="name-stem"?" (same skill, different content-hash suffix).":` (${(o.similarity*100).toFixed(0)}% identical body).`),` Installed: ${P(e.dir,o.name)}`,"A second copy is not more available \u2014 it is one more thing to keep in sync."]}}let n=C({dir:e.dir,name:t.name,content:t.content,description:t.description}),i=[...n.warnings],s=[m.relative(e.dir,n.skillFile)];n.linkKind!=="none"&&s.push(m.relative(e.dir,n.linkPath));let a={boundaryClass:"inside",targets:s,requires:[],provides:[`skill:${n.dirName}`]},c={kind:"delete-paths",paths:s},p=A(a,c);if(p.length===0)try{await U({instructionId:t.id,projectPath:e.projectPath,targetPath:n.skillFile,beforeHash:"",appliedHash:"",boundaryClass:a.boundaryClass,targets:a.targets,inverse:c,requires:a.requires,provides:a.provides,applyMode:e.actor==="auto"?"auto":"human"})}catch(o){i.push(`the effect ledger did not record this install (${o instanceof Error?o.message:String(o)}) \u2014 \`suggestions undo\` will not remove it; delete ${s.join(" and ")} by hand.`)}else i.push(`no reversible inverse could be recorded (${p.map(o=>o.message).join("; ")}).`);await h(e.suggestionId,e.projectPath,t.id,e.actor);let d=[`Accepted: installed skill ${n.dirName} to ${m.relative(e.dir,n.skillFile)}.`];n.linkKind==="none"&&d.push("Claude Code will NOT see it yet \u2014 its path is taken by a directory this command did not create."),d.push("It loads on demand, so it costs no context until a task matches its description."),d.push(`Undo with: rulemetric suggestions undo ${t.id}`);for(let o of i)d.push(` Warning: ${o}`);return{action:"added",instructionId:t.id,name:t.name,fileModified:!0,messages:d}}l(H,"acceptSkill");async function K(e,t){let n=t.estimatedTokens?` It currently costs roughly ${t.estimatedTokens} tokens per session (estimated).`:"";return await h(e.suggestionId,e.projectPath,t.instructionId,e.actor),{action:"acknowledged",instructionId:t.instructionId,name:t.name,fileModified:!1,messages:[`Noted: ${t.name} is measured neutral, not harmful.${n}`,"Nothing was changed \u2014 trimming is a judgement call about which parts carry the value,","and the measurement only found the absence of a detectable effect, not which half to cut.",` View it: rulemetric instructions get ${t.instructionId}`," Then edit CLAUDE.md (or the instruction) and let the next measurement cycle re-check it.","This suggestion will stop re-surfacing."]}}l(K,"acknowledgeTrim");async function B(e,t){let n=_(e.dir,t.instructionId).length>0;await j(`/api/instructions/${encodeURIComponent(t.instructionId)}`);let i=t.estimatedTokens?` Frees roughly ${t.estimatedTokens} tokens of context per session (estimated).`:"",s=n?[`Retired: removed ${t.name} from CLAUDE.md and archived it.${i}`]:[`Archived ${t.name}.${i}`,"CLAUDE.md was not modified \u2014 no rulemetric-managed block for this instruction was found in this directory. If you added it by hand, remove it yourself."];return s.push("Undo with: rulemetric instructions restore "+t.instructionId),await h(e.suggestionId,e.projectPath,t.instructionId,e.actor),{action:n?"retired":"archived-only",instructionId:t.instructionId,name:t.name,fileModified:n,messages:s}}l(B,"acceptRemoval");export{ie as a,E as b,N as c,_ as d,re as e,L as f,q as g,ae as h};
@@ -1 +1 @@
1
- import{a as G,c as I}from"./chunk-FADINV4H.js";import{f as j}from"./chunk-SWSOEYC7.js";import{a as R}from"./chunk-FG343JM3.js";import{b as U}from"./chunk-HT6R6KR3.js";import{f as A}from"./chunk-4GOXEEXZ.js";import{b as P,e as C,h as _}from"./chunk-GIXHG5FK.js";import{a as x}from"./chunk-ZLLER3HP.js";var J=x(l=>l.summary.pass_rate===1?1:0,"fullPassScore");async function z(l,d={}){let $=d.executeEval??A,M=d.grade??R,q=d.getExperiment??(async o=>{try{return await C(`/api/memory-experiments/${o}`)}catch(e){if(e instanceof P&&e.statusCode===404)return null;throw e}}),B=d.getMemoryBody??(async o=>{try{let e=await C(`/api/memories/${o}`);return t?.memoryVersion!=null&&e.version!==t.memoryVersion?null:e.body}catch(e){if(e instanceof P&&e.statusCode===404)return null;throw e}}),p=d.updateExperiment??(async(o,e)=>{await _(`/api/memory-experiments/${o}`,e)}),t=await q(l.experimentId);if(!t)return{skipped:"not_found"};if(t.status==="completed"||t.status==="failed")return{skipped:"already_terminal",status:t.status};let E=t.memoryBody??await B(t.memoryId);if(E==null)return await p(t.id,{status:"failed",error:"memory no longer exists or its queued version is no longer available"}),{skipped:"memory_gone",status:"failed"};await p(t.id,{status:"running"});let v=t.expectations??[],c=t.model??void 0,i=t.engine??"claude",g=G({engine:i,model:c},{engine:l.graderEngine,model:l.graderModel}),f=x(async o=>{let e=(d.createWorkspace??j)({engine:i,targetType:"prompt",targetContent:o});try{if(e.leakedFiles.length)throw new Error("Contaminated memory trial workspace");return await $({prompt:t.taskPrompt,targetContent:e.systemPrompt,appendTarget:!0,ignoreContextFiles:!0,workDir:e.workDir,model:c,engine:i})}finally{e.cleanup()}},"executeArm"),s=[],u=new Set,b,k,m=[],w=0;try{if(l.measurement){let e=I(l);if(e.engine!==i||e.model!==c)throw new Error("Memory experiment differs from its queued measurement snapshot");g={engine:e.graderEngine,model:e.graderModel}}for(let e=0;e<t.trials;e++){let[r,n]=e%2===0?[await f(E),await f()]:await(async()=>{let y=await f();return[await f(E),y]})();if(r.error||n.error||r.exitCode!==0||n.exitCode!==0||!r.output.trim()||!n.output.trim()){w++,m.push({trial:e+1,reason:(r.error??n.error??"Nonzero exit or empty output").slice(0,500)});continue}if(r.engine!==i||n.engine!==i||!r.model||!n.model||r.model!==n.model||r.provider!==n.provider||r.model&&u.size>0&&!u.has(r.model)||i==="pi"&&c&&r.model!==`pi:${c}`){w++,m.push({trial:e+1,reason:"Harness, provider or model changed within the experiment"});continue}r.model&&u.add(r.model),n.model&&u.add(n.model);let[a,h]=await Promise.all([M({prompt:t.taskPrompt,output:r.output,expectations:v,...g}),M({prompt:t.taskPrompt,output:n.output,expectations:v,...g})]),T=JSON.stringify([a.judge_engine??null,a.judge_model??null]);if([a,h].some(y=>y.summary.pass_rate==null||y.summary.errored||y.summary.total!==v.length)||a.judge_model!==h.judge_model||a.judge_engine!==h.judge_engine||b!==void 0&&b!==T){w++,m.push({trial:e+1,reason:"Grading incomplete or judge changed; not a model failure"});continue}b=T,k={engine:a.judge_engine??null,model:a.judge_model??null},s.push({withScore:J(a),withoutScore:J(h),withLatency:r.durationMs/1e3,withoutLatency:n.durationMs/1e3,withTokens:r.totalTokens,withoutTokens:n.totalTokens,...r.costUsd!==void 0?{withCostUsd:r.costUsd}:{},...n.costUsd!==void 0?{withoutCostUsd:n.costUsd}:{}})}if(s.length===0){let e=`no trials completed (${w}/${t.trials} runs errored \u2014 is the ${i} CLI available?)`;return await p(t.id,{status:"failed",error:e,result:{pairs:s,excluded:m,completedTrials:0,engine:i}}),{status:"failed",requestedTrials:t.trials,completedTrials:0}}let o=U(s.map(e=>({...e,withCost:e.withCostUsd,withoutCost:e.withoutCostUsd})));return await p(t.id,{status:"completed",result:{verdict:o,pairs:s,excluded:m,judge:g,actualJudge:k,methodology:"v2-neutral-appended-memory",completedTrials:s.length,engine:i,model:[...u][0]}}),{status:"completed",requestedTrials:t.trials,completedTrials:s.length,significant:o.significant,delta:o.delta}}catch(o){let e=o instanceof Error?o.message:String(o);return await p(t.id,{status:"failed",error:e.slice(0,500),result:{pairs:s,excluded:m,completedTrials:s.length,engine:i,model:[...u][0]??null,judge:g,actualJudge:k,methodology:"v2-neutral-appended-memory"}}).catch(()=>{}),{status:"failed",requestedTrials:t.trials,completedTrials:s.length}}}x(z,"processMemoryAb");export{z as a};
1
+ import{a as G,c as I}from"./chunk-FADINV4H.js";import{f as j}from"./chunk-SWSOEYC7.js";import{a as R}from"./chunk-FG343JM3.js";import{b as U}from"./chunk-KFNFLMUR.js";import{f as A}from"./chunk-4GOXEEXZ.js";import{b as P,e as C,h as _}from"./chunk-GIXHG5FK.js";import{a as x}from"./chunk-ZLLER3HP.js";var J=x(l=>l.summary.pass_rate===1?1:0,"fullPassScore");async function z(l,d={}){let $=d.executeEval??A,M=d.grade??R,q=d.getExperiment??(async o=>{try{return await C(`/api/memory-experiments/${o}`)}catch(e){if(e instanceof P&&e.statusCode===404)return null;throw e}}),B=d.getMemoryBody??(async o=>{try{let e=await C(`/api/memories/${o}`);return t?.memoryVersion!=null&&e.version!==t.memoryVersion?null:e.body}catch(e){if(e instanceof P&&e.statusCode===404)return null;throw e}}),p=d.updateExperiment??(async(o,e)=>{await _(`/api/memory-experiments/${o}`,e)}),t=await q(l.experimentId);if(!t)return{skipped:"not_found"};if(t.status==="completed"||t.status==="failed")return{skipped:"already_terminal",status:t.status};let E=t.memoryBody??await B(t.memoryId);if(E==null)return await p(t.id,{status:"failed",error:"memory no longer exists or its queued version is no longer available"}),{skipped:"memory_gone",status:"failed"};await p(t.id,{status:"running"});let v=t.expectations??[],c=t.model??void 0,i=t.engine??"claude",g=G({engine:i,model:c},{engine:l.graderEngine,model:l.graderModel}),f=x(async o=>{let e=(d.createWorkspace??j)({engine:i,targetType:"prompt",targetContent:o});try{if(e.leakedFiles.length)throw new Error("Contaminated memory trial workspace");return await $({prompt:t.taskPrompt,targetContent:e.systemPrompt,appendTarget:!0,ignoreContextFiles:!0,workDir:e.workDir,model:c,engine:i})}finally{e.cleanup()}},"executeArm"),s=[],u=new Set,b,k,m=[],w=0;try{if(l.measurement){let e=I(l);if(e.engine!==i||e.model!==c)throw new Error("Memory experiment differs from its queued measurement snapshot");g={engine:e.graderEngine,model:e.graderModel}}for(let e=0;e<t.trials;e++){let[r,n]=e%2===0?[await f(E),await f()]:await(async()=>{let y=await f();return[await f(E),y]})();if(r.error||n.error||r.exitCode!==0||n.exitCode!==0||!r.output.trim()||!n.output.trim()){w++,m.push({trial:e+1,reason:(r.error??n.error??"Nonzero exit or empty output").slice(0,500)});continue}if(r.engine!==i||n.engine!==i||!r.model||!n.model||r.model!==n.model||r.provider!==n.provider||r.model&&u.size>0&&!u.has(r.model)||i==="pi"&&c&&r.model!==`pi:${c}`){w++,m.push({trial:e+1,reason:"Harness, provider or model changed within the experiment"});continue}r.model&&u.add(r.model),n.model&&u.add(n.model);let[a,h]=await Promise.all([M({prompt:t.taskPrompt,output:r.output,expectations:v,...g}),M({prompt:t.taskPrompt,output:n.output,expectations:v,...g})]),T=JSON.stringify([a.judge_engine??null,a.judge_model??null]);if([a,h].some(y=>y.summary.pass_rate==null||y.summary.errored||y.summary.total!==v.length)||a.judge_model!==h.judge_model||a.judge_engine!==h.judge_engine||b!==void 0&&b!==T){w++,m.push({trial:e+1,reason:"Grading incomplete or judge changed; not a model failure"});continue}b=T,k={engine:a.judge_engine??null,model:a.judge_model??null},s.push({withScore:J(a),withoutScore:J(h),withLatency:r.durationMs/1e3,withoutLatency:n.durationMs/1e3,withTokens:r.totalTokens,withoutTokens:n.totalTokens,...r.costUsd!==void 0?{withCostUsd:r.costUsd}:{},...n.costUsd!==void 0?{withoutCostUsd:n.costUsd}:{}})}if(s.length===0){let e=`no trials completed (${w}/${t.trials} runs errored \u2014 is the ${i} CLI available?)`;return await p(t.id,{status:"failed",error:e,result:{pairs:s,excluded:m,completedTrials:0,engine:i}}),{status:"failed",requestedTrials:t.trials,completedTrials:0}}let o=U(s.map(e=>({...e,withCost:e.withCostUsd,withoutCost:e.withoutCostUsd})));return await p(t.id,{status:"completed",result:{verdict:o,pairs:s,excluded:m,judge:g,actualJudge:k,methodology:"v2-neutral-appended-memory",completedTrials:s.length,engine:i,model:[...u][0]}}),{status:"completed",requestedTrials:t.trials,completedTrials:s.length,significant:o.significant,delta:o.delta}}catch(o){let e=o instanceof Error?o.message:String(o);return await p(t.id,{status:"failed",error:e.slice(0,500),result:{pairs:s,excluded:m,completedTrials:s.length,engine:i,model:[...u][0]??null,judge:g,actualJudge:k,methodology:"v2-neutral-appended-memory"}}).catch(()=>{}),{status:"failed",requestedTrials:t.trials,completedTrials:s.length}}}x(z,"processMemoryAb");export{z as a};
@@ -1 +1 @@
1
- import{b as m}from"./chunk-74KE4VOX.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
+ import{b as m}from"./chunk-65LFPUDB.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};
@@ -0,0 +1 @@
1
+ import{a as d}from"./chunk-I6W2KC6W.js";import{a as g}from"./chunk-HYQ5YKBC.js";import{e as c,h as p}from"./chunk-GIXHG5FK.js";import{a as i}from"./chunk-ZLLER3HP.js";import{createHash as l}from"node:crypto";import{z as r}from"zod";var m=r.object({content:r.string().min(1),name:r.string().min(1),type:r.enum(["instruction","skill"]),contentHash:r.string().regex(/^[a-f0-9]{64}$/),suggestionId:r.string().uuid()}).strict();async function w(e,u){let t=m.parse(e.candidateSnapshot);if(l("sha256").update(t.content).digest("hex")!==t.contentHash)throw new Error("Candidate snapshot hash mismatch");let o=e.preparationSourceJobId?{preparationSourceJobId:e.preparationSourceJobId}:await g({...e,candidateSnapshot:t,config:{...e.config,parallel:1,runsPerEval:1,iteration:1,skipBaseline:!1,skipGrading:!1,generateIfEmpty:!0,timeout:12e4}},u);if((await c(`/api/eval-targets/${e.evalTargetId}/jobs`)).find(s=>s.id===e.mirrorId)?.status==="cancelled")return{...o,cancelled:!0,adoptionAllowed:!1};let a;try{a=await d({evalTargetId:e.evalTargetId,evalJobId:e.preparationSourceJobId??e.mirrorId,...t})}catch(s){a={status:"blocked",reason:s instanceof Error?s.message:String(s)}}let n={...o,livePreparation:a,evidenceKind:"constructed_evaluation",candidateHash:t.contentHash,suggestionId:t.suggestionId,adoptionAllowed:!1};return await p(`/api/eval-jobs/${e.mirrorId}/state`,{result:n}),n}i(w,"processSuggestionEval");export{w as a};
@@ -0,0 +1 @@
1
+ import{b as l}from"./chunk-IG4JMWFK.js";import{a as f}from"./chunk-5RBLIVBF.js";import{a as p}from"./chunk-EHW2KS6R.js";import{h as m}from"./chunk-GIXHG5FK.js";import{a as c}from"./chunk-ZLLER3HP.js";async function d(t){if(!t.worktree?.create)return t;let{branch:n,baseRef:i}=t.worktree,o=await l({repoRoot:t.projectPath,branch:n,baseRef:i});return{...t,projectPath:o.path,gitBranch:o.branch}}c(d,"resolveWorktreeForLaunch");async function j(t,n){let{mirrorId:i,tool:o}=t,{config:r}=t,a=c(e=>n.logger.info(e),"log");if(n.job.attempts>1)throw new f(`process_launch is not safe to retry (attempt ${n.job.attempts}). Re-launch manually.`);r=await d(r),r.worktree?.create&&a(`Worktree resolved: ${r.projectPath} (branch ${r.gitBranch})`),a(`Launching ${o}...`);let{getLauncher:g}=await import("./dist-UAAG2IWQ.js"),u=await g(o).launch(r);a(`Launch completed: sessionId=${u.sessionId}`);let s;if(r.scopedConfirmation&&r.mode==="headless")try{s=await p(r,u.sessionId)}catch(e){s={status:"unmeasured",reason:e instanceof Error?e.message:String(e)}}let h={...u,...s?{studyOutcome:s}:{},worktreePath:r.worktree?.create?r.projectPath:void 0,runId:r.runId};return await m(`/api/launch-jobs/${i}/state`,{result:h}).catch(e=>{a(`result persist failed: ${e instanceof Error?e.message:String(e)}`)}),h}c(j,"processLaunch");export{d as a,j as b};
@@ -1 +1 @@
1
- import{b as u,c as d}from"./chunk-EJY5GK6A.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
+ import{b as u,c as d}from"./chunk-TSLBCZ5P.js";import{b as g}from"./chunk-HBDKOU2N.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,4 +1,4 @@
1
- import{b as $}from"./chunk-HXOQUYG3.js";import{a as C}from"./chunk-PDXHRF4E.js";import{a as y}from"./chunk-FG343JM3.js";import{f}from"./chunk-4GOXEEXZ.js";import{e as h,f as w}from"./chunk-GIXHG5FK.js";import{a as v}from"./chunk-ZLLER3HP.js";async function N(n,i,p){let{conversationId:a,messageId:g,messageContent:r}=n,o=await h(`/api/eval-targets/${i}`),c=await h(`/api/eval-targets/${i}/evals`),e=await h(`/api/eval-conversations/${a}/messages`),t=e.findIndex(l=>l.id===g);if(t>=0&&e.slice(t+1).some(u=>u.role==="assistant"&&(u.type==="results"||u.type==="proposal"||u.type==="generated"||u.type==="text"))){p(`Message ${g} already processed \u2014 skipping (idempotency guard)`);return}let s=v(async(l,u,m)=>{await w(`/api/eval-conversations/${a}/messages/assistant`,{content:l,type:u,data:m})},"postMessage"),d=await _(o,c,e,r,p);p(`Action: ${d.action}`);try{switch(d.action){case"run_evals":await x(o,c,a,s,p);break;case"generate_cases":await k(o,i,a,s,p);break;case"analyze_results":case"propose_changes":await E(o,c,e,r,a,s,p);break;case"respond":await s(d.response,"text");break}}catch(l){let u=l instanceof Error?l.message:String(l);throw await s(`Something went wrong: ${u}`,"text").catch(()=>{}),l}}v(N,"processConversationJob");async function _(n,i,p,a,g){let r=p.slice(-10).map(e=>`${e.role}: ${e.content.slice(0,200)}`).join(`
1
+ import{b as $}from"./chunk-HBDKOU2N.js";import{a as C}from"./chunk-PDXHRF4E.js";import{a as y}from"./chunk-FG343JM3.js";import{f}from"./chunk-4GOXEEXZ.js";import{e as h,f as w}from"./chunk-GIXHG5FK.js";import{a as v}from"./chunk-ZLLER3HP.js";async function N(n,i,p){let{conversationId:a,messageId:g,messageContent:r}=n,o=await h(`/api/eval-targets/${i}`),c=await h(`/api/eval-targets/${i}/evals`),e=await h(`/api/eval-conversations/${a}/messages`),t=e.findIndex(l=>l.id===g);if(t>=0&&e.slice(t+1).some(u=>u.role==="assistant"&&(u.type==="results"||u.type==="proposal"||u.type==="generated"||u.type==="text"))){p(`Message ${g} already processed \u2014 skipping (idempotency guard)`);return}let s=v(async(l,u,m)=>{await w(`/api/eval-conversations/${a}/messages/assistant`,{content:l,type:u,data:m})},"postMessage"),d=await _(o,c,e,r,p);p(`Action: ${d.action}`);try{switch(d.action){case"run_evals":await x(o,c,a,s,p);break;case"generate_cases":await k(o,i,a,s,p);break;case"analyze_results":case"propose_changes":await E(o,c,e,r,a,s,p);break;case"respond":await s(d.response,"text");break}}catch(l){let u=l instanceof Error?l.message:String(l);throw await s(`Something went wrong: ${u}`,"text").catch(()=>{}),l}}v(N,"processConversationJob");async function _(n,i,p,a,g){let r=p.slice(-10).map(e=>`${e.role}: ${e.content.slice(0,200)}`).join(`
2
2
  `),o=`You are an eval assistant. Decide what action to take based on the user's message.
3
3
 
4
4
  ## Current State
@@ -1,2 +1,2 @@
1
- import{c as f}from"./chunk-ISFPPDDB.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}
1
+ import{c as f}from"./chunk-IG4JMWFK.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,2 +1,2 @@
1
- import{c as E,n as m}from"./chunk-T75KAEJO.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(`
1
+ import{c as E,n as m}from"./chunk-MMMT34KO.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{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(`
1
+ import{h as E}from"./chunk-DHIEGG4T.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{c as q,d as K}from"../chunk-TYFEWLYZ.js";import{b as L,c as W}from"../chunk-V5U3E4BZ.js";import{a as J}from"../chunk-2TJ7Q2OU.js";import{e as O,f as _,g as M}from"../chunk-QWCEZEDO.js";import"../chunk-KKDHD4XA.js";import"../chunk-SZ62CP55.js";import{d as oe,e as ne}from"../chunk-DYET4EYU.js";import"../chunk-M7QSC64D.js";import"../chunk-7LFCZI64.js";import"../chunk-CMDOLJ23.js";import{i as z,j as Q,k as Z,m as ee,n as te}from"../chunk-TWPD3ICV.js";import"../chunk-G7V4ZZZ3.js";import"../chunk-LJE5J3EW.js";import"../chunk-AHLVY52I.js";import"../chunk-YXMAGC53.js";import"../chunk-T7HZZ4DJ.js";import"../chunk-XCH4HPEZ.js";import"../chunk-PPAHIVG5.js";import"../chunk-CT7FWSIU.js";import"../chunk-5MXZJWQS.js";import"../chunk-N7ODX6PO.js";import{a as V}from"../chunk-OZQNSELV.js";import"../chunk-HFGO5762.js";import"../chunk-VS5ROGDP.js";import"../chunk-FADINV4H.js";import"../chunk-SWSOEYC7.js";import"../chunk-U2NT5OSQ.js";import"../chunk-KGURGIZ2.js";import"../chunk-GYNZ3OZF.js";import"../chunk-UPFH72PF.js";import"../chunk-FG343JM3.js";import"../chunk-CDY7TQFZ.js";import"../chunk-HT6R6KR3.js";import"../chunk-4GOXEEXZ.js";import"../chunk-JP6ULOEX.js";import"../chunk-JNLDISBA.js";import{d as F}from"../chunk-GPBN4ROE.js";import"../chunk-6XTLP2G7.js";import"../chunk-PJ3WHQ67.js";import{a as X,b as D,c as Y,g as j,h as G}from"../chunk-QI3FJKGK.js";import{a as B}from"../chunk-WUCACPGC.js";import"../chunk-IZTIYR5Q.js";import"../chunk-WL5ZWQAS.js";import"../chunk-KEVDLLHT.js";import"../chunk-DX6IPDED.js";import"../chunk-3AV3GTMP.js";import{a as U,e as y}from"../chunk-GIXHG5FK.js";import"../chunk-X6CF5KTW.js";import"../chunk-XQYAVSUQ.js";import{a as N,g as v,l as x}from"../chunk-PZNWH4VQ.js";import{a as S}from"../chunk-ZLLER3HP.js";import{spawnSync as le}from"node:child_process";import{existsSync as ce,readFileSync as ue}from"node:fs";import{join as se}from"node:path";var I=class h extends B{static{S(this,"Diagnostics")}static description='Diagnose capture / proxy / connectivity problems (e.g. a client-side "502 Bad Gateway")';static examples=["<%= config.bin %> diagnostics"];baseUrl(){return process.env.RULEMETRIC_API_URL??N().apiUrl??U}async checkDirect(){let r=process.env.HTTPS_PROXY,i=process.env.HTTP_PROXY;delete process.env.HTTPS_PROXY,delete process.env.HTTP_PROXY;let s=new AbortController,l=setTimeout(()=>s.abort(),8e3);try{return(await globalThis.fetch(`${this.baseUrl()}/health`,{signal:s.signal})).ok}catch{return!1}finally{clearTimeout(l),r!==void 0&&(process.env.HTTPS_PROXY=r),i!==void 0&&(process.env.HTTP_PROXY=i)}}configuredProxy(){if(process.env.HTTPS_PROXY)return process.env.HTTPS_PROXY;for(let r of["settings.local.json","settings.json"]){let i=se(process.cwd(),".claude",r);if(ce(i))try{let s=JSON.parse(ue(i,"utf8"));if(s.env?.HTTPS_PROXY)return s.env.HTTPS_PROXY}catch{}}return null}checkThroughProxy(r){let i=le("curl",["-sS","-x",r,"--max-time","8","-o","/dev/null","-w","%{http_code}",`${this.baseUrl()}/health`],{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return i.error||typeof i.stdout!="string"?null:i.stdout.trim()==="200"}async run(){await this.parse(h);let r=process.version,i=this.configuredProxy(),s=i!=null,[l,m,d]=await Promise.all([this.checkDirect(),M(O),M(_)]),p=s&&i?this.checkThroughProxy(i):null,t=S((e,c,T)=>{let u=c===null?"\u2013":c?"[OK]":"[!!]";this.log(` ${u} ${e.padEnd(22)} ${T}`)},"line");this.log("RuleMetric diagnostics"),this.log(""),t("Node",!L(r),`${r}${L(r)?" (< 20.11 \u2014 breaks the bundled proxy)":""}`),t("API (direct)",l,`${this.baseUrl()}/health ${l?"reachable":"UNREACHABLE"}`),t("Authenticated",v(),v()?"yes":"no \u2014 run `rulemetric auth login`"),t("Proxy configured",s?!0:null,s?i:"no HTTPS_PROXY set"),s&&(t("Gateway :"+O,m,m?"listening":"NOT listening"),t("mitmproxy :"+_,d,d?"listening":"not listening (gateway should route direct)"),t("API (via proxy)",p,p===null?"inconclusive (curl unavailable)":p?"reachable":"FAILED \u2014 502/blocked through your proxy"));let a=F();t("claude CLI",a.claudeBin!=null,a.claudeBin??"not found \u2014 LLM features (grading, distill) will no-op"),t("codex CLI",a.codexBin!=null?!0:null,a.codexBin?`${a.codexBin}${a.codexConfiguredModel?` (model ${a.codexConfiguredModel})`:""}`:"not found \u2014 optional; enables the cross-vendor reviewer (evals validate-judge)");let o=null;if(v()&&l)try{o=await y("/api/workers/health")}catch{o=null}if(o){let e=o.worker;t("Worker",!!e.active,e.present?e.active?`online (last heartbeat ${e.ageSeconds??"?"}s ago${e.clientVersion?`, v${e.clientVersion}`:""})`:`NOT RUNNING \u2014 last heartbeat ${A(e.ageSeconds)} ago`:"never connected \u2014 no worker has ever reported in");let c=o.worker.engines;if(c!=null){let u=[c.claude&&"claude",c.codex&&"codex"].filter(Boolean);t("LLM engine",u.length>0,u.length>0?`${u.join(" + ")} available to the worker`:"NONE \u2014 the worker found no `claude` and no `codex`. LLM jobs will complete with empty output rather than failing.")}let T=o.pending.reduce((u,E)=>u+E.count,0);if(T>0){let u=o.verdict.stuck.reduce(($,k)=>$+k.count,0),E=o.verdict.unclaimable.reduce(($,k)=>$+k.count,0),R=(o.verdict.engineBlocked??[]).reduce(($,k)=>$+k.count,0);t("Job queue",u===0&&R===0,`${T} pending`+(u>0?` \u2014 ${u} waiting on this worker`:"")+(R>0?` \u2014 ${R} need a local LLM engine`:"")+(E>0?` \u2014 ${E} need a worker with DATABASE_URL`:""))}else t("Job queue",!0,"empty")}else v()&&l&&t("Worker",null,"could not read /workers/health (older API?)");let n=o?.worker.machine;if(n){let e=n.suspends+n.stalls,c=n.lastPause;t("Worker pauses",e===0?!0:null,e===0?`none since ${n.since} \u2014 no sleep or stall seen by the worker`:`${n.suspends} suspend${n.suspends===1?"":"s"}`+(n.stalls>0?` + ${n.stalls} event-loop stall${n.stalls===1?"":"s"}`:"")+` since ${n.since}, ${A(Math.round(n.pausedMs/1e3))} paused total`+(c?`; last: ${c.kind} of ${A(Math.round(c.wallGapMs/1e3))} ending ${c.detectedAt}`:"")+" \u2014 jobs in flight during a suspend lose their lease and are redone on wake")}let f=await q();if(f){t("Machine sleep (pmset)",f.sleeps===0?!0:null,K(f));for(let e of f.recent.slice(-3)){let c=e.seconds!=null?` (${A(e.seconds)})`:"";this.log(` \u21B3 ${e.at.toISOString()} ${e.kind}${c}: ${e.reason.slice(0,80)}`)}}let C=V(process.cwd()),g=await D({configDir:x()}),re=await Y({configDir:x()}),w=` \u2014 ${G(re)}`,b=J(process.cwd()),H=[b.user&&`user hooks (${b.user})`,b.workspace&&`workspace hooks (${b.workspace})`].filter(Boolean),ie={claude_code:`session hooks (+ proxy for instruction linking)${w}`,codex:`worker transcript sync of ~/.codex/sessions \u2014 ${j(g)}`,cursor:`user hooks (~/.cursor/hooks.json)${w}`,copilot_agent:`workspace hooks${w}`,antigravity:H.length>0?`${H.join(" + ")}${w}`:"NOT CAPTURED \u2014 no rulemetric block in ~/.gemini/config/hooks.json or .agents/hooks.json; run `rulemetric hooks install` (user hooks are on by default)"};this.log(""),this.log(" Capture coverage (agents found on this machine):");for(let e of C)this.log(` \u2022 ${e.padEnd(15)} ${ie[e]??"captured"}`);if(C.includes("codex"))if(g.error)this.log(` ! ${g.error}`);else if(g.mode==="allowlist")for(let e of g.roots)this.log(` \u21B3 ${e}`);else g.mode==="all"&&this.log(` \u21B3 scope it with ${se(x(),X)} ({"codex":{"roots":["/path/to/repo"]}}) or RULEMETRIC_CODEX_CAPTURE=off`);o&&!o.worker.active&&C.includes("codex")&&g.mode!=="off"&&this.log(" ! Codex capture runs INSIDE the worker \u2014 it is stopped while the worker is down."),v()&&l&&await this.reportEvolutionSpend();let P=W({nodeVersion:r,directApiOk:l,httpsProxySet:s,gatewayAlive:m,mitmproxyAlive:d,proxyPathOk:p});this.log("");let ae=P.severity==="ok"?"[OK]":P.severity==="warn"?"[!!]":"[XX]";this.log(`${ae} ${P.headline}`);for(let e of P.hints)this.log(` \u2022 ${e}`);if(o&&o.verdict.severity!=="ok"){let e=o.verdict.severity==="warn"?"[!!]":"[XX]";this.log(""),this.log(`${e} ${o.verdict.headline}`);for(let c of o.verdict.hints)this.log(` \u2022 ${c}`)}}async reportEvolutionSpend(){let r;try{r=await y("/api/eval-targets?type=instruction&limit=200")}catch{return}let i=r.filter(s=>{let l=s.metadata??{};return l.autoEvolveEnabled===!0||l.autoEvolveEnabled==="true"});if(i.length!==0){this.log(""),this.log(" Nightly instruction evolution (cron_instruction_evolution, 07:30 UTC):");for(let s of i){let l=s.metadata??{},m=Q(l),d=z(l);if(m){this.log(` \u2022 ${s.name} \u2014 PAUSED (metadata.autoEvolvePaused). Opt-in preserved.`),this.log(" \u21B3 resume: set autoEvolvePaused=false");continue}let p=null;try{p=(await y(`/api/eval-targets/${s.id}/evals`)).filter(a=>!a.retiredAt).length}catch{}if(this.log(` \u2022 ${s.name}`),p!=null){let t=ne(p,d.minPairs,oe(d,p));if(!t.feasible)this.log(` \u21B3 cannot reach a verdict \u2014 ${t.reason}`);else{let a=Z({liveCases:p,passes:t.passes});this.log(` \u21B3 each night: ${te(a)}`)}}this.log(` \u21B3 pairs budget ${d.minPairs}`+(d.configured?" (metadata.autoEvolvePairs)":" (default)")+` \xB7 writes ${l.autoEvolveApply===!0||l.autoEvolveApply==="true"?"ENABLED":"off (dry run)"}`),d.note&&this.log(` ! ${d.note}`);try{let t=await y(`/api/eval-targets/${s.id}/promotions?limit=1`),a=t.promotions[0];if(a){let n=a.gates?.cost,f=n?.modelCalls?`${n.modelCalls} model calls, ${n.usablePairs??"?"} usable pair(s)`+(n.mde!=null?`, resolved +/-${ee(n.mde)}`:"")+(n.wallMs?`, ${(n.wallMs/6e4).toFixed(0)} min`:""):"cost not recorded (decision predates cost tracking)";this.log(` \u21B3 last run ${new Date(a.createdAt).toISOString().slice(0,10)}: ${a.decision}${a.applied?" (APPLIED)":""} \u2014 ${f}`)}let o=t.counts??{};this.log(` \u21B3 lifetime: ${o.promote??0} promote / ${o.revert??0} revert / ${o.refuse??0} refuse`)}catch{}}this.log(" \u21B3 pause the spend: metadata.autoEvolvePaused=true (keeps the opt-in)")}}};function A(h){if(h===null)return"never";if(h<90)return`${Math.round(h)}s`;let r=Math.round(h/60);return r<90?`${r}m`:`${Math.round(r/60)}h`}S(A,"formatAge");export{I as default};
1
+ import{c as q,d as K}from"../chunk-TYFEWLYZ.js";import{b as L,c as W}from"../chunk-V5U3E4BZ.js";import{a as J}from"../chunk-2TJ7Q2OU.js";import{e as O,f as _,g as M}from"../chunk-QWCEZEDO.js";import"../chunk-KKDHD4XA.js";import"../chunk-SZ62CP55.js";import{d as oe,e as ne}from"../chunk-KGU2IW54.js";import"../chunk-M7QSC64D.js";import"../chunk-ZKPURXUS.js";import"../chunk-ISEUEYSC.js";import{i as z,j as Q,k as Z,m as ee,n as te}from"../chunk-GYKYJJNF.js";import"../chunk-G7V4ZZZ3.js";import"../chunk-LJE5J3EW.js";import"../chunk-AHLVY52I.js";import"../chunk-YXMAGC53.js";import"../chunk-T7HZZ4DJ.js";import"../chunk-DHIEGG4T.js";import"../chunk-PPAHIVG5.js";import"../chunk-5MXZJWQS.js";import"../chunk-CT7FWSIU.js";import"../chunk-N7ODX6PO.js";import{a as V}from"../chunk-OZQNSELV.js";import"../chunk-HFGO5762.js";import"../chunk-VS5ROGDP.js";import"../chunk-FADINV4H.js";import"../chunk-SWSOEYC7.js";import"../chunk-U2NT5OSQ.js";import"../chunk-KGURGIZ2.js";import"../chunk-GYNZ3OZF.js";import"../chunk-UPFH72PF.js";import"../chunk-FG343JM3.js";import"../chunk-CDY7TQFZ.js";import"../chunk-KFNFLMUR.js";import"../chunk-4GOXEEXZ.js";import"../chunk-JP6ULOEX.js";import"../chunk-JNLDISBA.js";import{d as F}from"../chunk-GPBN4ROE.js";import"../chunk-6XTLP2G7.js";import"../chunk-PJ3WHQ67.js";import{a as X,b as D,c as Y,g as j,h as G}from"../chunk-QI3FJKGK.js";import{a as B}from"../chunk-WUCACPGC.js";import"../chunk-IZTIYR5Q.js";import"../chunk-WL5ZWQAS.js";import"../chunk-KEVDLLHT.js";import"../chunk-DX6IPDED.js";import"../chunk-3AV3GTMP.js";import{a as U,e as y}from"../chunk-GIXHG5FK.js";import"../chunk-X6CF5KTW.js";import"../chunk-XQYAVSUQ.js";import{a as N,g as v,l as x}from"../chunk-PZNWH4VQ.js";import{a as S}from"../chunk-ZLLER3HP.js";import{spawnSync as le}from"node:child_process";import{existsSync as ce,readFileSync as ue}from"node:fs";import{join as se}from"node:path";var I=class h extends B{static{S(this,"Diagnostics")}static description='Diagnose capture / proxy / connectivity problems (e.g. a client-side "502 Bad Gateway")';static examples=["<%= config.bin %> diagnostics"];baseUrl(){return process.env.RULEMETRIC_API_URL??N().apiUrl??U}async checkDirect(){let r=process.env.HTTPS_PROXY,i=process.env.HTTP_PROXY;delete process.env.HTTPS_PROXY,delete process.env.HTTP_PROXY;let s=new AbortController,l=setTimeout(()=>s.abort(),8e3);try{return(await globalThis.fetch(`${this.baseUrl()}/health`,{signal:s.signal})).ok}catch{return!1}finally{clearTimeout(l),r!==void 0&&(process.env.HTTPS_PROXY=r),i!==void 0&&(process.env.HTTP_PROXY=i)}}configuredProxy(){if(process.env.HTTPS_PROXY)return process.env.HTTPS_PROXY;for(let r of["settings.local.json","settings.json"]){let i=se(process.cwd(),".claude",r);if(ce(i))try{let s=JSON.parse(ue(i,"utf8"));if(s.env?.HTTPS_PROXY)return s.env.HTTPS_PROXY}catch{}}return null}checkThroughProxy(r){let i=le("curl",["-sS","-x",r,"--max-time","8","-o","/dev/null","-w","%{http_code}",`${this.baseUrl()}/health`],{encoding:"utf8",stdio:["ignore","pipe","ignore"]});return i.error||typeof i.stdout!="string"?null:i.stdout.trim()==="200"}async run(){await this.parse(h);let r=process.version,i=this.configuredProxy(),s=i!=null,[l,m,d]=await Promise.all([this.checkDirect(),M(O),M(_)]),p=s&&i?this.checkThroughProxy(i):null,t=S((e,c,T)=>{let u=c===null?"\u2013":c?"[OK]":"[!!]";this.log(` ${u} ${e.padEnd(22)} ${T}`)},"line");this.log("RuleMetric diagnostics"),this.log(""),t("Node",!L(r),`${r}${L(r)?" (< 20.11 \u2014 breaks the bundled proxy)":""}`),t("API (direct)",l,`${this.baseUrl()}/health ${l?"reachable":"UNREACHABLE"}`),t("Authenticated",v(),v()?"yes":"no \u2014 run `rulemetric auth login`"),t("Proxy configured",s?!0:null,s?i:"no HTTPS_PROXY set"),s&&(t("Gateway :"+O,m,m?"listening":"NOT listening"),t("mitmproxy :"+_,d,d?"listening":"not listening (gateway should route direct)"),t("API (via proxy)",p,p===null?"inconclusive (curl unavailable)":p?"reachable":"FAILED \u2014 502/blocked through your proxy"));let a=F();t("claude CLI",a.claudeBin!=null,a.claudeBin??"not found \u2014 LLM features (grading, distill) will no-op"),t("codex CLI",a.codexBin!=null?!0:null,a.codexBin?`${a.codexBin}${a.codexConfiguredModel?` (model ${a.codexConfiguredModel})`:""}`:"not found \u2014 optional; enables the cross-vendor reviewer (evals validate-judge)");let o=null;if(v()&&l)try{o=await y("/api/workers/health")}catch{o=null}if(o){let e=o.worker;t("Worker",!!e.active,e.present?e.active?`online (last heartbeat ${e.ageSeconds??"?"}s ago${e.clientVersion?`, v${e.clientVersion}`:""})`:`NOT RUNNING \u2014 last heartbeat ${A(e.ageSeconds)} ago`:"never connected \u2014 no worker has ever reported in");let c=o.worker.engines;if(c!=null){let u=[c.claude&&"claude",c.codex&&"codex"].filter(Boolean);t("LLM engine",u.length>0,u.length>0?`${u.join(" + ")} available to the worker`:"NONE \u2014 the worker found no `claude` and no `codex`. LLM jobs will complete with empty output rather than failing.")}let T=o.pending.reduce((u,E)=>u+E.count,0);if(T>0){let u=o.verdict.stuck.reduce(($,k)=>$+k.count,0),E=o.verdict.unclaimable.reduce(($,k)=>$+k.count,0),R=(o.verdict.engineBlocked??[]).reduce(($,k)=>$+k.count,0);t("Job queue",u===0&&R===0,`${T} pending`+(u>0?` \u2014 ${u} waiting on this worker`:"")+(R>0?` \u2014 ${R} need a local LLM engine`:"")+(E>0?` \u2014 ${E} need a worker with DATABASE_URL`:""))}else t("Job queue",!0,"empty")}else v()&&l&&t("Worker",null,"could not read /workers/health (older API?)");let n=o?.worker.machine;if(n){let e=n.suspends+n.stalls,c=n.lastPause;t("Worker pauses",e===0?!0:null,e===0?`none since ${n.since} \u2014 no sleep or stall seen by the worker`:`${n.suspends} suspend${n.suspends===1?"":"s"}`+(n.stalls>0?` + ${n.stalls} event-loop stall${n.stalls===1?"":"s"}`:"")+` since ${n.since}, ${A(Math.round(n.pausedMs/1e3))} paused total`+(c?`; last: ${c.kind} of ${A(Math.round(c.wallGapMs/1e3))} ending ${c.detectedAt}`:"")+" \u2014 jobs in flight during a suspend lose their lease and are redone on wake")}let f=await q();if(f){t("Machine sleep (pmset)",f.sleeps===0?!0:null,K(f));for(let e of f.recent.slice(-3)){let c=e.seconds!=null?` (${A(e.seconds)})`:"";this.log(` \u21B3 ${e.at.toISOString()} ${e.kind}${c}: ${e.reason.slice(0,80)}`)}}let C=V(process.cwd()),g=await D({configDir:x()}),re=await Y({configDir:x()}),w=` \u2014 ${G(re)}`,b=J(process.cwd()),H=[b.user&&`user hooks (${b.user})`,b.workspace&&`workspace hooks (${b.workspace})`].filter(Boolean),ie={claude_code:`session hooks (+ proxy for instruction linking)${w}`,codex:`worker transcript sync of ~/.codex/sessions \u2014 ${j(g)}`,cursor:`user hooks (~/.cursor/hooks.json)${w}`,copilot_agent:`workspace hooks${w}`,antigravity:H.length>0?`${H.join(" + ")}${w}`:"NOT CAPTURED \u2014 no rulemetric block in ~/.gemini/config/hooks.json or .agents/hooks.json; run `rulemetric hooks install` (user hooks are on by default)"};this.log(""),this.log(" Capture coverage (agents found on this machine):");for(let e of C)this.log(` \u2022 ${e.padEnd(15)} ${ie[e]??"captured"}`);if(C.includes("codex"))if(g.error)this.log(` ! ${g.error}`);else if(g.mode==="allowlist")for(let e of g.roots)this.log(` \u21B3 ${e}`);else g.mode==="all"&&this.log(` \u21B3 scope it with ${se(x(),X)} ({"codex":{"roots":["/path/to/repo"]}}) or RULEMETRIC_CODEX_CAPTURE=off`);o&&!o.worker.active&&C.includes("codex")&&g.mode!=="off"&&this.log(" ! Codex capture runs INSIDE the worker \u2014 it is stopped while the worker is down."),v()&&l&&await this.reportEvolutionSpend();let P=W({nodeVersion:r,directApiOk:l,httpsProxySet:s,gatewayAlive:m,mitmproxyAlive:d,proxyPathOk:p});this.log("");let ae=P.severity==="ok"?"[OK]":P.severity==="warn"?"[!!]":"[XX]";this.log(`${ae} ${P.headline}`);for(let e of P.hints)this.log(` \u2022 ${e}`);if(o&&o.verdict.severity!=="ok"){let e=o.verdict.severity==="warn"?"[!!]":"[XX]";this.log(""),this.log(`${e} ${o.verdict.headline}`);for(let c of o.verdict.hints)this.log(` \u2022 ${c}`)}}async reportEvolutionSpend(){let r;try{r=await y("/api/eval-targets?type=instruction&limit=200")}catch{return}let i=r.filter(s=>{let l=s.metadata??{};return l.autoEvolveEnabled===!0||l.autoEvolveEnabled==="true"});if(i.length!==0){this.log(""),this.log(" Nightly instruction evolution (cron_instruction_evolution, 07:30 UTC):");for(let s of i){let l=s.metadata??{},m=Q(l),d=z(l);if(m){this.log(` \u2022 ${s.name} \u2014 PAUSED (metadata.autoEvolvePaused). Opt-in preserved.`),this.log(" \u21B3 resume: set autoEvolvePaused=false");continue}let p=null;try{p=(await y(`/api/eval-targets/${s.id}/evals`)).filter(a=>!a.retiredAt).length}catch{}if(this.log(` \u2022 ${s.name}`),p!=null){let t=ne(p,d.minPairs,oe(d,p));if(!t.feasible)this.log(` \u21B3 cannot reach a verdict \u2014 ${t.reason}`);else{let a=Z({liveCases:p,passes:t.passes});this.log(` \u21B3 each night: ${te(a)}`)}}this.log(` \u21B3 pairs budget ${d.minPairs}`+(d.configured?" (metadata.autoEvolvePairs)":" (default)")+` \xB7 writes ${l.autoEvolveApply===!0||l.autoEvolveApply==="true"?"ENABLED":"off (dry run)"}`),d.note&&this.log(` ! ${d.note}`);try{let t=await y(`/api/eval-targets/${s.id}/promotions?limit=1`),a=t.promotions[0];if(a){let n=a.gates?.cost,f=n?.modelCalls?`${n.modelCalls} model calls, ${n.usablePairs??"?"} usable pair(s)`+(n.mde!=null?`, resolved +/-${ee(n.mde)}`:"")+(n.wallMs?`, ${(n.wallMs/6e4).toFixed(0)} min`:""):"cost not recorded (decision predates cost tracking)";this.log(` \u21B3 last run ${new Date(a.createdAt).toISOString().slice(0,10)}: ${a.decision}${a.applied?" (APPLIED)":""} \u2014 ${f}`)}let o=t.counts??{};this.log(` \u21B3 lifetime: ${o.promote??0} promote / ${o.revert??0} revert / ${o.refuse??0} refuse`)}catch{}}this.log(" \u21B3 pause the spend: metadata.autoEvolvePaused=true (keeps the opt-in)")}}};function A(h){if(h===null)return"never";if(h<90)return`${Math.round(h)}s`;let r=Math.round(h/60);return r<90?`${r}m`:`${Math.round(r/60)}h`}S(A,"formatAge");export{I as default};
@@ -1,3 +1,3 @@
1
- import{a as G,b as V,c as j,d as q}from"../../chunk-J4W6GNCF.js";import{b as M}from"../../chunk-GH4EZK2O.js";import{c as g}from"../../chunk-V576KKH6.js";import{e as D}from"../../chunk-N2PP2A7M.js";import"../../chunk-XXPWPKTD.js";import"../../chunk-5TM7AOH2.js";import"../../chunk-IEQDLURA.js";import"../../chunk-KINIFUZQ.js";import"../../chunk-5PMTNNA6.js";import"../../chunk-ZYGBABMZ.js";import"../../chunk-IFIWDL7G.js";import"../../chunk-FZMO7XSN.js";import"../../chunk-LLXC5SRC.js";import"../../chunk-4DA6L7KL.js";import"../../chunk-JU5ZNXPK.js";import"../../chunk-WQFR2LOY.js";import"../../chunk-Q7IDLOSP.js";import"../../chunk-XIOYV5A7.js";import"../../chunk-ISFPPDDB.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-JSGXFD42.js";import"../../chunk-CZBO3A6B.js";import"../../chunk-JUBXWTJA.js";import"../../chunk-W6MMJRFZ.js";import"../../chunk-PZS55PW2.js";import"../../chunk-QPAOX7P2.js";import"../../chunk-3ZHVP3KE.js";import"../../chunk-CIKQXFQ2.js";import"../../chunk-HOQPVOMF.js";import"../../chunk-5Z6XXOJL.js";import"../../chunk-MOJY6S5J.js";import"../../chunk-CYCH2EQC.js";import"../../chunk-CVPAKEEZ.js";import"../../chunk-VUNJGZPP.js";import"../../chunk-L562Y4RN.js";import"../../chunk-GLBWNB2N.js";import"../../chunk-CQD2R3BA.js";import"../../chunk-3UKZJAFS.js";import"../../chunk-77FH6UZP.js";import"../../chunk-KE5K3F7J.js";import"../../chunk-PIVEJTNF.js";import"../../chunk-KR36ZDGN.js";import"../../chunk-JOXTWLLK.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-SIGZEQ3K.js";import"../../chunk-DQYYHX6K.js";import"../../chunk-RE7RAZQ5.js";import"../../chunk-6T6YFPBW.js";import"../../chunk-ISYU5BMU.js";import"../../chunk-DANMUHNW.js";import"../../chunk-T75KAEJO.js";import"../../chunk-FXQS7AEZ.js";import"../../chunk-LJRE3LZ2.js";import"../../chunk-EJY5GK6A.js";import"../../chunk-74KE4VOX.js";import"../../chunk-HXOQUYG3.js";import"../../chunk-3H44B6PB.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-MODXEGCU.js";import"../../chunk-MHVHGKDK.js";import"../../chunk-RBSEE2Z6.js";import"../../chunk-PDXHRF4E.js";import"../../chunk-DYET4EYU.js";import"../../chunk-M7QSC64D.js";import"../../chunk-7LFCZI64.js";import"../../chunk-CMDOLJ23.js";import"../../chunk-TWPD3ICV.js";import"../../chunk-G7V4ZZZ3.js";import"../../chunk-LJE5J3EW.js";import"../../chunk-AHLVY52I.js";import"../../chunk-YXMAGC53.js";import"../../chunk-T7HZZ4DJ.js";import"../../chunk-XCH4HPEZ.js";import"../../chunk-PPAHIVG5.js";import"../../chunk-CT7FWSIU.js";import"../../chunk-5MXZJWQS.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-OZQNSELV.js";import"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import"../../chunk-FADINV4H.js";import"../../chunk-SWSOEYC7.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-GYNZ3OZF.js";import"../../chunk-UPFH72PF.js";import"../../chunk-FG343JM3.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-HT6R6KR3.js";import"../../chunk-4GOXEEXZ.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-JNLDISBA.js";import"../../chunk-GPBN4ROE.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{b as A,d as C,g as S,i as E,j as L,k as $}from"../../chunk-QI3FJKGK.js";import{a as O}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as m}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import{e as I,l as p}from"../../chunk-PZNWH4VQ.js";import{a as e}from"../../chunk-ZLLER3HP.js";import{trace as de,context as me}from"@opentelemetry/api";import{NodeSDK as W}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as Y}from"@opentelemetry/exporter-trace-otlp-http";import{BatchSpanProcessor as J,ConsoleSpanExporter as z,SimpleSpanProcessor as Q}from"@opentelemetry/sdk-trace-node";import{Resource as Z}from"@opentelemetry/resources";import{ATTR_SERVICE_NAME as ee,ATTR_SERVICE_VERSION as te}from"@opentelemetry/semantic-conventions";function F(r){if(!r)return{};let n={};for(let o of r.split(",")){let s=o.indexOf("=");if(s===-1)continue;let i=o.slice(0,s).trim(),c=o.slice(s+1).trim();i&&(n[i]=c)}return n}e(F,"parseOtlpHeaders");var u=null;function T(){return process.env.TELEMETRY_ENABLED!=="false"}e(T,"isTelemetryEnabled");function x(r){if(!T()||u!==null)return"off";let n=new Z({[ee]:r.serviceName,[te]:r.serviceVersion??"0.1.0"}),o=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,s,i;if(o){let c=F(process.env.OTEL_EXPORTER_OTLP_HEADERS),l=new Y({url:`${o}/v1/traces`,headers:c});i=new J(l),s="otlp"}else if(process.env.OTEL_SPAN_EXPORT==="none")i=void 0,s="silent";else{let c=new z;i=new Q(c),s="console"}return u=new W({resource:n,spanProcessors:i?[i]:[]}),u.start(),s}e(x,"initTelemetry");async function h(){u&&(await u.shutdown(),u=null)}e(h,"shutdownTelemetry");import{SpanKind as Pe,SpanStatusCode as Re}from"@opentelemetry/api";import{trace as Ie,context as Oe}from"@opentelemetry/api";import*as f from"@sentry/node";var v=!1;function w(r){if(v)return!1;let n=process.env.SENTRY_DSN;return n?(f.init({dsn:n,serverName:r.serviceName,environment:process.env.NODE_ENV??"development",tracesSampleRate:0}),v=!0,!0):!1}e(w,"initSentry");async function y(r){v&&await f.flush(r)}e(y,"flushSentry");import{existsSync as ne,mkdirSync as oe,readFileSync as k,unlinkSync as X,writeFileSync as U}from"node:fs";import{dirname as se,join as R}from"node:path";import{execFileSync as ie}from"node:child_process";var a=R(p(),"evals-agent.lock");function ce(r){try{return process.kill(r,0),!0}catch(n){return n.code==="EPERM"}}e(ce,"pidAlive");function ae(r){if(!ce(r))return!1;try{let n=ie("ps",["-p",String(r),"-o","command="],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return/run\.js\s+evals\s+agent|evals\s+agent/.test(n)}catch{return!0}}e(ae,"isLiveAgent");function le(){try{oe(se(a),{recursive:!0})}catch{}for(let r=0;r<2;r++)try{return U(a,String(process.pid),{flag:"wx"}),{ok:!0}}catch(n){if(n.code!=="EEXIST")throw n;let o=0;try{o=Number(k(a,"utf-8").trim())}catch{}if(o&&o!==process.pid&&ae(o))return{ok:!1,holder:o};try{X(a)}catch{}}try{U(a,String(process.pid))}catch{}return{ok:!0}}e(le,"acquireAgentLock");function P(){try{ne(a)&&Number(k(a,"utf-8").trim())===process.pid&&X(a)}catch{}}e(P,"releaseAgentLock");var N=class r extends O{static{e(this,"EvalAgentCommand")}static description="The worker daemon: long-polls /api/work/next, claims jobs, and runs them locally. Installed as a launchd service by `rulemetric service install`.";static examples=["<%= config.bin %> evals agent"];async run(){await this.parse(r),this.requireAuth();let n=le();if(!n.ok){this.log(`Another rulemetric evals agent is already running (pid ${n.holder}). Refusing to start a second instance.`);return}process.env.PG_APPLICATION_NAME||="rulemetric-agent",w({serviceName:"rulemetric-agent"})&&this.log("[sentry] error capture enabled");let s=x({serviceName:"rulemetric-agent"});s==="otlp"?this.log(`[otel] traces exporting to ${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}`):s==="console"?this.log("[otel] cron spans printing to stdout (set OTEL_EXPORTER_OTLP_ENDPOINT to ship to a backend)"):this.log("[otel] disabled (TELEMETRY_ENABLED=false)"),!I()&&!process.env.RULEMETRIC_API_KEY&&this.error("No auth token found. Run `rulemetric auth login` first."),this.log("Starting thin agent (Phase 4b parallel-run)..."),this.log(`Long-polling /api/work/next. Press Ctrl+C to stop.
1
+ import{a as G,b as V,c as j,d as q}from"../../chunk-J4W6GNCF.js";import{b as M}from"../../chunk-GH4EZK2O.js";import{c as g}from"../../chunk-HTAHNQZJ.js";import{e as D}from"../../chunk-OCCJEWOF.js";import"../../chunk-XXPWPKTD.js";import"../../chunk-5TM7AOH2.js";import"../../chunk-IEQDLURA.js";import"../../chunk-KINIFUZQ.js";import"../../chunk-U3YPVLM3.js";import"../../chunk-TQM7MF5C.js";import"../../chunk-WOANSBMJ.js";import"../../chunk-IG4JMWFK.js";import"../../chunk-ZYGBABMZ.js";import"../../chunk-GIQ2HK3W.js";import"../../chunk-TTZWVZIW.js";import"../../chunk-FZMO7XSN.js";import"../../chunk-MOJY6S5J.js";import"../../chunk-I6W2KC6W.js";import"../../chunk-5A6TMSRO.js";import"../../chunk-HYQ5YKBC.js";import"../../chunk-JU5ZNXPK.js";import"../../chunk-3WCX2SLU.js";import"../../chunk-KOORMTZO.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-Q7IDLOSP.js";import"../../chunk-CZBO3A6B.js";import"../../chunk-USKRCVX3.js";import"../../chunk-7YZURVZD.js";import"../../chunk-PZS55PW2.js";import"../../chunk-QPAOX7P2.js";import"../../chunk-3ZHVP3KE.js";import"../../chunk-EFEPD4AZ.js";import"../../chunk-HOQPVOMF.js";import"../../chunk-E4CIJ67Z.js";import"../../chunk-EHW2KS6R.js";import"../../chunk-D4FP5M2B.js";import"../../chunk-CVPAKEEZ.js";import"../../chunk-VUNJGZPP.js";import"../../chunk-GGUXEZC3.js";import"../../chunk-GLBWNB2N.js";import"../../chunk-CQD2R3BA.js";import"../../chunk-3UKZJAFS.js";import"../../chunk-77FH6UZP.js";import"../../chunk-KE5K3F7J.js";import"../../chunk-PIVEJTNF.js";import"../../chunk-KR36ZDGN.js";import"../../chunk-WL34G6IR.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-SIGZEQ3K.js";import"../../chunk-DQYYHX6K.js";import"../../chunk-RIYVZDOQ.js";import"../../chunk-6T6YFPBW.js";import"../../chunk-ISYU5BMU.js";import"../../chunk-DANMUHNW.js";import"../../chunk-MMMT34KO.js";import"../../chunk-FXQS7AEZ.js";import"../../chunk-LJRE3LZ2.js";import"../../chunk-TSLBCZ5P.js";import"../../chunk-65LFPUDB.js";import"../../chunk-HBDKOU2N.js";import"../../chunk-3H44B6PB.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-MODXEGCU.js";import"../../chunk-MHVHGKDK.js";import"../../chunk-RBSEE2Z6.js";import"../../chunk-PDXHRF4E.js";import"../../chunk-KGU2IW54.js";import"../../chunk-M7QSC64D.js";import"../../chunk-ZKPURXUS.js";import"../../chunk-ISEUEYSC.js";import"../../chunk-GYKYJJNF.js";import"../../chunk-G7V4ZZZ3.js";import"../../chunk-LJE5J3EW.js";import"../../chunk-AHLVY52I.js";import"../../chunk-YXMAGC53.js";import"../../chunk-T7HZZ4DJ.js";import"../../chunk-DHIEGG4T.js";import"../../chunk-PPAHIVG5.js";import"../../chunk-5MXZJWQS.js";import"../../chunk-CT7FWSIU.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-OZQNSELV.js";import"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import"../../chunk-FADINV4H.js";import"../../chunk-SWSOEYC7.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-GYNZ3OZF.js";import"../../chunk-UPFH72PF.js";import"../../chunk-FG343JM3.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-KFNFLMUR.js";import"../../chunk-4GOXEEXZ.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-JNLDISBA.js";import"../../chunk-GPBN4ROE.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{b as A,d as C,g as S,i as E,j as L,k as $}from"../../chunk-QI3FJKGK.js";import{a as O}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as m}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import{e as I,l as p}from"../../chunk-PZNWH4VQ.js";import{a as e}from"../../chunk-ZLLER3HP.js";import{trace as de,context as me}from"@opentelemetry/api";import{NodeSDK as W}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as Y}from"@opentelemetry/exporter-trace-otlp-http";import{BatchSpanProcessor as J,ConsoleSpanExporter as z,SimpleSpanProcessor as Q}from"@opentelemetry/sdk-trace-node";import{Resource as Z}from"@opentelemetry/resources";import{ATTR_SERVICE_NAME as ee,ATTR_SERVICE_VERSION as te}from"@opentelemetry/semantic-conventions";function F(r){if(!r)return{};let n={};for(let o of r.split(",")){let s=o.indexOf("=");if(s===-1)continue;let i=o.slice(0,s).trim(),c=o.slice(s+1).trim();i&&(n[i]=c)}return n}e(F,"parseOtlpHeaders");var u=null;function T(){return process.env.TELEMETRY_ENABLED!=="false"}e(T,"isTelemetryEnabled");function x(r){if(!T()||u!==null)return"off";let n=new Z({[ee]:r.serviceName,[te]:r.serviceVersion??"0.1.0"}),o=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,s,i;if(o){let c=F(process.env.OTEL_EXPORTER_OTLP_HEADERS),l=new Y({url:`${o}/v1/traces`,headers:c});i=new J(l),s="otlp"}else if(process.env.OTEL_SPAN_EXPORT==="none")i=void 0,s="silent";else{let c=new z;i=new Q(c),s="console"}return u=new W({resource:n,spanProcessors:i?[i]:[]}),u.start(),s}e(x,"initTelemetry");async function h(){u&&(await u.shutdown(),u=null)}e(h,"shutdownTelemetry");import{SpanKind as Pe,SpanStatusCode as Re}from"@opentelemetry/api";import{trace as Ie,context as Oe}from"@opentelemetry/api";import*as f from"@sentry/node";var v=!1;function w(r){if(v)return!1;let n=process.env.SENTRY_DSN;return n?(f.init({dsn:n,serverName:r.serviceName,environment:process.env.NODE_ENV??"development",tracesSampleRate:0}),v=!0,!0):!1}e(w,"initSentry");async function y(r){v&&await f.flush(r)}e(y,"flushSentry");import{existsSync as ne,mkdirSync as oe,readFileSync as k,unlinkSync as X,writeFileSync as U}from"node:fs";import{dirname as se,join as R}from"node:path";import{execFileSync as ie}from"node:child_process";var a=R(p(),"evals-agent.lock");function ce(r){try{return process.kill(r,0),!0}catch(n){return n.code==="EPERM"}}e(ce,"pidAlive");function ae(r){if(!ce(r))return!1;try{let n=ie("ps",["-p",String(r),"-o","command="],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return/run\.js\s+evals\s+agent|evals\s+agent/.test(n)}catch{return!0}}e(ae,"isLiveAgent");function le(){try{oe(se(a),{recursive:!0})}catch{}for(let r=0;r<2;r++)try{return U(a,String(process.pid),{flag:"wx"}),{ok:!0}}catch(n){if(n.code!=="EEXIST")throw n;let o=0;try{o=Number(k(a,"utf-8").trim())}catch{}if(o&&o!==process.pid&&ae(o))return{ok:!1,holder:o};try{X(a)}catch{}}try{U(a,String(process.pid))}catch{}return{ok:!0}}e(le,"acquireAgentLock");function P(){try{ne(a)&&Number(k(a,"utf-8").trim())===process.pid&&X(a)}catch{}}e(P,"releaseAgentLock");var N=class r extends O{static{e(this,"EvalAgentCommand")}static description="The worker daemon: long-polls /api/work/next, claims jobs, and runs them locally. Installed as a launchd service by `rulemetric service install`.";static examples=["<%= config.bin %> evals agent"];async run(){await this.parse(r),this.requireAuth();let n=le();if(!n.ok){this.log(`Another rulemetric evals agent is already running (pid ${n.holder}). Refusing to start a second instance.`);return}process.env.PG_APPLICATION_NAME||="rulemetric-agent",w({serviceName:"rulemetric-agent"})&&this.log("[sentry] error capture enabled");let s=x({serviceName:"rulemetric-agent"});s==="otlp"?this.log(`[otel] traces exporting to ${process.env.OTEL_EXPORTER_OTLP_ENDPOINT}`):s==="console"?this.log("[otel] cron spans printing to stdout (set OTEL_EXPORTER_OTLP_ENDPOINT to ship to a backend)"):this.log("[otel] disabled (TELEMETRY_ENABLED=false)"),!I()&&!process.env.RULEMETRIC_API_KEY&&this.error("No auth token found. Run `rulemetric auth login` first."),this.log("Starting thin agent (Phase 4b parallel-run)..."),this.log(`Long-polling /api/work/next. Press Ctrl+C to stop.
2
2
  `);let c=new AbortController,l=await A({configDir:p()});if(this.log(`[transcript-sync] Codex capture: ${S(l)}`),l.error)this.log(`[transcript-sync] WARNING: ${l.error}`);else if(l.mode==="allowlist")for(let t of l.roots)this.log(`[transcript-sync] \u2022 ${t}`);let d=await C({configDir:p()});if(this.log(`[transcript-sync] Pi capture: ${E(d)}`),d.error)this.log(`[transcript-sync] WARNING: ${d.error}`);else if(d.mode==="allowlist")for(let t of d.roots)this.log(`[transcript-sync] \u2022 ${t}`);let B=new M({postSnapshot:e((t,K)=>m(`/api/sessions/${t}/context-snapshots`,K),"postSnapshot"),linkInstructions:e(t=>m("/api/sessions/link-instructions",{sessionId:t}),"linkInstructions"),log:e(t=>this.log(`[transcript-sync] ${t}`),"log")}),H=new G({providers:[V(void 0,void 0,L({configDir:p(),onChange:e(t=>this.log(`[transcript-sync] Codex capture changed: ${S(t)}`),"onChange")})),j(void 0,void 0,$({configDir:p(),onChange:e(t=>this.log(`[transcript-sync] Pi capture changed: ${E(t)}`),"onChange")}))],statePath:R(p(),"transcript-sync-state.json"),importTranscript:e(t=>m("/api/sessions/import",t),"importTranscript"),emitInstructions:e(t=>B.emit(t),"emitInstructions"),log:e(t=>this.log(`[transcript-sync] ${t}`),"log")});q(H,{signal:c.signal,log:e(t=>this.log(`[transcript-sync] ${t}`),"log")});let _=e(async t=>{this.log(`
3
3
  [${t}] shutting down agent...`),c.abort(),await Promise.allSettled([y(2e3),h(),g()]),P(),process.exit(0)},"shutdown");process.on("SIGINT",()=>{_("SIGINT")}),process.on("SIGTERM",()=>{_("SIGTERM")});let b=!1;try{await D({signal:c.signal,log:e(t=>this.log(t),"log"),version:this.config.version,readInstalledVersion:e(()=>{try{return JSON.parse(k(R(this.config.root,"package.json"),"utf-8")).version??null}catch{return null}},"readInstalledVersion"),onVersionDrift:e(()=>{b=!0},"onVersionDrift")}),b&&(this.log("[upgrade] Installed CLI version changed \u2014 restarting worker onto the new code."),await Promise.allSettled([y(2e3),h(),g()]),P(),process.exit(1))}finally{P(),await g()}}};export{N as default};
@@ -1,4 +1,4 @@
1
- import{b as h,c as f}from"../../chunk-QFTAU33Y.js";import"../../chunk-HT6R6KR3.js";import{a as m}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e as c}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as u}from"../../chunk-ZLLER3HP.js";import{Args as p,Flags as v}from"@oclif/core";var d=class b extends m{static{u(this,"EvalBenchmarkCommand")}static description="Aggregate eval runs into a benchmark for a target";static examples=["<%= config.bin %> evals benchmark <target-id>","<%= config.bin %> evals benchmark <target-id> --iteration 2"];static args={targetId:p.string({description:"Eval target ID",required:!0})};static flags={iteration:v.integer({description:"Filter runs by iteration",default:1})};async run(){let{args:o,flags:l}=await this.parse(b);this.requireAuth();let g=await c(`/api/eval-targets/${o.targetId}`);this.log(`Aggregating benchmark for "${g.name}" v${g.version}, iteration ${l.iteration}`);let a=await h(o.targetId,l.iteration);a.totalRuns===0&&this.error("No completed runs found. Run evals first with `rulemetric evals run`."),this.log(`
1
+ import{b as h,c as f}from"../../chunk-7LE2W3WP.js";import"../../chunk-KFNFLMUR.js";import{a as m}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e as c}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as u}from"../../chunk-ZLLER3HP.js";import{Args as p,Flags as v}from"@oclif/core";var d=class b extends m{static{u(this,"EvalBenchmarkCommand")}static description="Aggregate eval runs into a benchmark for a target";static examples=["<%= config.bin %> evals benchmark <target-id>","<%= config.bin %> evals benchmark <target-id> --iteration 2"];static args={targetId:p.string({description:"Eval target ID",required:!0})};static flags={iteration:v.integer({description:"Filter runs by iteration",default:1})};async run(){let{args:o,flags:l}=await this.parse(b);this.requireAuth();let g=await c(`/api/eval-targets/${o.targetId}`);this.log(`Aggregating benchmark for "${g.name}" v${g.version}, iteration ${l.iteration}`);let a=await h(o.targetId,l.iteration);a.totalRuns===0&&this.error("No completed runs found. Run evals first with `rulemetric evals run`."),this.log(`
2
2
  Aggregated ${a.totalRuns} runs
3
3
  `);for(let[e,n]of Object.entries(a.runSummary)){this.log(`${e}:`);for(let[r,i]of Object.entries(n)){let s=i;this.log(` ${r}: mean=${s.mean} stddev=${s.stddev} [${s.min}, ${s.max}]`)}}let t=a.verdict;if(t)if(this.log(`
4
4
  Verdict (${t.mode}, baseline=${t.baseline}):`),!t.sufficient)this.log(` ${t.insufficientReason??"insufficient data"} \u2014 no effect claimed`);else{let e=t.delta>=0?"+":"";this.log(` pass-rate delta: ${e}${(t.delta*100).toFixed(0)}% (n=${t.nWith} paired)`),this.log(` 95% CI: ${(t.ci.lower*100).toFixed(0)}\u2013${(t.ci.upper*100).toFixed(0)}%`),t.pValue!=null&&this.log(` McNemar p: ${t.pValue.toFixed(4)}`),this.log(` significant: ${t.significant?"YES":"no"}`)}if(a.notes.length>0){this.log(`