@rulemetric/cli 0.17.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-command.js +1 -1
- package/dist/{chunk-DHIEGG4T.js → chunk-26XE3JCL.js} +1 -1
- package/dist/chunk-2IQBXE6F.js +1 -0
- package/dist/{chunk-QXPGTEMO.js → chunk-2K4TF5RM.js} +1 -1
- package/dist/chunk-3IAZMJA4.js +1 -0
- package/dist/{chunk-F5GSKVF2.js → chunk-3WNQ52TW.js} +1 -1
- package/dist/{chunk-KEVDLLHT.js → chunk-433HK3QQ.js} +1 -1
- package/dist/{chunk-KR36ZDGN.js → chunk-4GM4OEQY.js} +1 -1
- package/dist/{chunk-5A6TMSRO.js → chunk-4XRPSKIJ.js} +1 -1
- package/dist/{chunk-65LFPUDB.js → chunk-52OHAULM.js} +1 -1
- package/dist/{chunk-T7HZZ4DJ.js → chunk-55HFAX5Y.js} +1 -1
- package/dist/{chunk-QPAOX7P2.js → chunk-57YXM7AI.js} +1 -1
- package/dist/{chunk-SFZPFNC6.js → chunk-6YSTU453.js} +1 -1
- package/dist/{chunk-3H44B6PB.js → chunk-7V6LLVAY.js} +1 -1
- package/dist/{chunk-USKRCVX3.js → chunk-ACJ2DBOE.js} +1 -1
- package/dist/{chunk-LJE5J3EW.js → chunk-ANHFE6US.js} +1 -1
- package/dist/{chunk-FADINV4H.js → chunk-AXTEV56C.js} +1 -1
- package/dist/{chunk-HBDKOU2N.js → chunk-AZB34RT6.js} +7 -6
- package/dist/{chunk-RDQXK5LG.js → chunk-AZK4Y5DB.js} +1 -1
- package/dist/{chunk-GIQ2HK3W.js → chunk-BLGICIV4.js} +1 -1
- package/dist/{chunk-6QMIDH6X.js → chunk-BV3JMD3A.js} +1 -1
- package/dist/{chunk-ZKPURXUS.js → chunk-CEM7JMUW.js} +1 -1
- package/dist/{chunk-NWV66NMA.js → chunk-CWVXTLXZ.js} +1 -1
- package/dist/{chunk-IMN4BWAR.js → chunk-CXSDZ473.js} +1 -1
- package/dist/{chunk-4ZDE63UG.js → chunk-DB4ZM5N3.js} +1 -1
- package/dist/{chunk-QPVUGTDP.js → chunk-EOTSCWFS.js} +1 -1
- package/dist/chunk-FLXWL4F4.js +8 -0
- package/dist/{chunk-7YZURVZD.js → chunk-FPEC6DJV.js} +1 -1
- package/dist/chunk-G2226CG6.js +1 -0
- package/dist/{chunk-KOORMTZO.js → chunk-GLZBTGN5.js} +1 -1
- package/dist/{chunk-5TM7AOH2.js → chunk-GPWLS64K.js} +1 -1
- package/dist/{chunk-STUNT4N3.js → chunk-HB4RUEEE.js} +1 -1
- package/dist/{chunk-UVCVJKEN.js → chunk-JEZ5ZTKR.js} +1 -1
- package/dist/{chunk-ISYU5BMU.js → chunk-JQ2ZCUEC.js} +1 -1
- package/dist/{chunk-FHRBW4AQ.js → chunk-KSKC5SEQ.js} +1 -1
- package/dist/{chunk-ISEUEYSC.js → chunk-L3AXNCWC.js} +1 -1
- package/dist/chunk-LARY6ZFT.js +1 -0
- package/dist/{chunk-E4CIJ67Z.js → chunk-LEUXIXIS.js} +1 -1
- package/dist/{chunk-GGUXEZC3.js → chunk-LMNUO32P.js} +1 -1
- package/dist/{chunk-ZBTJ5R7C.js → chunk-LMQDS47I.js} +1 -1
- package/dist/{chunk-VUNJGZPP.js → chunk-M2CPTQZL.js} +1 -1
- package/dist/{chunk-WUCACPGC.js → chunk-MOQTSJNZ.js} +1 -1
- package/dist/chunk-N7P3HUPD.js +3 -0
- package/dist/{chunk-7LE2W3WP.js → chunk-PHBPHZSZ.js} +1 -1
- package/dist/{chunk-TSLBCZ5P.js → chunk-QH7JB4UQ.js} +1 -1
- package/dist/{chunk-CVPAKEEZ.js → chunk-R7URROQD.js} +1 -1
- package/dist/{chunk-EFEPD4AZ.js → chunk-RAIXY6YA.js} +1 -1
- package/dist/{chunk-KUW6AVSI.js → chunk-RCJTCLZO.js} +1 -1
- package/dist/chunk-SVZYRGO5.js +4 -0
- package/dist/{chunk-WL5ZWQAS.js → chunk-TDDJOSFQ.js} +1 -1
- package/dist/{chunk-EMZFZCS4.js → chunk-TDRUVE4J.js} +1 -1
- package/dist/chunk-TFJAT263.js +2 -0
- package/dist/{chunk-PDXHRF4E.js → chunk-TL57YUJV.js} +1 -1
- package/dist/{chunk-QNSIBPWG.js → chunk-TZC4CYPD.js} +1 -1
- package/dist/{chunk-FG343JM3.js → chunk-U6AASXY3.js} +1 -1
- package/dist/{chunk-BDQTVYYF.js → chunk-UDNEOJWY.js} +1 -1
- package/dist/{chunk-PJ4RIUI3.js → chunk-UPJVMMDK.js} +1 -1
- package/dist/{chunk-Q7IDLOSP.js → chunk-V2G6E53W.js} +1 -1
- package/dist/{chunk-MYGVN6X4.js → chunk-VF54EOLZ.js} +1 -1
- package/dist/{chunk-KE5K3F7J.js → chunk-VFWQ2W4B.js} +1 -1
- package/dist/chunk-VZYNZS5U.js +1 -0
- package/dist/{chunk-DX6IPDED.js → chunk-WDLAPZPN.js} +1 -1
- package/dist/{chunk-AKCCNLHL.js → chunk-WM437XV6.js} +1 -1
- package/dist/chunk-WULEBQPI.js +1 -0
- package/dist/{chunk-CPDW7WW2.js → chunk-WWL4HNXM.js} +17 -17
- package/dist/{chunk-KGU2IW54.js → chunk-YSY25OGG.js} +1 -1
- package/dist/{chunk-WL34G6IR.js → chunk-YVEI7XR6.js} +1 -1
- package/dist/{chunk-YXMAGC53.js → chunk-YX2IGS72.js} +1 -1
- package/dist/chunk-Z7UN4R7T.js +1 -0
- package/dist/{chunk-TQM7MF5C.js → chunk-ZZZ7ECPT.js} +1 -1
- package/dist/commands/antigravity/backfill.js +1 -1
- package/dist/commands/auth/create-key.js +1 -1
- package/dist/commands/auth/login.js +1 -1
- package/dist/commands/auth/logout.js +1 -1
- package/dist/commands/auth/revoke-key.js +1 -1
- package/dist/commands/auth/signup.js +1 -1
- package/dist/commands/auth/status.js +1 -1
- package/dist/commands/capture/scope.js +1 -1
- package/dist/commands/catalog/index.js +1 -1
- package/dist/commands/catalog/recommend.js +1 -1
- package/dist/commands/crons/list.js +1 -1
- package/dist/commands/crons/run.js +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/diagnostics.js +1 -1
- package/dist/commands/eval-targets/create.js +1 -1
- package/dist/commands/eval-targets/list.js +1 -1
- package/dist/commands/evals/agent.js +1 -1
- package/dist/commands/evals/auto-run.js +1 -1
- package/dist/commands/evals/benchmark.js +1 -1
- package/dist/commands/evals/compare.js +1 -1
- package/dist/commands/evals/create.js +1 -1
- package/dist/commands/evals/optimize-description.js +1 -1
- package/dist/commands/evals/optimize.js +1 -1
- package/dist/commands/evals/refine-cases.js +1 -1
- package/dist/commands/evals/run.js +1 -1
- package/dist/commands/evals/validate-judge.js +1 -1
- package/dist/commands/experiments/list.js +1 -1
- package/dist/commands/gateway/ensure.js +1 -1
- package/dist/commands/hooks/install.js +1 -1
- package/dist/commands/hooks/run.js +1 -1
- package/dist/commands/hooks/uninstall.js +1 -1
- package/dist/commands/instructions/create.js +1 -1
- package/dist/commands/instructions/dedupe.js +1 -1
- package/dist/commands/instructions/delete.js +1 -1
- package/dist/commands/instructions/fork.js +1 -1
- package/dist/commands/instructions/get.js +1 -1
- package/dist/commands/instructions/list.js +1 -1
- package/dist/commands/instructions/promote.js +1 -1
- package/dist/commands/instructions/pull.js +1 -1
- package/dist/commands/instructions/restore.js +1 -1
- package/dist/commands/instructions/retract.js +1 -1
- package/dist/commands/instructions/upstream.js +1 -1
- package/dist/commands/instructions/versions.js +1 -1
- package/dist/commands/launcher.js +1 -1
- package/dist/commands/local/down.js +1 -1
- package/dist/commands/local/up.js +1 -1
- package/dist/commands/org/current.js +1 -1
- package/dist/commands/org/list.js +1 -1
- package/dist/commands/org/switch.js +1 -1
- package/dist/commands/packs/add-instruction.js +1 -1
- package/dist/commands/packs/apply.js +1 -1
- package/dist/commands/packs/create.js +1 -1
- package/dist/commands/packs/fork.js +1 -1
- package/dist/commands/packs/get.js +1 -1
- package/dist/commands/packs/list.js +1 -1
- package/dist/commands/packs/remove-instruction.js +1 -1
- package/dist/commands/proxy/env.js +1 -1
- package/dist/commands/proxy/logs.js +1 -1
- package/dist/commands/proxy/restart.js +1 -1
- package/dist/commands/proxy/setup.js +1 -1
- package/dist/commands/proxy/start.js +1 -1
- package/dist/commands/proxy/status.js +1 -1
- package/dist/commands/proxy/stop.js +1 -1
- package/dist/commands/research/backfill.js +1 -1
- package/dist/commands/research/resume-scoped-outcomes.js +1 -1
- package/dist/commands/research/tail-transcript.js +1 -1
- package/dist/commands/service/install.js +1 -1
- package/dist/commands/service/status.js +1 -1
- package/dist/commands/service/uninstall.js +1 -1
- package/dist/commands/sessions/analyze.js +1 -1
- package/dist/commands/sessions/delete.js +1 -1
- package/dist/commands/sessions/end.js +1 -1
- package/dist/commands/sessions/import.js +1 -1
- package/dist/commands/sessions/list.js +1 -1
- package/dist/commands/sessions/start.js +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/skills/export-approved.js +1 -1
- package/dist/commands/skills/install.js +1 -1
- package/dist/commands/skills/list.js +1 -1
- package/dist/commands/skills/publish.js +1 -1
- package/dist/commands/skills/search.js +1 -1
- package/dist/commands/skills/update.js +1 -1
- package/dist/commands/suggestions/accept.js +1 -1
- package/dist/commands/suggestions/auto.js +1 -1
- package/dist/commands/suggestions/dismiss.js +1 -1
- package/dist/commands/suggestions/list.js +1 -1
- package/dist/commands/suggestions/refresh.js +1 -1
- package/dist/commands/suggestions/undo.js +1 -1
- package/dist/dashboard/Dashboard.js +1 -1
- package/dist/dashboard/data.js +1 -1
- package/dist/dashboard/launcher/LauncherOverlay.js +1 -1
- package/dist/dashboard/launcher/api.js +1 -1
- package/dist/dashboard/launcher/useLaunchJobs.js +1 -1
- package/dist/dashboard/panels/measurement.js +1 -1
- package/dist/{dist-5647V2E7.js → dist-WGZCHQTC.js} +1 -1
- package/dist/lib/active-org-refresh.js +1 -1
- package/dist/lib/actor-env.js +1 -0
- package/dist/lib/agent-loop.js +1 -1
- package/dist/lib/agent-presence.js +1 -1
- package/dist/lib/antigravity-transcript.js +1 -1
- package/dist/lib/api-client.js +1 -1
- package/dist/lib/codex-exec.js +1 -1
- package/dist/lib/ensure-api-key.js +1 -1
- package/dist/lib/ensure-fresh-token.js +1 -1
- package/dist/lib/eval-analyzer.js +1 -1
- package/dist/lib/eval-benchmark.js +1 -1
- package/dist/lib/eval-candidate-run.js +1 -1
- package/dist/lib/eval-case-generator.js +1 -1
- package/dist/lib/eval-conversation-handler.js +1 -1
- package/dist/lib/eval-executor.js +1 -1
- package/dist/lib/eval-grader.js +1 -1
- package/dist/lib/eval-meta-judge.js +1 -1
- package/dist/lib/eval-resume.js +1 -1
- package/dist/lib/eval-run-batch.js +1 -1
- package/dist/lib/eval-trigger-tester.js +1 -1
- package/dist/lib/evolution-enrolment.js +1 -1
- package/dist/lib/insights/nomination/nominate.js +1 -1
- package/dist/lib/instruction-proposer.js +1 -1
- package/dist/lib/instruction-restoration.js +1 -1
- package/dist/lib/instructions/acceptance/accept-events.js +1 -1
- package/dist/lib/instructions/acceptance/accept-hook.js +1 -1
- package/dist/lib/instructions/acceptance/reverse-applications.js +1 -1
- package/dist/lib/instructions/acceptance/suggestion-accept.js +1 -1
- package/dist/lib/jobs/handlers/cron-auto-accept-suggestions.js +1 -1
- package/dist/lib/jobs/handlers/cron-eval-autorun.js +1 -1
- package/dist/lib/jobs/handlers/cron-instruction-evolution.js +1 -1
- package/dist/lib/jobs/handlers/cron-instruction-training.js +1 -1
- package/dist/lib/jobs/handlers/cron-reconcile-attribution.js +1 -1
- package/dist/lib/jobs/handlers/cron-refine-cases.js +1 -1
- package/dist/lib/jobs/handlers/cron-refresh-pricing.js +1 -1
- package/dist/lib/jobs/handlers/cron-retire-unused-skills.js +1 -1
- package/dist/lib/jobs/handlers/cron-suggest-instructions.js +1 -1
- package/dist/lib/jobs/handlers/distill-memories.js +1 -1
- package/dist/lib/jobs/handlers/finalize-scoped-launch.js +1 -1
- package/dist/lib/jobs/handlers/prepare-suggestion-live.js +1 -1
- package/dist/lib/jobs/handlers/process-conversation.js +1 -1
- package/dist/lib/jobs/handlers/process-eval.js +1 -1
- package/dist/lib/jobs/handlers/process-insights.js +1 -1
- package/dist/lib/jobs/handlers/process-judge-review.js +1 -1
- package/dist/lib/jobs/handlers/process-launch.js +1 -1
- package/dist/lib/jobs/handlers/process-memory-ab.js +1 -1
- package/dist/lib/jobs/handlers/process-run-cleanup.js +1 -1
- package/dist/lib/jobs/handlers/process-session-goal.js +1 -1
- package/dist/lib/jobs/handlers/process-suggestion-eval.js +1 -1
- package/dist/lib/jobs/shed-retry.js +1 -1
- package/dist/lib/judge-review-runner.js +1 -1
- package/dist/lib/llm-client.js +1 -1
- package/dist/lib/manual-tasks.js +1 -1
- package/dist/lib/measurement-llm.js +1 -1
- package/dist/lib/projects/workspace/eval-workspace.js +1 -1
- package/dist/lib/projects/workspace/worktree.js +1 -1
- package/dist/lib/refine-cases.js +1 -1
- package/dist/lib/repository-capabilities.js +1 -0
- package/dist/lib/research-client.js +1 -1
- package/dist/lib/setup-steps.js +1 -1
- package/dist/lib/telemetry.js +1 -1
- package/dist/lib/terminal-target-heartbeat.js +1 -1
- package/dist/lib/work-report.js +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +6 -6
- package/dist/chunk-2PO5I3XR.js +0 -1
- package/dist/chunk-3MYCWZ63.js +0 -1
- package/dist/chunk-4GOXEEXZ.js +0 -1
- package/dist/chunk-CDSSOOIG.js +0 -1
- package/dist/chunk-FCALFMZV.js +0 -1
- package/dist/chunk-GIXHG5FK.js +0 -1
- package/dist/chunk-JNLDISBA.js +0 -4
- package/dist/chunk-SWSOEYC7.js +0 -1
- package/dist/chunk-ZLBYYLJZ.js +0 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as $}from"../../chunk-4VN5PG2S.js";import{a as k}from"../../chunk-
|
|
1
|
+
import{a as $}from"../../chunk-4VN5PG2S.js";import{a as k}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as b}from"../../chunk-Z7UN4R7T.js";import{A as f,B as g,z as h}from"../../chunk-X6CF5KTW.js";import{f as p}from"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as d}from"../../chunk-ZLLER3HP.js";import{Args as _,Flags as y}from"@oclif/core";var l=class w extends k{static{d(this,"CronsRun")}static description="Run a maintenance task synchronously, right now";static examples=["<%= config.bin %> crons run cron_check_changelog","<%= config.bin %> crons run cron_suggest_instructions --quiet"];static args={name:_.string({description:"Task name (run `rulemetric crons list` to see all)",required:!0})};static flags={"dry-run":y.boolean({description:"For Harbor, print the saved engine/model and supported tasks without running them"}),quiet:y.boolean({char:"q",description:"Suppress per-line log output; print summary only"})};async run(){let{args:s,flags:a}=await this.parse(w);this.requireAuth();let o=$.find(e=>e.name===s.name);o||this.error(`Unknown task: ${s.name}
|
|
2
2
|
Run \`rulemetric crons list\` to see available tasks.`);let t=null;if(s.name==="harbor_ab"){let e=await b("/api/settings/measurement");t=e.execution.harbor?p.parse(e.execution.harbor):null;for(let r of h("proven")){let m=f(r,t);if(m){this.log(`Unsupported: ${m}`);continue}let i=g(r,"manual",t);this.log(`${r.task}: ${t?.engine??"claude"} / ${i.model}, ${i.class}, ${i.nTrials} trials per arm`)}if(a["dry-run"])return}else a["dry-run"]&&this.error("--dry-run is currently supported only for harbor_ab");let u;try{({runManualTask:u}=await import("../../lib/manual-tasks.js"))}catch(e){let r=e?.code;throw(r==="ERR_MODULE_NOT_FOUND"||r==="MODULE_NOT_FOUND")&&this.error("`crons run` needs the worker runtime, which isn't available in this install.\nReinstall the CLI and verify that its runtime dependencies are present. A database credential is not required for end-user maintenance tasks."),e}this.log(`\u25B6 Running ${o.name} \u2026`);let v=Date.now(),n=await u(s.name,{measurement:t});if(!a.quiet)for(let e of n.logs){let r=e.level==="error"||e.level==="warn"?`[${e.level}]`:"";this.log(` ${r} ${e.message}`)}let c=((n.durationMs??Date.now()-v)/1e3).toFixed(1);n.ok?this.log(`\u2713 ${o.name} completed in ${c}s (${n.logs.length} log line${n.logs.length===1?"":"s"})`):this.error(`\u2717 ${o.name} failed after ${c}s: ${n.error}`)}};export{l as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as o}from"../chunk-
|
|
1
|
+
import{a as o}from"../chunk-MOQTSJNZ.js";import"../chunk-IZTIYR5Q.js";import"../chunk-TDDJOSFQ.js";import"../chunk-433HK3QQ.js";import"../chunk-WDLAPZPN.js";import"../chunk-3AV3GTMP.js";import"../chunk-Z7UN4R7T.js";import"../chunk-X6CF5KTW.js";import"../chunk-XQYAVSUQ.js";import"../chunk-PZNWH4VQ.js";import{a as i}from"../chunk-ZLLER3HP.js";import{Flags as r}from"@oclif/core";var a=class s extends o{static{i(this,"Dashboard")}static description="Interactive TUI dashboard showing session analytics, outcomes, friction, and insights";static examples=["<%= config.bin %> dashboard","<%= config.bin %> dashboard --period 30days","<%= config.bin %> dashboard --launcher"];static flags={period:r.string({char:"p",default:"week",options:["today","week","30days","month","all"],description:"Initial time period"}),launcher:r.boolean({char:"l",default:!1,description:"Open the launcher overlay immediately"})};async run(){let{flags:e}=await this.parse(s),{renderDashboard:t}=await import("../dashboard/Dashboard.js");await t(e.period,{openLauncher:e.launcher})}};export{a as default};
|
|
@@ -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-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
|
+
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-YSY25OGG.js";import"../chunk-M7QSC64D.js";import"../chunk-CEM7JMUW.js";import"../chunk-L3AXNCWC.js";import"../chunk-ANHFE6US.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-AHLVY52I.js";import"../chunk-YX2IGS72.js";import"../chunk-55HFAX5Y.js";import"../chunk-26XE3JCL.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-AXTEV56C.js";import"../chunk-VZYNZS5U.js";import"../chunk-U2NT5OSQ.js";import"../chunk-KGURGIZ2.js";import"../chunk-GYNZ3OZF.js";import"../chunk-UPFH72PF.js";import"../chunk-U6AASXY3.js";import"../chunk-CDY7TQFZ.js";import"../chunk-KFNFLMUR.js";import"../chunk-LARY6ZFT.js";import"../chunk-JP6ULOEX.js";import"../chunk-SVZYRGO5.js";import"../chunk-WULEBQPI.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-MOQTSJNZ.js";import"../chunk-IZTIYR5Q.js";import"../chunk-TDDJOSFQ.js";import"../chunk-433HK3QQ.js";import"../chunk-WDLAPZPN.js";import"../chunk-3AV3GTMP.js";import{a as U,e as y}from"../chunk-Z7UN4R7T.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 +1 @@
|
|
|
1
|
-
import{a}from"../../chunk-
|
|
1
|
+
import{a}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{f as s}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Flags as e}from"@oclif/core";import{readFileSync as p}from"node:fs";var n=class c extends a{static{o(this,"EvalTargetCreate")}static description="Create an eval target (instruction, skill, prompt, or plan to test)";static examples=["<%= config.bin %> eval-targets create --name my-rules --type instruction --file ./CLAUDE.md",'<%= config.bin %> eval-targets create --name my-prompt --type prompt --content "Always use TypeScript"'];static flags={name:e.string({char:"n",description:"Name for the eval target",required:!0}),type:e.string({char:"t",description:"Target type",options:["instruction","skill","prompt","plan"],required:!0}),file:e.string({char:"f",description:"Path to content file"}),content:e.string({char:"c",description:"Content string (alternative to --file)"}),description:e.string({char:"d",description:"Description of the target",default:""})};async run(){let{flags:t}=await this.parse(c);this.requireAuth();let i;t.file?i=p(t.file,"utf-8"):t.content?i=t.content:this.error("Provide either --file or --content");let r=await s("/api/eval-targets",{name:t.name,type:t.type,content:i,description:t.description});this.log(`Created eval target: ${r.name} (${r.id}) v${r.version}`)}};export{n as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as p,b as e}from"../../chunk-W2MV25SB.js";import{a as o}from"../../chunk-
|
|
1
|
+
import{a as p,b as e}from"../../chunk-W2MV25SB.js";import{a as o}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as s}from"../../chunk-ZLLER3HP.js";import{Flags as m}from"@oclif/core";import{printTable as d}from"@oclif/table";var r=class l extends o{static{s(this,"EvalTargetList")}static description="List eval targets";static examples=["<%= config.bin %> eval-targets list","<%= config.bin %> eval-targets list --type instruction"];static flags={type:m.string({char:"t",description:"Filter by type",options:["instruction","skill","prompt","plan"]})};async run(){let{flags:i}=await this.parse(l);this.requireAuth();let c=i.type?`?type=${i.type}`:"",a=await n(`/api/eval-targets${c}`);if(a.length===0){this.log("No eval targets found. Create one with `rulemetric eval-targets create`.");return}d({data:a.map(t=>({Name:e(t.name,30),Type:t.type,Version:`v${t.version}`,Description:e(t.description,40),Updated:p(t.updatedAt)})),columns:["Name","Type","Version","Description","Updated"]})}};export{r 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-HTAHNQZJ.js";import{e as D}from"../../chunk-
|
|
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-2IQBXE6F.js";import"../../chunk-GPWLS64K.js";import"../../chunk-IEQDLURA.js";import"../../chunk-KINIFUZQ.js";import"../../chunk-HB4RUEEE.js";import"../../chunk-TFJAT263.js";import"../../chunk-JU5ZNXPK.js";import"../../chunk-GLZBTGN5.js";import"../../chunk-V2G6E53W.js";import"../../chunk-G2226CG6.js";import"../../chunk-ZZZ7ECPT.js";import"../../chunk-AZK4Y5DB.js";import"../../chunk-2K4TF5RM.js";import"../../chunk-ZYGBABMZ.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-BLGICIV4.js";import"../../chunk-RAIXY6YA.js";import"../../chunk-HOQPVOMF.js";import"../../chunk-LEUXIXIS.js";import"../../chunk-FZMO7XSN.js";import"../../chunk-MOJY6S5J.js";import"../../chunk-RCJTCLZO.js";import"../../chunk-VBGHPAUT.js";import"../../chunk-4XRPSKIJ.js";import"../../chunk-M2CPTQZL.js";import"../../chunk-LMNUO32P.js";import"../../chunk-N7P3HUPD.js";import"../../chunk-ACJ2DBOE.js";import"../../chunk-FPEC6DJV.js";import"../../chunk-SW24KZ5C.js";import"../../chunk-57YXM7AI.js";import"../../chunk-3ZHVP3KE.js";import"../../chunk-WM437XV6.js";import"../../chunk-R7URROQD.js";import"../../chunk-VFWQ2W4B.js";import"../../chunk-GLBWNB2N.js";import"../../chunk-CQD2R3BA.js";import"../../chunk-3UKZJAFS.js";import"../../chunk-77FH6UZP.js";import"../../chunk-YVEI7XR6.js";import"../../chunk-4GM4OEQY.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-DQYYHX6K.js";import"../../chunk-DB4ZM5N3.js";import"../../chunk-3WNQ52TW.js";import"../../chunk-PIVEJTNF.js";import"../../chunk-KSKC5SEQ.js";import"../../chunk-LMQDS47I.js";import"../../chunk-DANMUHNW.js";import"../../chunk-JQ2ZCUEC.js";import"../../chunk-WWL4HNXM.js";import"../../chunk-3IAZMJA4.js";import"../../chunk-XFOG2PDJ.js";import"../../chunk-SIGZEQ3K.js";import"../../chunk-FXQS7AEZ.js";import"../../chunk-LJRE3LZ2.js";import"../../chunk-QH7JB4UQ.js";import"../../chunk-52OHAULM.js";import"../../chunk-AZB34RT6.js";import"../../chunk-FLXWL4F4.js";import"../../chunk-7V6LLVAY.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-MODXEGCU.js";import"../../chunk-MHVHGKDK.js";import"../../chunk-RBSEE2Z6.js";import"../../chunk-TL57YUJV.js";import"../../chunk-YSY25OGG.js";import"../../chunk-M7QSC64D.js";import"../../chunk-CEM7JMUW.js";import"../../chunk-L3AXNCWC.js";import"../../chunk-ANHFE6US.js";import"../../chunk-GYKYJJNF.js";import"../../chunk-G7V4ZZZ3.js";import"../../chunk-AHLVY52I.js";import"../../chunk-YX2IGS72.js";import"../../chunk-55HFAX5Y.js";import"../../chunk-26XE3JCL.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-AXTEV56C.js";import"../../chunk-VZYNZS5U.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-GYNZ3OZF.js";import"../../chunk-UPFH72PF.js";import"../../chunk-U6AASXY3.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-KFNFLMUR.js";import"../../chunk-LARY6ZFT.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-SVZYRGO5.js";import"../../chunk-WULEBQPI.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-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{f as m}from"../../chunk-Z7UN4R7T.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{a as k}from"../../chunk-RBSEE2Z6.js";import{e as $}from"../../chunk-
|
|
1
|
+
import{a as k}from"../../chunk-RBSEE2Z6.js";import{e as $}from"../../chunk-AXTEV56C.js";import"../../chunk-VZYNZS5U.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-GYNZ3OZF.js";import"../../chunk-UPFH72PF.js";import"../../chunk-U6AASXY3.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-LARY6ZFT.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-SVZYRGO5.js";import"../../chunk-WULEBQPI.js";import"../../chunk-GPBN4ROE.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as w}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as h}from"../../chunk-ZLLER3HP.js";import{Args as A,Flags as r}from"@oclif/core";var m=class y extends w{static{h(this,"EvalAutoRun")}static description="Run evals in a loop until the effect verdict is statistically powered (\xA76f auto-run-to-power)";static examples=["<%= config.bin %> evals auto-run <target-id> # preview (cost + plan)","<%= config.bin %> evals auto-run <target-id> --yes # run until powered / budget","<%= config.bin %> evals auto-run <target-id> --yes --max-runs 120 --batch-parallel 4"];static args={targetId:A.string({description:"Eval target ID",required:!0})};static flags={yes:r.boolean({char:"y",description:"Actually run. Without this, only previews the plan + cost."}),"max-runs":r.integer({description:"Hard ceiling on completed runs",default:200}),"batch-parallel":r.integer({description:"Concurrent executions within a batch",default:3}),timeout:r.integer({description:"Timeout per eval in ms",default:12e4}),model:r.string({description:"Model for eval execution"}),"grader-model":r.string({description:"Model for grading"}),"skip-baseline":r.boolean({description:"Skip without_target runs (no delta \u2014 not recommended)",default:!1})};async run(){let{args:C,flags:e}=await this.parse(y);this.requireAuth();let i=C.targetId,c=20,a=await n(`/api/eval-targets/${i}`),l=await n(`/api/eval-targets/${i}/evals`);l.length===0&&this.error(`No active cases on "${a.name}". Generate some (\`evals create\` / the web Generate button) or run \`evals refine-cases\` first.`);let b=l.length*(e["skip-baseline"]?1:2),f=Math.ceil(e["max-runs"]/b);if(this.log(`Auto-run "${a.name}" v${a.version} toward a powered \xB1${c}pp verdict.`),this.log(`Plan: up to ${e["max-runs"]} runs (${l.length} active case(s) \xD7 ${e["skip-baseline"]?1:2}/batch = ${b}/batch, \u2264${f} batches). Each run is a synthetic \`claude -p\` execution + grade.`),this.log('Note: this is a controlled synthetic A/B. For a DEPLOYED instruction with real usage, the Insights observational verdict is cheaper and uses real sessions \u2014 auto-run is for pre-deploy, catalog skills, or targets with no real "without" cohort.'),!e.yes){this.log(`
|
|
2
2
|
Preview only. Re-run with --yes to start.`);return}let t={runsCompleted:0,maxRuns:e["max-runs"],batchesRun:0,maxBatches:f},x={targetId:i,targetVersion:a.version,iteration:1,timeout:e.timeout,model:e.model,graderModel:e["grader-model"],skipGrading:!1,targetType:a.type,targetName:a.name};for(;;){let s;try{s=await n(`/api/eval-targets/${i}/judge-calibration`)}catch(o){this.log(`
|
|
3
3
|
\u25A0 stopping \u2014 could not read the power check: ${o instanceof Error?o.message:String(o)}`);break}let E={powered:s.powerCheck?.powered??!1,mde:s.powerCheck?.mde==null?1/0:s.powerCheck.mde},B=s.caseDiscrimination??{total:0,discriminating:0,nonDiscriminating:0,unpaired:0},p=k(E,B,t,{targetEffectPp:c});if(this.log(`
|
|
4
4
|
${p.action==="stop"?"\u25A0":"\u25B8"} ${p.reason}`),p.action==="stop")break;let v=await n(`/api/eval-targets/${i}/evals`);if(v.length===0){this.log("\u25A0 no active cases left \u2014 stopping.");break}let{completed:g,failed:D}=await $({cases:v,targetContent:a.content,concurrency:e["batch-parallel"],runNumber:t.batchesRun+1,opts:x,skipBaseline:e["skip-baseline"],onLog:h(o=>this.log(o),"onLog")});if(t.runsCompleted+=g,t.batchesRun+=1,this.log(`Batch ${t.batchesRun}: ${g} completed, ${D} failed \u2014 ${t.runsCompleted}/${t.maxRuns} runs, ${t.batchesRun}/${t.maxBatches} batches.`),g===0){this.log("\u25A0 batch produced 0 completed runs \u2014 the executor appears broken (check the model / `claude -p`). Aborting.");break}}let d=await n(`/api/eval-targets/${i}/judge-calibration`),u=d.powerCheck?.mde,R=u==null||!Number.isFinite(u)?"unknown":`\xB1${Math.round(u*100)}pp`;this.log(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as h,c as f}from"../../chunk-
|
|
1
|
+
import{b as h,c as f}from"../../chunk-PHBPHZSZ.js";import"../../chunk-KFNFLMUR.js";import{a as m}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as c}from"../../chunk-Z7UN4R7T.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(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as $,b as A}from"../../chunk-647M2I2Y.js";import{
|
|
1
|
+
import{a as $,b as A}from"../../chunk-647M2I2Y.js";import{g as p}from"../../chunk-LARY6ZFT.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-SVZYRGO5.js";import"../../chunk-WULEBQPI.js";import"../../chunk-GPBN4ROE.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as f}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as l,f as w}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as h}from"../../chunk-ZLLER3HP.js";import{Args as B,Flags as b}from"@oclif/core";var c=class I extends f{static{h(this,"EvalCompareCommand")}static description="Blind A/B comparison between two eval target versions";static examples=["<%= config.bin %> evals compare <target-a> <target-b>"];static args={targetA:B.string({description:"First eval target ID",required:!0}),targetB:B.string({description:"Second eval target ID",required:!0})};static flags={model:b.string({description:"Model for execution and comparison"}),timeout:b.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:g,flags:o}=await this.parse(I);this.requireAuth();let[e,r]=await Promise.all([l(`/api/eval-targets/${g.targetA}`),l(`/api/eval-targets/${g.targetB}`)]),m=await l(`/api/eval-targets/${g.targetA}/evals`);m.length===0&&this.error("No evals found for target A. Create some first."),this.log(`Comparing "${e.name}" v${e.version} vs "${r.name}" v${r.version}`),this.log(`Running ${m.length} eval(s)...
|
|
2
2
|
`);let a=Math.random()>.5,E=a?r.content:e.content,T=a?e.content:r.content,C=a?r.name:e.name,x=a?e.name:r.name,v=[];for(let t of m){this.log(`[${t.name}] Running A...`);let s=await p({prompt:t.prompt,targetContent:E,timeout:o.timeout,model:o.model});this.log(`[${t.name}] Running B...`);let d=await p({prompt:t.prompt,targetContent:T,timeout:o.timeout,model:o.model});(s.error||d.error)&&this.error(`[${t.name}] execution failed (A: ${s.error??"ok"} | B: ${d.error??"ok"}) \u2014 aborting before the blind comparison`),v.push({evalName:t.name,outputA:s.output,outputB:d.output})}this.log(`
|
|
3
3
|
Running blind comparison...`);let N=v.map(t=>`
|
|
4
4
|
## Eval: ${t.evalName}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as c}from"../../chunk-
|
|
1
|
+
import{a as c}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{f as i}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as m}from"../../chunk-ZLLER3HP.js";import{Args as f,Flags as r}from"@oclif/core";import{readFileSync as g}from"node:fs";var s=class d extends c{static{m(this,"EvalCreate")}static description="Create test cases (evals) for an eval target";static examples=['<%= config.bin %> evals create <target-id> --name "ts-check" --prompt "Write a function to add two numbers"',"<%= config.bin %> evals create <target-id> --from-file evals.json"];static args={targetId:f.string({description:"Eval target ID",required:!0})};static flags={name:r.string({char:"n",description:"Eval name"}),prompt:r.string({char:"p",description:"Test prompt"}),expectations:r.string({char:"e",description:"Assertion (repeatable)",multiple:!0}),"from-file":r.string({description:"Bulk create from JSON file"})};async run(){let{args:n,flags:e}=await this.parse(d);if(this.requireAuth(),e["from-file"]){let a=JSON.parse(g(e["from-file"],"utf-8")),p=Array.isArray(a)?a:a.evals;for(let t of p){let l=await i(`/api/eval-targets/${n.targetId}/evals`,{name:t.name,prompt:t.prompt,expectations:t.expectations??[],files:t.files??[]});this.log(`Created eval: ${l.name} (${l.id})`)}this.log(`Created ${p.length} evals.`);return}(!e.name||!e.prompt)&&this.error("Provide --name and --prompt, or use --from-file for bulk creation");let o=await i(`/api/eval-targets/${n.targetId}/evals`,{name:e.name,prompt:e.prompt,expectations:e.expectations??[]});this.log(`Created eval: ${o.name} (${o.id})`)}};export{s as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as P,b as S}from"../../chunk-
|
|
1
|
+
import{a as P,b as S}from"../../chunk-BV3JMD3A.js";import{g as b}from"../../chunk-LARY6ZFT.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-SVZYRGO5.js";import"../../chunk-WULEBQPI.js";import"../../chunk-GPBN4ROE.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as N}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as y,f as q,g as w}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as E}from"../../chunk-ZLLER3HP.js";import{Args as Q,Flags as v}from"@oclif/core";var C=process.env.RULEMETRIC_WEB_URL??"https://rulemetric.com",_=30*6e4,R=class k extends N{static{E(this,"EvalOptimizeDescriptionCommand")}static description="Optimize eval target description for better triggering accuracy";static examples=["<%= config.bin %> evals optimize-description <target-id>","<%= config.bin %> evals optimize-description <target-id> --queries 10"];static args={targetId:Q.string({description:"Eval target ID",required:!0})};static flags={"max-iterations":v.integer({description:"Maximum optimization iterations",default:5}),model:v.string({description:"Model for trigger testing and improvement"}),queries:v.integer({description:"Number of trigger queries to generate",default:20}),"runs-per-query":v.integer({description:"Runs per query for reliability",default:3}),"poll-interval":v.integer({description:"Ms between approval polls",default:5e3}),timeout:v.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:i,flags:t}=await this.parse(k);this.requireAuth();let e=await y(`/api/eval-targets/${i.targetId}`);this.log(`Optimizing description for "${e.name}" v${e.version}`),this.log(`Current description: "${e.description}"`),this.log("Scores measure description-gated invocation choice (catalog decision protocol)."),this.log(""),this.log("Generating trigger queries...");let r=await this.generateTriggerQueries(e,t.queries,t),a=await q(`/api/eval-targets/${i.targetId}/trigger-evals`,{queries:r}),g=`${C}/eval-targets/${i.targetId}`;this.log(`
|
|
2
2
|
Generated ${r.length} trigger queries.`),this.log("Review and approve them at:"),this.log(` ${g}`),this.log(" (Triggers tab \u2192 click to review)"),this.log(`
|
|
3
3
|
Waiting for approval...`);let c=Date.now(),d=!1;for(;!d;){Date.now()-c>_&&this.error(`Timed out after ${_/6e4} minutes waiting for approval. Approve the trigger set at ${g} (Triggers tab) and re-run this command.`),await new Promise(h=>setTimeout(h,t["poll-interval"]));let p=(await y(`/api/eval-targets/${i.targetId}/trigger-evals?status=approved`)).find(h=>h.id===a.id);p&&(d=!0,r.length=0,r.push(...p.queries),this.log("Trigger queries approved!"))}let n=r.map((u,p)=>p).sort(()=>Math.random()-.5),s=Math.ceil(n.length*.6),o=n.slice(0,s),I=n.slice(s);await w(`/api/trigger-evals/${a.id}`,{trainIndices:o,testIndices:I});let x=o.map(u=>r[u]),D=I.map(u=>r[u]);this.log(`
|
|
4
4
|
Split: ${x.length} train, ${D.length} test`);let m=e.description,T=m,$=0;for(let u=1;u<=t["max-iterations"];u++){this.log(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as P,c as C}from"../../chunk-BU3ZGLQG.js";import{a as V}from"../../chunk-
|
|
1
|
+
import{b as P,c as C}from"../../chunk-BU3ZGLQG.js";import{a as V}from"../../chunk-TL57YUJV.js";import{a as N}from"../../chunk-U6AASXY3.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-KFNFLMUR.js";import{g as F}from"../../chunk-LARY6ZFT.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-SVZYRGO5.js";import"../../chunk-WULEBQPI.js";import"../../chunk-GPBN4ROE.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as A}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as w,f as m,g as S}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as k}from"../../chunk-ZLLER3HP.js";import{createInterface as _}from"node:readline/promises";import{Args as q,Flags as g}from"@oclif/core";var $=class O extends A{static{k(this,"EvalOptimizeCommand")}static description="Iteratively optimize eval target content using eval results as feedback";static examples=["<%= config.bin %> evals optimize <target-id>","<%= config.bin %> evals optimize <target-id> --auto --max-iterations 3"];static args={targetId:q.string({description:"Eval target ID",required:!0})};static flags={auto:g.boolean({description:"Skip interactive review, apply suggestions automatically",default:!1}),"max-iterations":g.integer({description:"Maximum optimization iterations",default:5}),threshold:g.string({description:"Stop if pass rate reaches this threshold (0-1)",default:"0.95"}),model:g.string({description:"Model for eval execution"}),"analyzer-model":g.string({description:"Model for analysis/suggestions"}),timeout:g.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:n,flags:e}=await this.parse(O);this.requireAuth();let t=await w(`/api/eval-targets/${n.targetId}`),i=await w(`/api/eval-targets/${n.targetId}/evals`);i.length===0&&this.error("No evals found. Create some first with `rulemetric evals create`.");let s=[...i].sort(()=>Math.random()-.5),c=Math.ceil(s.length*.6),u=s.slice(0,c),d=s.slice(c);this.log(`Optimizing "${t.name}" v${t.version}`),this.log(`Evals: ${u.length} train, ${d.length} test`);let h=parseFloat(e.threshold);this.log(`Config: max ${e["max-iterations"]} iterations, threshold ${(h*100).toFixed(0)}%`),e.auto&&this.log("Mode: auto (no interactive review)"),this.log("");let T=t.version,f=0,x=0;for(let l=1;l<=e["max-iterations"];l++){this.log(`
|
|
2
2
|
=== Iteration ${l} ===`),this.log("Running train evals...");let b=await this.runEvalsOnTarget(t,u,e),p=this.computePassRate(b);if(this.log(`Train pass rate: ${(p*100).toFixed(1)}%`),p>=h){this.log(`Train score ${(p*100).toFixed(1)}% >= threshold ${(h*100).toFixed(0)}%. Stopping.`);let o=await this.runEvalsOnTarget(t,d,e),z=this.computePassRate(o);this.log(`Final test score: ${(z*100).toFixed(1)}%`),await m("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:l,inputVersion:t.version,trainScore:p,testScore:z,analysis:{reason:"threshold_reached"},status:"completed"});break}this.log("Analyzing results...");let M=b.map(o=>({evalName:o.evalName,prompt:o.prompt,expectations:o.expectations,grading:o.grading})),a=await V({content:t.content,evalResults:M,model:e["analyzer-model"]??e.model,timeout:e.timeout});this.log(`
|
|
3
3
|
Assessment: ${a.overallAssessment}`),this.log(`Suggestions: ${a.suggestions.length}`);for(let o of a.suggestions)this.log(` - [${o.section}] ${o.reasoning}`);if(a.proposedContent===t.content){this.log("No changes proposed. Stopping."),await m("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:l,inputVersion:t.version,trainScore:p,analysis:{reason:"no_changes"},status:"completed"});break}if(!e.auto&&!await this.confirm(`
|
|
4
4
|
Apply the proposed changes as a new version? [y/N] `)){this.log("Changes not applied. Stopping."),await m("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:l,inputVersion:t.version,trainScore:p,analysis:{reason:"user_declined",suggestions:a.suggestions},status:"completed"});break}let r=await S(`/api/eval-targets/${t.id}`,{content:a.proposedContent});this.log(`Created v${r.version}`),this.log(`Running test evals on v${t.version} (baseline) and v${r.version}...`);let E=await this.runEvalsOnTarget(t,d,e),R=await this.runEvalsOnTarget(r,d,e),v=this.computePassRate(R),I=this.computePassRate(E);this.log(`Test pass rate: v${t.version} ${(I*100).toFixed(1)}% \u2192 v${r.version} ${(v*100).toFixed(1)}%`);let y=P(E,R);if(y&&this.log(C(y,t.version,r.version)),await m("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:l,inputVersion:t.version,outputVersion:r.version,trainScore:p,testScore:v,analysis:{suggestions:a.suggestions,overallAssessment:a.overallAssessment,priorTestScore:I,verdict:y},status:"completed"}),v>f)f=v,T=r.version,x=0;else if(x++,x>=2){this.log("No improvement for 2 consecutive iterations. Stopping.");break}t=r}this.log(`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{b as w,c as $}from"../../chunk-
|
|
1
|
+
import{b as w,c as $}from"../../chunk-QH7JB4UQ.js";import"../../chunk-52OHAULM.js";import{b as v}from"../../chunk-AZB34RT6.js";import"../../chunk-FLXWL4F4.js";import"../../chunk-YSY25OGG.js";import"../../chunk-M7QSC64D.js";import"../../chunk-CEM7JMUW.js";import"../../chunk-L3AXNCWC.js";import"../../chunk-ANHFE6US.js";import"../../chunk-GYKYJJNF.js";import"../../chunk-G7V4ZZZ3.js";import"../../chunk-AHLVY52I.js";import"../../chunk-YX2IGS72.js";import"../../chunk-55HFAX5Y.js";import"../../chunk-26XE3JCL.js";import"../../chunk-PPAHIVG5.js";import"../../chunk-5MXZJWQS.js";import"../../chunk-CT7FWSIU.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-AXTEV56C.js";import"../../chunk-VZYNZS5U.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-GYNZ3OZF.js";import"../../chunk-UPFH72PF.js";import"../../chunk-U6AASXY3.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-KFNFLMUR.js";import"../../chunk-LARY6ZFT.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-SVZYRGO5.js";import"../../chunk-WULEBQPI.js";import"../../chunk-GPBN4ROE.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as f}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as d,f as p,h}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import{Args as P,Flags as y}from"@oclif/core";var c=a(s=>s==null?"n/a":`${Math.round(s*100)}%`,"pct"),g=class s extends f{static{a(this,"EvalRefineCases")}static description="Retire non-discriminating eval cases and regenerate discriminating replacements (\xA76e)";static examples=["<%= config.bin %> evals refine-cases <target-id> # preview","<%= config.bin %> evals refine-cases <target-id> --yes # apply: retire + regenerate","<%= config.bin %> evals refine-cases <target-id> --yes --no-generate"];static args={targetId:P.string({description:"Eval target ID",required:!0})};static flags={yes:y.boolean({char:"y",description:"Apply (retire + regenerate). Without this, only previews."}),"no-generate":y.boolean({description:"Retire dead cases but do not regenerate replacements."})};async run(){let{args:b,flags:l}=await this.parse(s);this.requireAuth();let n=b.targetId,o=await d(`/api/eval-targets/${n}`),m=await d(`/api/eval-targets/${n}/judge-calibration`),i=m.caseDiscrimination,t=w(i);if(this.log(`Target "${o.name}" v${o.version} \u2014 judge ${m.judge.currentModel??"(unstamped)"}`),t.refused==="no-discrimination-data"){this.log("No case-discrimination data yet \u2014 run some evals with AND without the target first (`evals run` / the web Run Evals button), then refine.");return}if(this.log(`${i.total} diagnosable case(s): ${i.discriminating} discriminate, ${i.nonDiscriminating} flat/wrong-sign, ${i.unpaired} unpaired.`),t.refused==="all-discriminating"){this.log("Every case discriminates \u2014 nothing to retire. \u{1F389}");return}let C=i.cases.filter(e=>!e.discriminating),u=new Set(t.retire.map(e=>e.evalId));this.log(`
|
|
2
2
|
Would retire ${t.retire.length} non-discriminating case(s):`);for(let e of C)u.has(e.evalId)&&this.log(` \u2717 ${e.name} \u2014 ${c(e.withPassRate)} with vs ${c(e.withoutPassRate)} without (\u0394${(e.separation*100).toFixed(0)}pp) \u2014 ${e.note}`);for(let e of i.unpairedCases)u.has(e.evalId)&&this.log(` \u2717 ${e.name} \u2014 ${c(e.withPassRate)} with vs ${c(e.withoutPassRate)} without \u2014 unpaired`);if(t.replacementsRequired&&this.log(`
|
|
3
3
|
${t.summary}. Replacements are generated and created BEFORE anything is retired \u2014 a target left under the floor drops out of the nightly evolution rotation with no error anywhere.`),!l.yes){this.log(`
|
|
4
4
|
Preview only. Re-run with --yes to retire ${t.retire.length} case(s)${l["no-generate"]?"":" and generate replacements"}.`);return}let r=await $(t,{generate:a(e=>l["no-generate"]?Promise.resolve([]):v({content:o.content,name:o.name,feedback:e}),"generate"),createCase:a(e=>p(`/api/eval-targets/${n}/evals`,{name:e.name,prompt:e.prompt,expectations:e.expectations}),"createCase"),retireCase:a(async(e,R)=>{await h(`/api/eval-targets/${n}/evals/${e}`,{retire:!0,retiredReason:R})},"retireCase"),log:a(e=>this.log(e),"log")});if(r.skipped==="no-llm-backend"){this.warn(r.summary+" Install the `claude` CLI (or set ANTHROPIC_API_KEY), then run `evals refine-cases` again.");return}if(r.skipped==="no-replacements-generated"){this.warn(r.summary);return}this.log(`
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{d as k}from"../../chunk-
|
|
1
|
+
import{d as k}from"../../chunk-AXTEV56C.js";import"../../chunk-VZYNZS5U.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-GYNZ3OZF.js";import"../../chunk-UPFH72PF.js";import"../../chunk-U6AASXY3.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-LARY6ZFT.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-SVZYRGO5.js";import"../../chunk-WULEBQPI.js";import"../../chunk-GPBN4ROE.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as $}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as v,f as h}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as R}from"../../chunk-ZLLER3HP.js";import{Args as I,Flags as g}from"@oclif/core";var b=class _ extends ${static{R(this,"EvalRunCommand")}static description="Run evals against a target, optionally grade results, and post to API";static examples=["<%= config.bin %> evals run <target-id>","<%= config.bin %> evals run <target-id> --parallel 3 --runs-per-eval 2","<%= config.bin %> evals run <target-id> --skip-baseline --skip-grading"];static args={targetId:I.string({description:"Eval target ID",required:!0})};static flags={parallel:g.integer({description:"Number of parallel eval executions",default:1}),"runs-per-eval":g.integer({description:"Number of runs per eval for variance analysis",default:1}),iteration:g.integer({description:"Iteration number for tracking",default:1}),"skip-baseline":g.boolean({description:"Skip baseline (without_target) runs",default:!1}),"skip-grading":g.boolean({description:"Skip LLM grading step",default:!1}),model:g.string({description:"Model for eval execution (default: user configured)"}),"grader-model":g.string({description:"Model for grading (default: same as execution model)"}),timeout:g.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:c,flags:r}=await this.parse(_);this.requireAuth();let i=await v(`/api/eval-targets/${c.targetId}`),l=await v(`/api/eval-targets/${c.targetId}/evals`);l.length===0&&this.error(`No evals found for target "${i.name}". Create some with \`rulemetric evals create\`.`),this.log(`Running ${l.length} eval(s) for "${i.name}" v${i.version}`),this.log(`Config: ${r["runs-per-eval"]} run(s) per eval, parallel=${r.parallel}, iteration=${r.iteration}`),r["skip-baseline"]&&this.log("Skipping baseline runs"),r["skip-grading"]&&this.log("Skipping grading"),this.log("");let m=[{name:"with_target",content:i.content}];r["skip-baseline"]||m.push({name:"without_target"});let p=[];for(let a of l)for(let n of m)for(let t=1;t<=r["runs-per-eval"];t++)p.push({eval_:a,configuration:n.name,targetContent:n.content,runNumber:t});let u=[],y=r.parallel;for(let a=0;a<p.length;a+=y){let n=p.slice(a,a+y),t=await Promise.all(n.map(d=>this.executeAndGrade(d,i,r)));u.push(...t)}this.log(""),this.log("Posting results to API...");for(let a of u)await h("/api/eval-runs",a);try{await h(`/api/eval-targets/${c.targetId}/label-state`,{})}catch{}this.log(""),this.log("=== Results Summary ===");for(let a of m){let n=u.filter(e=>e.configuration===a.name),t=n.filter(e=>e.status==="completed"),d=t.filter(e=>Object.keys(e.grading).length>0);if(this.log(`
|
|
2
2
|
${a.name}:`),this.log(` Runs: ${t.length}/${n.length} completed`),d.length>0){let e=d.map(o=>o.grading.summary?.pass_rate??0),s=e.reduce((o,f)=>o+f,0)/e.length;this.log(` Avg pass_rate: ${(s*100).toFixed(1)}%`)}for(let e of n){let s=l.find(x=>x.id===e.evalId)?.name??e.evalId,o=e.grading.summary?.pass_rate,f=o!==void 0?` pass_rate=${(o*100).toFixed(0)}%`:"",w=e.timing.duration_ms?` ${(e.timing.duration_ms/1e3).toFixed(1)}s`:"";this.log(` [${e.status}] ${s} run#${e.runNumber}${f}${w}`)}}if(!r["skip-baseline"]&&u.length>0){let a=u.filter(t=>t.configuration==="with_target"&&Object.keys(t.grading).length>0),n=u.filter(t=>t.configuration==="without_target"&&Object.keys(t.grading).length>0);if(a.length>0&&n.length>0){let t=a.map(s=>s.grading.summary?.pass_rate??0).reduce((s,o)=>s+o,0)/a.length,d=n.map(s=>s.grading.summary?.pass_rate??0).reduce((s,o)=>s+o,0)/n.length,e=t-d;this.log(`
|
|
3
3
|
Delta: ${e>0?"+":""}${(e*100).toFixed(1)}% (with_target vs without_target)`)}}}async executeAndGrade(c,r,i){return k(c,{targetId:r.id,targetVersion:r.version,iteration:i.iteration,timeout:i.timeout,model:i.model,graderModel:i["grader-model"],skipGrading:i["skip-grading"],targetType:r.type,targetName:r.name},l=>this.log(l))}};export{b as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c,d as m}from"../../chunk-
|
|
1
|
+
import{c,d as m}from"../../chunk-7V6LLVAY.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-U6AASXY3.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-LARY6ZFT.js";import"../../chunk-JP6ULOEX.js";import"../../chunk-SVZYRGO5.js";import"../../chunk-WULEBQPI.js";import"../../chunk-GPBN4ROE.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as u}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import{Args as p,Flags as s}from"@oclif/core";var o=r(n=>n==null?"\u2014":`${(n*100).toFixed(0)}%`,"pct"),g=class n extends u{static{r(this,"EvalValidateJudge")}static description="Score a second model against your human judge-review labels (\xA76g validation pass)";static examples=["<%= config.bin %> evals validate-judge <target-id> # auto-detect installed CLIs","<%= config.bin %> evals validate-judge <target-id> --engine codex --model gpt-5.5","<%= config.bin %> evals validate-judge <target-id> --model claude-sonnet-5 --json","<%= config.bin %> evals validate-judge <target-id> --limit 5 # quick sample"];static args={targetId:p.string({description:"Eval target ID",required:!0})};static flags={model:s.string({description:"Second reviewer model. Default: resolved from your installed tooling (codex: your ~/.codex/config.toml model; claude: a tier that differs from the original judge)."}),engine:s.string({description:"CLI that runs the second reviewer. `auto` prefers your installed codex for a cross-vendor reviewer \u2014 two Claude models share a training lineage, so their agreement overstates independence.",options:["auto","claude","codex"],default:"auto"}),limit:s.integer({description:"Sample only the N most-recently-annotated runs (cost control / smoke)"}),"skip-reviewed":s.boolean({description:"Only re-grade assertions this reviewer model has not ruled on yet",default:!1}),parallel:s.integer({description:"Concurrent re-grades",default:3}),timeout:s.integer({description:"Timeout per re-grade in ms",default:12e4}),json:s.boolean({description:"Emit the full report as JSON"})};async run(){let{args:h,flags:i}=await this.parse(n);this.requireAuth();let a;try{a=await m({targetId:h.targetId,engineFlag:i.engine,modelFlag:i.model,limit:i.limit,parallel:i.parallel,timeoutMs:i.timeout,skipReviewed:i["skip-reviewed"],log:r(t=>this.log(t),"log"),warn:r(t=>this.warn(t),"warn")})}catch(t){throw t instanceof c&&this.error(t.message),t}let{report:e,judgeModels:l,reviewerModel:d}=a;if(l.length===1&&l[0]===d&&this.warn(`Second reviewer resolved to the SAME model as the original judge (${l[0]}) \u2014 this measures self-consistency, not independent review.`),i.json){this.log(JSON.stringify({target:a.targetName,judgeA:l,judgeB:d,persisted:a.persisted,alreadyReviewed:a.alreadyReviewed,...e},null,2));return}if(e.pairs===0&&a.alreadyReviewed>0){this.log(`All ${a.alreadyReviewed} labeled assertion(s) already reviewed by ${d} \u2014 nothing new to grade.`);return}if(this.log(""),this.log(`Second reviewer: ${d} \u2014 scored against ${e.pairs} human-labeled assertion(s)`+(e.skipped?` (${e.skipped} skipped)`:"")),this.log(""),this.log(` reviewer vs HUMAN: ${o(e.bVsHuman.overall.rate)} overall \xB7 ${o(e.bVsHuman.onJudgePass.rate)} where judge passed \xB7 ${o(e.bVsHuman.onJudgeFail.rate)} where judge failed`),this.log(` original judge vs human: ${o(e.aVsHuman.overall.rate)} (your approve rate)`),this.log(` reviewer vs judge: ${o(e.bVsA.overall.rate)} (inter-model, not truth)`),this.log(` Cohen's \u03BA (reviewer vs human): ${e.kappaBvsHuman==null?"undefined (degenerate marginals)":e.kappaBvsHuman.toFixed(2)}`),this.log(""),e.suggestedAnchorWeight!=null&&this.log(` suggested \xA76g anchor weight if used as a passive label source: ${e.suggestedAnchorWeight.toFixed(2)} (misclassification attenuation (2\xB7acc\u22121)\xB2; validated:false either way)`),e.disagreements.length>0){this.log(""),this.log(` ${e.disagreements.length} disagreement(s) with your labels \u2014 flagged on the Review tab:`);for(let t of e.disagreements.slice(0,10))this.log(` run ${t.runId.slice(0,8)} #${t.expectationIndex}: human=${t.humanPassed?"pass":"fail"} reviewer=${t.judgeBPassed?"pass":"fail"} \u2014 ${t.text.slice(0,80)}`);e.disagreements.length>10&&this.log(` \u2026 and ${e.disagreements.length-10} more (use --json for all)`)}}};export{g as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as c}from"../../chunk-MODXEGCU.js";import{a as d}from"../../chunk-
|
|
1
|
+
import{a as c}from"../../chunk-MODXEGCU.js";import{a as d}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{e as l}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{Flags as u}from"@oclif/core";import{printTable as p}from"@oclif/table";function s(e){return`${e>0?"+":""}${(e*100).toFixed(0)}pp`}n(s,"pp");function m(e){return e?e.contentChanged?"edited mid-test":e.randomisationSuspect?"suspect":e.resolution==="insufficient"?"insufficient":e.resolution==="resolved"&&e.delta!=null?s(e.delta):"no effect":"-"}n(m,"verdictCell");function g(e){return e?e.resolution==="resolved"&&e.ci?`95% CI ${s(e.ci.lower)} to ${s(e.ci.upper)}`:e.reason??"":""}n(g,"detailCell");var o=class e extends d{static{n(this,"ExperimentsList")}static description="Show instructions under randomised test and what each sample supports";static examples=["<%= config.bin %> experiments list","<%= config.bin %> experiments list --project /path/to/project","<%= config.bin %> experiments list --all"];static flags={project:u.string({char:"p",description:"Project path (defaults to current directory)"}),all:u.boolean({description:"Every project, not just this one",default:!1})};async run(){let{flags:i}=await this.parse(e);this.requireAuth();let a=new URLSearchParams({limit:"50"});i.all||a.set("projectPath",c(i.project??process.cwd()));let r=await l(`/api/instruction-experiments?${a}`);if(r.experiments.length===0){this.log(i.all?"No instructions are under test. One enters the loop when it is nominated for measurement.":"No instructions are under test for this project. Try --all, or nominate a candidate.");return}p({data:r.experiments.map(t=>({Instruction:t.instructionName,Status:t.graduation?`graduated \xB7 ${t.graduation.decision==="always"?"always inject":"never inject"}`:t.stoppedReason==="trial_neutral"||t.stoppedReason==="trial_inconclusive"?"ended \xB7 inconclusive":t.stoppedReason==="content_changed"?"ended \xB7 content edited":t.status,Verdict:m(t.verdict),Assigned:t.verdict?`${t.verdict.assigned.treated}/${t.verdict.assigned.control}`:"-",Measured:t.verdict?`${t.verdict.measured.treated}/${t.verdict.measured.control}`:"-",Detail:g(t.verdict)})),columns:["Instruction","Status","Verdict","Assigned","Measured","Detail"]}),this.log(""),this.log("Assigned/Measured are treated/control. Assigned is the arm; measured is what came back graded."),r.total>r.experiments.length&&this.log(`Showing ${r.experiments.length} of ${r.total}.`)}};export{o as default,g as detailCell,m as verdictCell};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as y,c as h}from"../../chunk-NVABG3AO.js";import{e,i as p,k as m,m as f}from"../../chunk-QWCEZEDO.js";import"../../chunk-KKDHD4XA.js";import{b as d,d as u}from"../../chunk-SZ62CP55.js";import{B as l,E as g}from"../../chunk-OZQNSELV.js";import"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import{a as c}from"../../chunk-
|
|
1
|
+
import{b as y,c as h}from"../../chunk-NVABG3AO.js";import{e,i as p,k as m,m as f}from"../../chunk-QWCEZEDO.js";import"../../chunk-KKDHD4XA.js";import{b as d,d as u}from"../../chunk-SZ62CP55.js";import{B as l,E as g}from"../../chunk-OZQNSELV.js";import"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import{a as c}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import{spawn as S}from"node:child_process";import{existsSync as v,readFileSync as R,statSync as C,writeFileSync as M}from"node:fs";import{homedir as T}from"node:os";import{join as o}from"node:path";var s=o(T(),".config","rulemetric"),x=o(s,"proxy-addon.version"),_=o(s,"proxy.pid"),w=o(s,"proxy-drift-restart.at"),E=10*6e4,n=class P extends c{static{a(this,"GatewayEnsure")}static description="Ensure the gateway proxy is running (called by hooks, not for direct use)";static hidden=!0;async run(){await this.parse(P),this.maybeRestartStaleProxy();let t=await p(e);if(t.status==="ours-live"){let r=h(i=>{i==="vscode"?l(e):g(e)});r.length>0&&console.error(`[RuleMetric] Gateway healthy again \u2014 restored ${r.join(", ")} proxy settings.`);return}if(t.status==="foreign"){if(m())return;let r=y(e);console.error(`[RuleMetric] A non-RuleMetric process holds :${e} \u2014 cannot start gateway. `+(r.length>0?`Unpinned ${r.join(", ")} proxy settings so editors are not routed through it. `:"")+"Run `rulemetric diagnostics` if Claude Code HTTPS requests fail.");return}try{f(this.config.version)}catch(r){console.error(`[RuleMetric] Could not start gateway: ${r.message}`)}}maybeRestartStaleProxy(){try{if(!v(x))return;let t=R(x,"utf-8").trim();if(!t||t===this.config.version)return;let r=R(_,"utf-8").trim(),i=Number(r);if(!Number.isFinite(i)||!u(i,d))return;try{if(Date.now()-C(w).mtimeMs<E)return}catch{}M(w,new Date().toISOString()),S(process.execPath,[process.argv[1],"proxy","restart"],{detached:!0,stdio:"ignore"}).unref(),console.error(`[RuleMetric] Capture proxy is running CLI ${t} but ${this.config.version} is installed \u2014 restarting it in the background.`)}catch{}}};export{n as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as mt}from"../../chunk-5INUF4A4.js";import{a as yt}from"../../chunk-6XEC6474.js";import{e as s,i as F,j as V,k as q,m as A,n as W}from"../../chunk-QWCEZEDO.js";import{e as D}from"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import"../../chunk-N7ODX6PO.js";import{B as ht,E as gt,H as pt,I as ft,e as Z,f as tt,g as et,i as st,j as ot,k as it,n as rt,p as at,q as nt,r as lt,u as ct,v as ut,y as dt}from"../../chunk-OZQNSELV.js";import{a as J,b as z,c as m,d as Q,g as R}from"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import{a as f}from"../../chunk-PJ3WHQ67.js";import{a as X}from"../../chunk-QPVUGTDP.js";import{a as B}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import{c as Y}from"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import{b as M}from"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import{a as L}from"../../chunk-PZNWH4VQ.js";import{a as w}from"../../chunk-ZLLER3HP.js";import{Flags as y}from"@oclif/core";import{execFileSync as Ct,spawnSync as l}from"node:child_process";import{existsSync as u}from"node:fs";import{homedir as kt}from"node:os";import{join as _,dirname as wt}from"node:path";function xt(){try{let h=Ct("/bin/sh",["-c","command -v rulemetric"],{encoding:"utf-8"}).trim();if(h&&u(h))return wt(h)}catch{}}w(xt,"resolveHookBinDir");function Pt(){try{return Ct("launchctl",["list","com.rulemetric.gateway"],{stdio:["ignore","pipe","pipe"]}),!0}catch{return!1}}w(Pt,"isGatewayLaunchdManaged");var o=_(kt(),".mitmproxy","mitmproxy-ca-cert.pem"),K=class h extends B{static{w(this,"HooksInstall")}static description="Install session tracking hooks and context capture proxy for Claude Code";static examples=["<%= config.bin %> hooks install","<%= config.bin %> hooks install --global","<%= config.bin %> hooks install --no-proxy"];static flags={"no-proxy":y.boolean({default:!1,description:"Skip proxy/gateway configuration (hooks only)"}),"project-dir":y.string({description:"Project directory to install hooks in (defaults to cwd)"}),"user-hooks":y.boolean({description:"Write user-level Cursor/Antigravity hooks (~/.cursor, ~/.gemini). Required for Cursor capture \u2014 its traffic bypasses the proxy.",default:!0,allowNo:!0}),global:y.boolean({char:"g",default:!1,description:"Install hooks globally (~/.claude/settings.json) so all projects are tracked"}),"statusline-usage":y.boolean({default:!1,description:"Install the statusline shim so Claude Code pushes live rate_limits on every refresh (makes /usage rings update in real time without needing the proxy)"})};async run(){let{flags:i}=await this.parse(h),r=i.global,a=r?kt():i["project-dir"]??process.cwd(),x=_(a,".claude"),C=it(x,r),$=r?"settings.json":"settings.local.json",P=i["no-proxy"],b=!1,g=P?"no_proxy_flag":void 0,p=!1,S=[];r&&this.log(`Installing hooks globally \u2192 ${C}`);let{settings:n,recoveredBackup:I}=Z(C);if(I&&this.log(`[!!] ${C} was not valid JSON \u2014 backed it up to ${I} and continued with a fresh file.`),!r){let e=rt(_(x,"settings.json"),s);e.migrated&&(this.log("[OK] Moved RuleMetric machine-local state out of the shared .claude/settings.json (it now lives in .claude/settings.local.json)"),e.backupPath&&this.log(` Previous shared settings backed up \u2192 ${e.backupPath}`),e.removedStatusline&&u(J)&&!R(n)&&(n.statusLine=m))}let E=L();(E.accessToken||process.env.RULEMETRIC_ACCESS_TOKEN)&&!E.apiKey&&!process.env.RULEMETRIC_API_KEY&&await X(this.log.bind(this),this.warn.bind(this),this.config.version);let vt=st(n),k=xt();if(et(n,k),this.log(vt?`[OK] Refreshed RuleMetric Claude Code session hooks \u2192 .claude/${$}`:`[OK] Installed RuleMetric Claude Code session hooks \u2192 .claude/${$}`),!P){let e=!!f("mitmdump");if(e||(this.log(""),this.log("[!!] mitmproxy not found \u2014 installing..."),S=["brew","pipx","uv"].filter(t=>!!f(t)),e=this.installMitmproxy(),e||(this.log("[!!] Could not install mitmproxy. Skipping proxy config."),this.log(" Install manually: pipx install mitmproxy"),this.log(" Then re-run: rulemetric hooks install"))),u(o))this.log("[OK] CA certificate found");else{this.log("[..] Generating CA certificate...");let t=f("mitmdump");t&&(l(t,["--set","listen_port=0","-q"],{timeout:5e3,stdio:"ignore"}),u(o)?this.log(`[OK] CA certificate generated at ${o}`):this.log("[!!] Could not generate CA cert"))}let c=u(o);c&&!this.isCACertTrusted()?(this.log("[..] Installing CA certificate into system trust store (requires admin)..."),p=this.trustCACert(),p?this.log("[OK] CA certificate trusted by system"):(this.log("[!!] Could not install CA cert automatically."),process.platform==="darwin"?this.log(` Run manually: sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${o}`):process.platform==="linux"&&this.log(` Run manually: sudo cp ${o} /usr/local/share/ca-certificates/mitmproxy-ca.crt && sudo update-ca-certificates`))):c&&(this.log("[OK] CA certificate already trusted"),p=!0);let d=Pt(),O=await F(s);if(d)this.log("[OK] Gateway managed by launchd (com.rulemetric.gateway)");else if(O.status==="ours-live")this.log("[OK] Gateway already running");else if(O.status==="foreign"&&q()){this.log("[..] Restarting gateway (running build predates the identity handshake)..."),W(),await new Promise(t=>setTimeout(t,500));try{let t=A(this.config.version);this.log(`[OK] Gateway restarted (PID ${t})`)}catch(t){this.log(`[!!] Could not restart gateway: ${t.message}`)}}else if(O.status!=="foreign")try{let t=A(this.config.version);this.log(`[OK] Gateway started (PID ${t})`)}catch(t){this.log(`[!!] Could not start gateway: ${t.message}`)}let G=await V(s,{timeoutMs:4e3});if(!c)g=e?"ca_not_generated":S.length===0?"no_package_manager":"mitmproxy_install_failed",this.log("[!!] No CA certificate \u2014 NOT setting HTTPS_PROXY (capture stays hooks-only)."),this.log(" Install mitmproxy, then re-run: rulemetric hooks install");else if(G.status==="foreign"&&!d){g="gateway_port_foreign";let t=D(s);this.log(`[!!] Port :${s} is held by a process that is NOT the RuleMetric gateway \u2014 NOT setting HTTPS_PROXY.`),this.log(t?` Holding the port: ${t}`:` Could not identify the holder (try: lsof -nP -iTCP:${s} -sTCP:LISTEN)`),this.log(" Capture still works via hooks. Free the port, then re-run: rulemetric hooks install")}else if(G.status==="dead")g="gateway_not_live",this.log(`[!!] Gateway is not answering on :${s} \u2014 NOT setting HTTPS_PROXY.`),this.log(" Capture still works via hooks. To enable deep (proxy) capture later:"),this.log(" rulemetric proxy start && rulemetric hooks install");else{let t=n.env??{};t.HTTPS_PROXY=`http://localhost:${s}`,t.NO_PROXY=ot,u(o)&&(t.NODE_EXTRA_CA_CERTS=o),n.env=t,b=!0,this.log(`[OK] HTTPS_PROXY set to gateway on :${s} (verified live)`),ct(a,s,o)&&this.log("[OK] Cursor proxy configured \u2192 .cursor/settings.json"),ut(a,s,o)&&this.log("[OK] VS Code workspace proxy configured \u2192 .vscode/settings.json"),ht(s)&&this.log("[OK] VS Code user proxy configured \u2192 ~/Library/Application Support/Code/User/settings.json"),gt(s)&&this.log("[OK] Cursor user proxy configured \u2192 ~/Library/Application Support/Cursor/User/settings.json"),p?dt(s,o)&&this.log("[OK] HTTPS_PROXY set for GUI apps (launchctl + LaunchAgent)"):(g="ca_untrusted",this.log("[!!] CA not trusted \u2014 skipping machine-wide GUI proxy (would break native-app TLS)."),this.log(" Claude Code capture is unaffected. Trust the CA + re-run to enable cross-app capture."))}}let v=[];if(!r){let e=at(a,k);e&&(this.log(`[OK] Cursor hooks configured \u2192 ${e}`),v.push(e));let c=lt(a,k);c&&(this.log(`[OK] Copilot Agent hooks configured \u2192 ${c}`),v.push(c));let d=pt(a);d&&(this.log(`[OK] Antigravity workspace hooks configured \u2192 ${d}`),v.push(d))}let H=i["user-hooks"]?ft():null;H&&this.log(`[OK] Antigravity user hooks configured \u2192 ${H}`);let U=i["user-hooks"]?nt(k):null;if(U&&this.log(`[OK] Cursor user hooks configured \u2192 ${U}`),i["user-hooks"]||(this.log("[--] Skipped user-level Cursor/Antigravity hooks (--no-user-hooks)."),this.log(" Cursor capture will not work: its chat traffic bypasses the proxy,"),this.log(" so hooks are the only path. Claude Code capture is unaffected.")),i["statusline-usage"])if(R(n))this.log("[OK] Statusline shim already installed");else{let e=Q(n);z(e),n.statusLine=m,e?this.log(`[OK] Statusline shim installed \u2192 ${m.command} (chains to: ${e})`):this.log(`[OK] Statusline shim installed \u2192 ${m.command}`),this.log(" Rate-limit rings will now update on Claude Code's statusline refresh cadence")}let{backupPath:N}=tt(C,n);N&&this.log(`[OK] Backed up previous settings \u2192 ${N}`),this.log(""),this.log("Setup complete! Next steps:"),r?(this.log(" 1. Install always-on API: rulemetric service install"),this.log(" 2. Start Claude Code in any project \u2014 all sessions tracked automatically"),this.log(""),this.log("The API service starts on login and restarts on crash.")):P?(this.log(" 1. Start Claude Code \u2014 sessions are captured by the hooks just installed"),this.log(""),this.log("No proxy means no mitmproxy / CA cert needed. The hooks capture full"),this.log("sessions on their own; re-run without --no-proxy to also capture system"),this.log("prompts for instruction-effectiveness linking.")):(this.log(" 1. Start Claude Code \u2014 sessions are captured by hooks immediately"),b?this.log(" 2. Full-depth capture is ON \u2014 the proxy is live on :"+s+"."):this.log(" 2. Enable full depth (proxy not yet live): rulemetric proxy start"),this.log(""),this.log("Hooks capture every session (lifecycle + transcript). The proxy adds the"),this.log("rendered system prompt (instruction-effectiveness linking) + cross-tool capture."),this.log(""),this.log("To capture traffic from other clients (Python, curl, etc.):"),this.log(' eval "$(rulemetric proxy env --all)"'));let j=mt(a,v);j&&this.log(j),await M(),Y("hooks_installed",{proxy:b,caTrusted:p,reason:g,installers:S,global:r},this.config.version);let T=await yt();this.log(""),T.available?this.log(`[OK] tmux found${T.version?` (v${T.version})`:""} \u2014 live send enabled`):this.log("[!!] tmux not found \u2014 live send will fall back to opening Terminal. Install with: brew install tmux")}installMitmproxy(){for(let[i,r]of[["pipx",["install","mitmproxy"]],["uv",["tool","install","mitmproxy"]],["brew",["install","mitmproxy"]]]){let a=f(i);if(a&&(this.log(` Installing via ${i}...`),l(a,[...r],{stdio:"inherit"}).status===0))return!0}return!1}isCACertTrusted(){return process.platform==="darwin"?l("security",["verify-cert","-c",o],{stdio:"pipe"}).status===0:process.platform==="linux"?u("/usr/local/share/ca-certificates/mitmproxy-ca.crt"):process.platform==="win32"?l("certutil",["-verify",o],{stdio:"pipe"}).status===0:!1}trustCACert(){return process.platform==="darwin"?l("sudo",["security","add-trusted-cert","-d","-r","trustRoot","-k","/Library/Keychains/System.keychain",o],{stdio:"inherit"}).status===0:process.platform==="linux"?l("sudo",["cp",o,"/usr/local/share/ca-certificates/mitmproxy-ca.crt"],{stdio:"inherit"}).status!==0?!1:l("sudo",["update-ca-certificates"],{stdio:"inherit"}).status===0:process.platform==="win32"?l("certutil",["-addstore","-f","Root",o],{stdio:"inherit"}).status===0:!1}};export{K as default};
|
|
1
|
+
import{b as mt}from"../../chunk-5INUF4A4.js";import{a as yt}from"../../chunk-6XEC6474.js";import{e as s,i as F,j as V,k as q,m as A,n as W}from"../../chunk-QWCEZEDO.js";import{e as D}from"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import"../../chunk-N7ODX6PO.js";import{B as ht,E as gt,H as pt,I as ft,e as Z,f as tt,g as et,i as st,j as ot,k as it,n as rt,p as at,q as nt,r as lt,u as ct,v as ut,y as dt}from"../../chunk-OZQNSELV.js";import{a as J,b as z,c as m,d as Q,g as R}from"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import{a as f}from"../../chunk-PJ3WHQ67.js";import{a as X}from"../../chunk-EOTSCWFS.js";import{a as B}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import{c as Y}from"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import{b as M}from"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import{a as L}from"../../chunk-PZNWH4VQ.js";import{a as w}from"../../chunk-ZLLER3HP.js";import{Flags as y}from"@oclif/core";import{execFileSync as Ct,spawnSync as l}from"node:child_process";import{existsSync as u}from"node:fs";import{homedir as kt}from"node:os";import{join as _,dirname as wt}from"node:path";function xt(){try{let h=Ct("/bin/sh",["-c","command -v rulemetric"],{encoding:"utf-8"}).trim();if(h&&u(h))return wt(h)}catch{}}w(xt,"resolveHookBinDir");function Pt(){try{return Ct("launchctl",["list","com.rulemetric.gateway"],{stdio:["ignore","pipe","pipe"]}),!0}catch{return!1}}w(Pt,"isGatewayLaunchdManaged");var o=_(kt(),".mitmproxy","mitmproxy-ca-cert.pem"),K=class h extends B{static{w(this,"HooksInstall")}static description="Install session tracking hooks and context capture proxy for Claude Code";static examples=["<%= config.bin %> hooks install","<%= config.bin %> hooks install --global","<%= config.bin %> hooks install --no-proxy"];static flags={"no-proxy":y.boolean({default:!1,description:"Skip proxy/gateway configuration (hooks only)"}),"project-dir":y.string({description:"Project directory to install hooks in (defaults to cwd)"}),"user-hooks":y.boolean({description:"Write user-level Cursor/Antigravity hooks (~/.cursor, ~/.gemini). Required for Cursor capture \u2014 its traffic bypasses the proxy.",default:!0,allowNo:!0}),global:y.boolean({char:"g",default:!1,description:"Install hooks globally (~/.claude/settings.json) so all projects are tracked"}),"statusline-usage":y.boolean({default:!1,description:"Install the statusline shim so Claude Code pushes live rate_limits on every refresh (makes /usage rings update in real time without needing the proxy)"})};async run(){let{flags:i}=await this.parse(h),r=i.global,a=r?kt():i["project-dir"]??process.cwd(),x=_(a,".claude"),C=it(x,r),$=r?"settings.json":"settings.local.json",P=i["no-proxy"],b=!1,g=P?"no_proxy_flag":void 0,p=!1,S=[];r&&this.log(`Installing hooks globally \u2192 ${C}`);let{settings:n,recoveredBackup:I}=Z(C);if(I&&this.log(`[!!] ${C} was not valid JSON \u2014 backed it up to ${I} and continued with a fresh file.`),!r){let e=rt(_(x,"settings.json"),s);e.migrated&&(this.log("[OK] Moved RuleMetric machine-local state out of the shared .claude/settings.json (it now lives in .claude/settings.local.json)"),e.backupPath&&this.log(` Previous shared settings backed up \u2192 ${e.backupPath}`),e.removedStatusline&&u(J)&&!R(n)&&(n.statusLine=m))}let E=L();(E.accessToken||process.env.RULEMETRIC_ACCESS_TOKEN)&&!E.apiKey&&!process.env.RULEMETRIC_API_KEY&&await X(this.log.bind(this),this.warn.bind(this),this.config.version);let vt=st(n),k=xt();if(et(n,k),this.log(vt?`[OK] Refreshed RuleMetric Claude Code session hooks \u2192 .claude/${$}`:`[OK] Installed RuleMetric Claude Code session hooks \u2192 .claude/${$}`),!P){let e=!!f("mitmdump");if(e||(this.log(""),this.log("[!!] mitmproxy not found \u2014 installing..."),S=["brew","pipx","uv"].filter(t=>!!f(t)),e=this.installMitmproxy(),e||(this.log("[!!] Could not install mitmproxy. Skipping proxy config."),this.log(" Install manually: pipx install mitmproxy"),this.log(" Then re-run: rulemetric hooks install"))),u(o))this.log("[OK] CA certificate found");else{this.log("[..] Generating CA certificate...");let t=f("mitmdump");t&&(l(t,["--set","listen_port=0","-q"],{timeout:5e3,stdio:"ignore"}),u(o)?this.log(`[OK] CA certificate generated at ${o}`):this.log("[!!] Could not generate CA cert"))}let c=u(o);c&&!this.isCACertTrusted()?(this.log("[..] Installing CA certificate into system trust store (requires admin)..."),p=this.trustCACert(),p?this.log("[OK] CA certificate trusted by system"):(this.log("[!!] Could not install CA cert automatically."),process.platform==="darwin"?this.log(` Run manually: sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${o}`):process.platform==="linux"&&this.log(` Run manually: sudo cp ${o} /usr/local/share/ca-certificates/mitmproxy-ca.crt && sudo update-ca-certificates`))):c&&(this.log("[OK] CA certificate already trusted"),p=!0);let d=Pt(),O=await F(s);if(d)this.log("[OK] Gateway managed by launchd (com.rulemetric.gateway)");else if(O.status==="ours-live")this.log("[OK] Gateway already running");else if(O.status==="foreign"&&q()){this.log("[..] Restarting gateway (running build predates the identity handshake)..."),W(),await new Promise(t=>setTimeout(t,500));try{let t=A(this.config.version);this.log(`[OK] Gateway restarted (PID ${t})`)}catch(t){this.log(`[!!] Could not restart gateway: ${t.message}`)}}else if(O.status!=="foreign")try{let t=A(this.config.version);this.log(`[OK] Gateway started (PID ${t})`)}catch(t){this.log(`[!!] Could not start gateway: ${t.message}`)}let G=await V(s,{timeoutMs:4e3});if(!c)g=e?"ca_not_generated":S.length===0?"no_package_manager":"mitmproxy_install_failed",this.log("[!!] No CA certificate \u2014 NOT setting HTTPS_PROXY (capture stays hooks-only)."),this.log(" Install mitmproxy, then re-run: rulemetric hooks install");else if(G.status==="foreign"&&!d){g="gateway_port_foreign";let t=D(s);this.log(`[!!] Port :${s} is held by a process that is NOT the RuleMetric gateway \u2014 NOT setting HTTPS_PROXY.`),this.log(t?` Holding the port: ${t}`:` Could not identify the holder (try: lsof -nP -iTCP:${s} -sTCP:LISTEN)`),this.log(" Capture still works via hooks. Free the port, then re-run: rulemetric hooks install")}else if(G.status==="dead")g="gateway_not_live",this.log(`[!!] Gateway is not answering on :${s} \u2014 NOT setting HTTPS_PROXY.`),this.log(" Capture still works via hooks. To enable deep (proxy) capture later:"),this.log(" rulemetric proxy start && rulemetric hooks install");else{let t=n.env??{};t.HTTPS_PROXY=`http://localhost:${s}`,t.NO_PROXY=ot,u(o)&&(t.NODE_EXTRA_CA_CERTS=o),n.env=t,b=!0,this.log(`[OK] HTTPS_PROXY set to gateway on :${s} (verified live)`),ct(a,s,o)&&this.log("[OK] Cursor proxy configured \u2192 .cursor/settings.json"),ut(a,s,o)&&this.log("[OK] VS Code workspace proxy configured \u2192 .vscode/settings.json"),ht(s)&&this.log("[OK] VS Code user proxy configured \u2192 ~/Library/Application Support/Code/User/settings.json"),gt(s)&&this.log("[OK] Cursor user proxy configured \u2192 ~/Library/Application Support/Cursor/User/settings.json"),p?dt(s,o)&&this.log("[OK] HTTPS_PROXY set for GUI apps (launchctl + LaunchAgent)"):(g="ca_untrusted",this.log("[!!] CA not trusted \u2014 skipping machine-wide GUI proxy (would break native-app TLS)."),this.log(" Claude Code capture is unaffected. Trust the CA + re-run to enable cross-app capture."))}}let v=[];if(!r){let e=at(a,k);e&&(this.log(`[OK] Cursor hooks configured \u2192 ${e}`),v.push(e));let c=lt(a,k);c&&(this.log(`[OK] Copilot Agent hooks configured \u2192 ${c}`),v.push(c));let d=pt(a);d&&(this.log(`[OK] Antigravity workspace hooks configured \u2192 ${d}`),v.push(d))}let H=i["user-hooks"]?ft():null;H&&this.log(`[OK] Antigravity user hooks configured \u2192 ${H}`);let U=i["user-hooks"]?nt(k):null;if(U&&this.log(`[OK] Cursor user hooks configured \u2192 ${U}`),i["user-hooks"]||(this.log("[--] Skipped user-level Cursor/Antigravity hooks (--no-user-hooks)."),this.log(" Cursor capture will not work: its chat traffic bypasses the proxy,"),this.log(" so hooks are the only path. Claude Code capture is unaffected.")),i["statusline-usage"])if(R(n))this.log("[OK] Statusline shim already installed");else{let e=Q(n);z(e),n.statusLine=m,e?this.log(`[OK] Statusline shim installed \u2192 ${m.command} (chains to: ${e})`):this.log(`[OK] Statusline shim installed \u2192 ${m.command}`),this.log(" Rate-limit rings will now update on Claude Code's statusline refresh cadence")}let{backupPath:N}=tt(C,n);N&&this.log(`[OK] Backed up previous settings \u2192 ${N}`),this.log(""),this.log("Setup complete! Next steps:"),r?(this.log(" 1. Install always-on API: rulemetric service install"),this.log(" 2. Start Claude Code in any project \u2014 all sessions tracked automatically"),this.log(""),this.log("The API service starts on login and restarts on crash.")):P?(this.log(" 1. Start Claude Code \u2014 sessions are captured by the hooks just installed"),this.log(""),this.log("No proxy means no mitmproxy / CA cert needed. The hooks capture full"),this.log("sessions on their own; re-run without --no-proxy to also capture system"),this.log("prompts for instruction-effectiveness linking.")):(this.log(" 1. Start Claude Code \u2014 sessions are captured by hooks immediately"),b?this.log(" 2. Full-depth capture is ON \u2014 the proxy is live on :"+s+"."):this.log(" 2. Enable full depth (proxy not yet live): rulemetric proxy start"),this.log(""),this.log("Hooks capture every session (lifecycle + transcript). The proxy adds the"),this.log("rendered system prompt (instruction-effectiveness linking) + cross-tool capture."),this.log(""),this.log("To capture traffic from other clients (Python, curl, etc.):"),this.log(' eval "$(rulemetric proxy env --all)"'));let j=mt(a,v);j&&this.log(j),await M(),Y("hooks_installed",{proxy:b,caTrusted:p,reason:g,installers:S,global:r},this.config.version);let T=await yt();this.log(""),T.available?this.log(`[OK] tmux found${T.version?` (v${T.version})`:""} \u2014 live send enabled`):this.log("[!!] tmux not found \u2014 live send will fall back to opening Terminal. Install with: brew install tmux")}installMitmproxy(){for(let[i,r]of[["pipx",["install","mitmproxy"]],["uv",["tool","install","mitmproxy"]],["brew",["install","mitmproxy"]]]){let a=f(i);if(a&&(this.log(` Installing via ${i}...`),l(a,[...r],{stdio:"inherit"}).status===0))return!0}return!1}isCACertTrusted(){return process.platform==="darwin"?l("security",["verify-cert","-c",o],{stdio:"pipe"}).status===0:process.platform==="linux"?u("/usr/local/share/ca-certificates/mitmproxy-ca.crt"):process.platform==="win32"?l("certutil",["-verify",o],{stdio:"pipe"}).status===0:!1}trustCACert(){return process.platform==="darwin"?l("sudo",["security","add-trusted-cert","-d","-r","trustRoot","-k","/Library/Keychains/System.keychain",o],{stdio:"inherit"}).status===0:process.platform==="linux"?l("sudo",["cp",o,"/usr/local/share/ca-certificates/mitmproxy-ca.crt"],{stdio:"inherit"}).status!==0?!1:l("sudo",["update-ca-certificates"],{stdio:"inherit"}).status===0:process.platform==="win32"?l("certutil",["-addstore","-f","Root",o],{stdio:"inherit"}).status===0:!1}};export{K as default};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as p}from"../../chunk-
|
|
1
|
+
import{a as p}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as c}from"../../chunk-ZLLER3HP.js";import{Args as m}from"@oclif/core";import{execFileSync as f}from"node:child_process";import{existsSync as g}from"node:fs";import{join as h,delimiter as l}from"node:path";var v=["session-start","session-end","user-prompt","post-tool-use","assistant-response"],a=class d extends p{static{c(this,"HooksRun")}static description="Execute a hook script (called by AI tool hooks, not for direct use)";static hidden=!0;static args={hook:m.string({description:"Hook name to run",required:!0,options:[...v]})};async run(){let{args:e}=await this.parse(d),t=e.hook,{scriptsDir:o}=await import("@rulemetric/hooks/scripts-dir"),i=h(o,`${t}.sh`);g(i)||this.error(`Hook script not found: ${i}`);try{let s=await this.readStdin();try{let{evaluateHookCaptureGate:r}=await import("../../lib/hooks-capture-gate.js"),{getDefaultConfigDir:u}=await import("../../lib/auth.js");if(!(await r({stdin:s,configDir:u()})).allowed)return}catch{}let n=`${process.env.PATH??""}${l}${o}`;if(f("bash",[i],{input:s,stdio:["pipe","inherit","inherit"],timeout:t==="session-end"?3e4:1e4,env:{...process.env,PATH:n}}),process.env.RULEMETRIC_HOOK_TOOL==="antigravity"&&t==="post-tool-use")try{let{tailAntigravityTranscript:r}=await import("../../lib/antigravity-transcript.js");await r(s)}catch(r){process.stderr.write(`[antigravity-tailer] ${r.message}
|
|
2
2
|
`)}}catch(s){let n=s.status;process.env.RULEMETRIC_HOOK_DEBUG&&process.stderr.write(`[rulemetric hooks run ${t}] non-fatal exit ${n??"?"}: ${s.message??""}
|
|
3
3
|
`)}}readStdin(){return new Promise(e=>{let t=[];process.stdin.on("data",o=>t.push(o)),process.stdin.on("end",()=>e(Buffer.concat(t).toString("utf-8"))),process.stdin.readableEnded&&e(Buffer.concat(t).toString("utf-8"))})}};export{a as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{e as v,n as y}from"../../chunk-QWCEZEDO.js";import"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import{C as j,F as b,J as A,K as w,o as R,s as k,t as x,w as C,x as S,z as P}from"../../chunk-OZQNSELV.js";import"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import{a as p}from"../../chunk-
|
|
1
|
+
import{e as v,n as y}from"../../chunk-QWCEZEDO.js";import"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import{C as j,F as b,J as A,K as w,o as R,s as k,t as x,w as C,x as S,z as P}from"../../chunk-OZQNSELV.js";import"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import{a as p}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{existsSync as c,readFileSync as N,writeFileSync as T}from"node:fs";import{spawnSync as s}from"node:child_process";import{homedir as O}from"node:os";import{join as u}from"node:path";import{Flags as a}from"@oclif/core";var i=u(O(),".mitmproxy","mitmproxy-ca-cert.pem");function E(){return c(i)?process.platform==="darwin"?s("sudo",["security","remove-trusted-cert","-d",i],{stdio:"inherit"}).status===0:process.platform==="linux"?s("sudo",["rm","-f","/usr/local/share/ca-certificates/mitmproxy-ca.crt"],{stdio:"inherit"}).status!==0?!1:s("sudo",["update-ca-certificates","--fresh"],{stdio:"inherit"}).status===0:process.platform==="win32"?s("certutil",["-delstore","Root","mitmproxy"],{stdio:"inherit"}).status===0:!1:!1}l(E,"untrustCACert");var m=class f extends p{static{l(this,"HooksUninstall")}static flags={global:a.boolean({description:"Remove the GLOBAL install (~/.claude) rather than this project",default:!1}),"project-dir":a.string({description:"Project directory to clean (defaults to cwd)"}),"user-hooks":a.boolean({description:"Also strip user-level Cursor/Antigravity hooks (~/.cursor, ~/.gemini)",default:!0,allowNo:!0})};static description="Remove session tracking hooks from a project (or the global install)";static examples=["<%= config.bin %> hooks uninstall","<%= config.bin %> hooks uninstall --global","<%= config.bin %> hooks uninstall --project-dir ~/work/repo-a","<%= config.bin %> hooks uninstall --no-user-hooks"];async run(){let{flags:r}=await this.parse(f),t=r.global?O():r["project-dir"]??process.cwd(),d=u(t,".claude");r.global&&this.log(`Removing the GLOBAL install \u2192 ${d}`);let h=R(d,v);if(h.length===0){this.log("No .claude/settings.json or .claude/settings.local.json found \u2014 nothing to uninstall.");return}let e=!1,g=!1;for(let o of h)o.recoveredBackup&&this.log(`[!!] ${o.configPath} was not valid JSON \u2014 backed up to ${o.recoveredBackup}; continuing.`),o.removedHooks&&this.log(`Removed RuleMetric hooks from .claude/${o.fileName}`),o.removedProxyEnv&&(this.log(`Removed HTTPS_PROXY, NO_PROXY and NODE_EXTRA_CA_CERTS from .claude/${o.fileName}`),g=!0),o.removedStatusline&&this.log(`Removed RuleMetric statusline shim from .claude/${o.fileName}`),e=e||o.changed;e||this.log("No hooks or proxy config found \u2014 nothing to uninstall."),k(t)&&(this.log("Removed RuleMetric hooks from .cursor/hooks.json"),e=!0),r["user-hooks"]&&x()&&(this.log("Removed RuleMetric hooks from ~/.cursor/hooks.json"),e=!0);let n=u(t,".cursor","settings.json");if(c(n))try{let o=JSON.parse(N(n,"utf-8"));o["http.proxy"]?.includes("localhost")&&(delete o["http.proxy"],delete o["http.proxyStrictSSL"],T(n,JSON.stringify(o,null,2)+`
|
|
2
2
|
`),this.log("Removed proxy config from .cursor/settings.json"),e=!0)}catch{}S(t)&&(this.log("Removed RuleMetric hooks from .github/hooks/"),e=!0),A(t)&&(this.log("Removed RuleMetric block from .agents/hooks.json"),e=!0),r["user-hooks"]&&w()&&(this.log("Removed RuleMetric block from ~/.gemini/config/hooks.json"),e=!0),C(t)&&(this.log("Removed proxy config from .vscode/settings.json"),e=!0),j()&&(this.log("Removed proxy config from VS Code user settings"),e=!0),b()&&(this.log("Removed proxy config from Cursor user settings"),e=!0),P()&&(this.log("Removed HTTPS_PROXY LaunchAgent"),e=!0),g&&c(i)&&(this.log("Removing the mitmproxy CA from the system trust store (requires sudo)..."),E()?this.log("[OK] mitmproxy CA untrusted."):(this.log("[!!] Could not untrust the CA automatically. Remove it manually:"),process.platform==="darwin"?this.log(` sudo security remove-trusted-cert -d ${i}`):process.platform==="linux"&&this.log(" sudo rm -f /usr/local/share/ca-certificates/mitmproxy-ca.crt && sudo update-ca-certificates --fresh"))),y()&&this.log("Gateway stopped.")}};export{m as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as p}from"../../chunk-
|
|
1
|
+
import{a as p}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import{f}from"../../chunk-Z7UN4R7T.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as d}from"../../chunk-ZLLER3HP.js";import*as s from"node:fs";import{Args as m,Flags as t}from"@oclif/core";var c=class u extends p{static{d(this,"InstructionsCreate")}static description="Create a new instruction";static examples=['<%= config.bin %> instructions create ./my-instruction.md --name "My Rules" --description "Team coding rules"','<%= config.bin %> instructions create ./rules.md -n "Rules" -d "Project rules" -s project'];static args={file:m.string({description:"Path to markdown file"})};static flags={name:t.string({char:"n",description:"Instruction name",required:!0}),description:t.string({char:"d",description:"Instruction description",required:!0}),scope:t.string({char:"s",description:"Instruction scope",options:["org","team","project","personal"],default:"personal"}),"scope-ref":t.string({description:"Scope reference UUID"}),tags:t.string({char:"t",description:"Comma-separated tags"})};async run(){let{args:i,flags:e}=await this.parse(u);this.requireAuth();let n;if(i.file)s.existsSync(i.file)||this.error(`File not found: ${i.file}`),n=s.readFileSync(i.file,"utf-8");else{this.log("No file provided. Paste content (Ctrl+D to finish):");let r=[];for await(let l of process.stdin)r.push(l);n=Buffer.concat(r).toString("utf-8")}let o={name:e.name,description:e.description,scope:e.scope,content:n};e["scope-ref"]&&(o.scopeRef=e["scope-ref"]),e.tags&&(o.tags=e.tags.split(",").map(r=>r.trim()));let a=await f("/api/instructions",o);this.log(`Created instruction: ${a.name} (${a.id})`)}};export{c as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{e as p}from"../../chunk-LJRE3LZ2.js";import{a as m}from"../../chunk-
|
|
1
|
+
import{e as p}from"../../chunk-LJRE3LZ2.js";import{a as m}from"../../chunk-MOQTSJNZ.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-TDDJOSFQ.js";import"../../chunk-433HK3QQ.js";import"../../chunk-WDLAPZPN.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-Z7UN4R7T.js";import{E as f}from"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import{Flags as $}from"@oclif/core";var l=class n extends m{static{a(this,"InstructionsDedupe")}static description="Report instructions in this project that repeat each other in different words";static examples=["<%= config.bin %> instructions dedupe","<%= config.bin %> instructions dedupe --dir apps/cli"];static flags={dir:$.string({description:"Directory whose CLAUDE.md to check (ancestors are included)",default:"."}),threshold:$.string({description:"Similarity floor 0-1 for calling two asks the same (default 0.3)"})};async run(){let{flags:i}=await this.parse(n),o=i.threshold===void 0?void 0:Number(i.threshold);o!==void 0&&(!Number.isFinite(o)||o<=0||o>1)&&this.error("--threshold must be a number greater than 0 and at most 1");let s=p(i.dir);if(s.length===0){this.log(`No CLAUDE.md found at or above ${i.dir}.`);return}let h=[...new Set(s.map(t=>t.source).filter(Boolean))];this.log(`Checked ${s.length} instruction(s) across ${h.length} file(s):`);for(let t of h)this.log(` ${t}`);this.log("");let d=f(s,o);if(d.length===0){this.log("No repeated instructions found.");return}let u=[...d].sort((t,e)=>Number(e.verdict.redundant)-Number(t.verdict.redundant));for(let{instruction:t,verdict:e}of u){let v=e.redundant?"FULLY COVERED \u2014 says nothing the earlier rules do not":`PARTLY COVERED \u2014 ${e.matches.length} of ${e.matches.length+e.novel.length} asks are repeats`;this.log(`${t.source??""} \xB7 ${t.id}`),this.log(` ${v}`);for(let r of e.matches)this.log(` "${c(r.directive)}"`),this.log(` \u21B3 ${(r.similarity*100).toFixed(0)}% match with ${r.matchedSource??r.matchedId}: "${c(r.matchedDirective)}"`);for(let r of e.novel)this.log(` KEEPS: "${c(r)}"`);e.redundant&&!t.id.includes("#handwritten")&&this.log(` Remove it: rulemetric suggestions undo ${t.id}`),this.log("")}let g=u.filter(t=>t.verdict.redundant).length;this.log(`${d.length} instruction(s) repeat earlier ones; ${g} ${g===1?"adds":"add"} nothing new. Nothing was changed \u2014 review each before removing it.`)}};function c(n,i=96){return n.length<=i?n:`${n.slice(0,i-1)}\u2026`}a(c,"clip");export{l as default};
|