@rulemetric/cli 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/dist/base-command.js +1 -1
  2. package/dist/{chunk-UE76F2NQ.js → chunk-2WQUOC6S.js} +20 -20
  3. package/dist/{chunk-DUBBL57L.js → chunk-5XEGRU2R.js} +1 -1
  4. package/dist/chunk-74QIUVWY.js +1 -0
  5. package/dist/chunk-7ML2UCI7.js +1 -0
  6. package/dist/chunk-AHLVY52I.js +1 -0
  7. package/dist/{chunk-O2HCD6XL.js → chunk-AT2MMCOJ.js} +1 -1
  8. package/dist/{chunk-GJBS6QYC.js → chunk-AXJAGWZB.js} +1 -1
  9. package/dist/{chunk-UYPBIXF2.js → chunk-BVOXWAJO.js} +1 -1
  10. package/dist/chunk-CT7FWSIU.js +3 -0
  11. package/dist/{chunk-KV5A77XW.js → chunk-DDYGA2DS.js} +1 -1
  12. package/dist/{chunk-5XK6LB2T.js → chunk-E5YE25QG.js} +1 -1
  13. package/dist/chunk-E7GQJML3.js +1 -0
  14. package/dist/{chunk-RK663O4M.js → chunk-E7RH43OS.js} +6 -6
  15. package/dist/{chunk-2EX27VJ3.js → chunk-ET7753IY.js} +1 -1
  16. package/dist/{chunk-25Q3Y7TC.js → chunk-EWGE7YTQ.js} +1 -1
  17. package/dist/{chunk-WOJ733IB.js → chunk-EXVXKJ7Y.js} +1 -1
  18. package/dist/chunk-FCTFHY3X.js +13 -0
  19. package/dist/{chunk-RJX75Y7J.js → chunk-FJX7WDPG.js} +1 -1
  20. package/dist/{chunk-3UPHCQWI.js → chunk-FK55FXKQ.js} +1 -1
  21. package/dist/chunk-GH4EZK2O.js +1 -0
  22. package/dist/chunk-GN46S7T4.js +9 -0
  23. package/dist/{chunk-BG55WDDX.js → chunk-GQGGFHX7.js} +1 -1
  24. package/dist/chunk-GYNZ3OZF.js +1 -0
  25. package/dist/{chunk-WJZY5Y22.js → chunk-H4LUPIHJ.js} +1 -1
  26. package/dist/{chunk-25RDT32M.js → chunk-HAYO6JYI.js} +1 -1
  27. package/dist/{chunk-YI2OWO6R.js → chunk-HFSISGCJ.js} +1 -1
  28. package/dist/chunk-HRJDKAJ4.js +1 -0
  29. package/dist/chunk-IC6VZHE6.js +1 -0
  30. package/dist/chunk-INAZLRY5.js +1 -0
  31. package/dist/{chunk-VXUKXGRX.js → chunk-IOX4VJPR.js} +2 -2
  32. package/dist/chunk-J4W6GNCF.js +2 -0
  33. package/dist/{chunk-VH2EAP4J.js → chunk-J7UZXRTH.js} +1 -1
  34. package/dist/{chunk-6GAIYJ6K.js → chunk-JKWB6UXA.js} +1 -1
  35. package/dist/{chunk-JWFRI32Y.js → chunk-JLBQKV4V.js} +1 -1
  36. package/dist/{chunk-VIQ25ORK.js → chunk-JRAXWASH.js} +1 -1
  37. package/dist/{chunk-PVGUDJD7.js → chunk-JRWQJZYQ.js} +1 -1
  38. package/dist/{chunk-6ZPSVZNH.js → chunk-LDUJWJ6A.js} +1 -1
  39. package/dist/chunk-LMCICVE7.js +12 -0
  40. package/dist/chunk-MHVHGKDK.js +3 -0
  41. package/dist/chunk-MMM4B3KH.js +1 -0
  42. package/dist/{chunk-CYYDQFRY.js → chunk-MX34N7Y5.js} +1 -1
  43. package/dist/{chunk-7AWFSFR7.js → chunk-N26UEHI3.js} +1 -1
  44. package/dist/{chunk-ZGW3N3A6.js → chunk-N4RJ6CN7.js} +1 -1
  45. package/dist/{chunk-J6QMBMC2.js → chunk-N7SZWKCU.js} +1 -1
  46. package/dist/{chunk-QFKUSNUB.js → chunk-NRYVMGJN.js} +1 -1
  47. package/dist/{chunk-4COLIGD7.js → chunk-NSPDDSRR.js} +1 -1
  48. package/dist/{chunk-GBWQENAH.js → chunk-O62OLKQL.js} +1 -1
  49. package/dist/{chunk-WY3VVX3R.js → chunk-OLJF4K7L.js} +1 -1
  50. package/dist/{chunk-6W2GSV4O.js → chunk-OMRH4JXS.js} +1 -1
  51. package/dist/{chunk-WH3IPXXQ.js → chunk-OO2ZRKZY.js} +5 -5
  52. package/dist/chunk-OUK2AWEI.js +1 -0
  53. package/dist/chunk-OYAOLJUH.js +1 -0
  54. package/dist/chunk-PPAHIVG5.js +1 -0
  55. package/dist/{chunk-3MDEGOUG.js → chunk-PPIZMPNI.js} +1 -1
  56. package/dist/chunk-PUX6P5KC.js +2 -0
  57. package/dist/chunk-QI3FJKGK.js +1 -0
  58. package/dist/chunk-RRM4HQG4.js +1 -0
  59. package/dist/{chunk-QTCWOIT4.js → chunk-S5CQSP35.js} +1 -1
  60. package/dist/chunk-S5U76YUI.js +1 -0
  61. package/dist/chunk-SE3UKA3M.js +25 -0
  62. package/dist/{chunk-BZS5QRWB.js → chunk-SG4UDDHB.js} +1 -1
  63. package/dist/chunk-SPJ73X7A.js +4 -0
  64. package/dist/chunk-SV73ASP2.js +1 -0
  65. package/dist/chunk-SWSOEYC7.js +1 -0
  66. package/dist/{chunk-I3M5VBLT.js → chunk-TTSDPDRH.js} +1 -1
  67. package/dist/chunk-TWPG3TEQ.js +48 -0
  68. package/dist/{chunk-WQX4RRBQ.js → chunk-U7BPWFOP.js} +1 -1
  69. package/dist/{chunk-NBEZ5FAU.js → chunk-UFQ43KXE.js} +1 -1
  70. package/dist/chunk-UJ7EPLKC.js +1 -0
  71. package/dist/{chunk-V2USQH27.js → chunk-UQDOOQCM.js} +1 -1
  72. package/dist/{chunk-M2VVRQKA.js → chunk-V4PUYPTU.js} +1 -1
  73. package/dist/{chunk-SHYP27B7.js → chunk-VALRPZXH.js} +1 -1
  74. package/dist/{chunk-LTQ5BJYL.js → chunk-VLWNSTYW.js} +1 -1
  75. package/dist/chunk-WSWZPNLG.js +1 -0
  76. package/dist/{chunk-MNQPCNGQ.js → chunk-XAOLOR4Q.js} +1 -1
  77. package/dist/{chunk-6QLZT7EP.js → chunk-XAXEZI6Z.js} +1 -1
  78. package/dist/{chunk-Y7QIOPN5.js → chunk-XFLKW6SJ.js} +1 -1
  79. package/dist/chunk-YNLHJHUP.js +1 -0
  80. package/dist/{chunk-U7TBEC3I.js → chunk-YP2CBUXH.js} +1 -1
  81. package/dist/{chunk-P2WSDHIA.js → chunk-YUIRDBQQ.js} +1 -1
  82. package/dist/{chunk-4N43IBXH.js → chunk-ZA6NXNPR.js} +1 -1
  83. package/dist/{chunk-APDRR6FS.js → chunk-ZZHIBOMT.js} +1 -1
  84. package/dist/commands/antigravity/backfill.js +1 -1
  85. package/dist/commands/auth/create-key.js +1 -1
  86. package/dist/commands/auth/login.js +1 -1
  87. package/dist/commands/auth/logout.js +1 -1
  88. package/dist/commands/auth/revoke-key.js +1 -1
  89. package/dist/commands/auth/signup.js +1 -1
  90. package/dist/commands/auth/status.js +1 -1
  91. package/dist/commands/capture/scope.js +1 -1
  92. package/dist/commands/catalog/index.js +1 -1
  93. package/dist/commands/catalog/recommend.js +1 -1
  94. package/dist/commands/crons/list.js +1 -1
  95. package/dist/commands/crons/run.js +2 -2
  96. package/dist/commands/dashboard.js +1 -1
  97. package/dist/commands/diagnostics.js +1 -1
  98. package/dist/commands/eval-targets/create.js +1 -1
  99. package/dist/commands/eval-targets/list.js +1 -1
  100. package/dist/commands/evals/agent.js +3 -3
  101. package/dist/commands/evals/auto-run.js +1 -1
  102. package/dist/commands/evals/benchmark.js +1 -1
  103. package/dist/commands/evals/compare.js +1 -1
  104. package/dist/commands/evals/create.js +1 -1
  105. package/dist/commands/evals/optimize-description.js +1 -1
  106. package/dist/commands/evals/optimize.js +1 -1
  107. package/dist/commands/evals/refine-cases.js +1 -1
  108. package/dist/commands/evals/run.js +1 -1
  109. package/dist/commands/evals/validate-judge.js +1 -1
  110. package/dist/commands/experiments/list.js +1 -1
  111. package/dist/commands/gateway/ensure.js +1 -1
  112. package/dist/commands/hooks/emit-instructions.js +1 -1
  113. package/dist/commands/hooks/install.js +1 -1
  114. package/dist/commands/hooks/run.js +1 -1
  115. package/dist/commands/hooks/uninstall.js +1 -1
  116. package/dist/commands/instructions/create.js +1 -1
  117. package/dist/commands/instructions/dedupe.js +1 -1
  118. package/dist/commands/instructions/delete.js +1 -1
  119. package/dist/commands/instructions/fork.js +1 -1
  120. package/dist/commands/instructions/get.js +1 -1
  121. package/dist/commands/instructions/list.js +1 -1
  122. package/dist/commands/instructions/promote.js +1 -1
  123. package/dist/commands/instructions/pull.js +1 -1
  124. package/dist/commands/instructions/restore.js +1 -1
  125. package/dist/commands/instructions/retract.js +1 -1
  126. package/dist/commands/instructions/upstream.js +1 -1
  127. package/dist/commands/instructions/versions.js +1 -1
  128. package/dist/commands/launcher.js +1 -1
  129. package/dist/commands/local/down.js +1 -1
  130. package/dist/commands/local/up.js +1 -1
  131. package/dist/commands/org/current.js +1 -1
  132. package/dist/commands/org/list.js +1 -1
  133. package/dist/commands/org/switch.js +1 -1
  134. package/dist/commands/packs/add-instruction.js +1 -1
  135. package/dist/commands/packs/apply.js +1 -1
  136. package/dist/commands/packs/create.js +1 -1
  137. package/dist/commands/packs/fork.js +1 -1
  138. package/dist/commands/packs/get.js +1 -1
  139. package/dist/commands/packs/list.js +1 -1
  140. package/dist/commands/packs/remove-instruction.js +1 -1
  141. package/dist/commands/proxy/env.js +1 -1
  142. package/dist/commands/proxy/logs.js +1 -1
  143. package/dist/commands/proxy/restart.js +1 -1
  144. package/dist/commands/proxy/setup.js +1 -1
  145. package/dist/commands/proxy/start.js +1 -1
  146. package/dist/commands/proxy/status.js +1 -1
  147. package/dist/commands/proxy/stop.js +1 -1
  148. package/dist/commands/research/backfill.js +1 -1
  149. package/dist/commands/research/tail-transcript.js +1 -1
  150. package/dist/commands/service/install.js +18 -18
  151. package/dist/commands/service/status.js +1 -1
  152. package/dist/commands/service/uninstall.js +1 -1
  153. package/dist/commands/sessions/analyze.js +1 -1
  154. package/dist/commands/sessions/delete.js +1 -1
  155. package/dist/commands/sessions/end.js +1 -1
  156. package/dist/commands/sessions/import.js +1 -1
  157. package/dist/commands/sessions/list.js +1 -1
  158. package/dist/commands/sessions/start.js +1 -1
  159. package/dist/commands/setup.js +1 -1
  160. package/dist/commands/skills/export-approved.js +1 -1
  161. package/dist/commands/skills/install.js +1 -1
  162. package/dist/commands/skills/list.js +1 -1
  163. package/dist/commands/skills/publish.js +1 -1
  164. package/dist/commands/skills/search.js +1 -1
  165. package/dist/commands/skills/update.js +1 -1
  166. package/dist/commands/suggestions/accept.js +1 -1
  167. package/dist/commands/suggestions/auto.js +1 -1
  168. package/dist/commands/suggestions/dismiss.js +1 -1
  169. package/dist/commands/suggestions/list.js +1 -1
  170. package/dist/commands/suggestions/refresh.js +1 -1
  171. package/dist/commands/suggestions/undo.js +1 -1
  172. package/dist/dashboard/Dashboard.js +1 -1
  173. package/dist/dashboard/data.js +1 -1
  174. package/dist/dashboard/launcher/LauncherOverlay.js +1 -1
  175. package/dist/dashboard/launcher/api.js +1 -1
  176. package/dist/dashboard/launcher/useLaunchJobs.js +1 -1
  177. package/dist/dist-NHS7HY5Q.js +1 -0
  178. package/dist/harbor/cost_delta.py +377 -0
  179. package/dist/harbor/mcp_container_shell.py +156 -0
  180. package/dist/harbor/provenance.py +361 -0
  181. package/dist/harbor/rm-batch-task/environment/Dockerfile +6 -0
  182. package/dist/harbor/rm-batch-task/environment/items.jsonl +60 -0
  183. package/dist/harbor/rm-batch-task/inject.md +8 -0
  184. package/dist/harbor/rm-batch-task/instruction.md +8 -0
  185. package/dist/harbor/rm-batch-task/solution/solve.sh +68 -0
  186. package/dist/harbor/rm-batch-task/task.toml +30 -0
  187. package/dist/harbor/rm-batch-task/tests/test.sh +23 -0
  188. package/dist/harbor/rm-batch-task/tests/test_outputs.py +32 -0
  189. package/dist/harbor/rm-locality-task/environment/Dockerfile +8 -0
  190. package/dist/harbor/rm-locality-task/environment/workspace/deploy/prod/ingest.yaml +3 -0
  191. package/dist/harbor/rm-locality-task/environment/workspace/deploy/staging/ingest.yaml +3 -0
  192. package/dist/harbor/rm-locality-task/environment/workspace/docs/architecture/ingest.md +6 -0
  193. package/dist/harbor/rm-locality-task/environment/workspace/legacy/ingest_v1/config.yaml +2 -0
  194. package/dist/harbor/rm-locality-task/environment/workspace/packages/shared/defaults.py +4 -0
  195. package/dist/harbor/rm-locality-task/environment/workspace/services/ingest/config/limits.defaults.yaml +4 -0
  196. package/dist/harbor/rm-locality-task/environment/workspace/services/ingest/config/limits.yaml +3 -0
  197. package/dist/harbor/rm-locality-task/environment/workspace/services/ingest/loader.py +15 -0
  198. package/dist/harbor/rm-locality-task/environment/workspace/tests/fixtures/ingest_config.yaml +3 -0
  199. package/dist/harbor/rm-locality-task/inject.md +12 -0
  200. package/dist/harbor/rm-locality-task/instruction.md +4 -0
  201. package/dist/harbor/rm-locality-task/solution/solve.sh +14 -0
  202. package/dist/harbor/rm-locality-task/task.toml +30 -0
  203. package/dist/harbor/rm-locality-task/tests/test.sh +23 -0
  204. package/dist/harbor/rm-locality-task/tests/test_outputs.py +19 -0
  205. package/dist/harbor/rm-migrations-task/environment/Dockerfile +7 -0
  206. package/dist/harbor/rm-migrations-task/environment/applied.txt +2 -0
  207. package/dist/harbor/rm-migrations-task/environment/migrations/00001_init.sql +1 -0
  208. package/dist/harbor/rm-migrations-task/environment/migrations/00002_add_email.sql +1 -0
  209. package/dist/harbor/rm-migrations-task/inject.md +7 -0
  210. package/dist/harbor/rm-migrations-task/instruction.md +8 -0
  211. package/dist/harbor/rm-migrations-task/solution/solve.sh +8 -0
  212. package/dist/harbor/rm-migrations-task/task.toml +30 -0
  213. package/dist/harbor/rm-migrations-task/tests/test.sh +23 -0
  214. package/dist/harbor/rm-migrations-task/tests/test_outputs.py +36 -0
  215. package/dist/harbor/rm-pagination-task/environment/Dockerfile +6 -0
  216. package/dist/harbor/rm-pagination-task/environment/store.py +29 -0
  217. package/dist/harbor/rm-pagination-task/inject.md +8 -0
  218. package/dist/harbor/rm-pagination-task/instruction.md +5 -0
  219. package/dist/harbor/rm-pagination-task/solution/solve.sh +7 -0
  220. package/dist/harbor/rm-pagination-task/task.toml +30 -0
  221. package/dist/harbor/rm-pagination-task/tests/test.sh +23 -0
  222. package/dist/harbor/rm-pagination-task/tests/test_outputs.py +14 -0
  223. package/dist/harbor/rm_host_claude.py +264 -0
  224. package/dist/harbor/rm_host_codex.py +208 -0
  225. package/dist/harbor/run.sh +268 -0
  226. package/dist/harbor/summarize.py +248 -0
  227. package/dist/lib/active-org-refresh.js +1 -1
  228. package/dist/lib/agent-loop.js +1 -1
  229. package/dist/lib/antigravity-transcript.js +1 -1
  230. package/dist/lib/api-client.js +1 -1
  231. package/dist/lib/capture-scope-config.js +1 -1
  232. package/dist/lib/codex-capture-scope.js +1 -1
  233. package/dist/lib/codex-exec.js +1 -1
  234. package/dist/lib/ensure-api-key.js +1 -1
  235. package/dist/lib/ensure-fresh-token.js +1 -1
  236. package/dist/lib/eval-accumulation.js +1 -0
  237. package/dist/lib/eval-analyzer.js +1 -1
  238. package/dist/lib/eval-benchmark.js +1 -1
  239. package/dist/lib/eval-candidate-run.js +1 -1
  240. package/dist/lib/eval-case-generator.js +1 -1
  241. package/dist/lib/eval-conversation-handler.js +1 -1
  242. package/dist/lib/eval-executor.js +1 -1
  243. package/dist/lib/eval-grader.js +1 -1
  244. package/dist/lib/eval-meta-judge.js +1 -1
  245. package/dist/lib/eval-resume.js +1 -1
  246. package/dist/lib/eval-run-batch.js +1 -1
  247. package/dist/lib/eval-trigger-tester.js +1 -1
  248. package/dist/lib/evolution-enrolment.js +1 -1
  249. package/dist/lib/harbor-readiness.js +1 -1
  250. package/dist/lib/hooks-capture-gate.js +1 -1
  251. package/dist/lib/insights/generation/installed-asks.js +1 -1
  252. package/dist/lib/insights/nomination/nominate.js +1 -1
  253. package/dist/lib/instruction-proposer.js +1 -1
  254. package/dist/lib/instruction-snapshot.js +1 -1
  255. package/dist/lib/instructions/acceptance/accept-events.js +1 -1
  256. package/dist/lib/instructions/acceptance/accept-hook.js +1 -1
  257. package/dist/lib/instructions/acceptance/agent-instruction-files.js +1 -1
  258. package/dist/lib/instructions/acceptance/hook-install.js +1 -1
  259. package/dist/lib/instructions/acceptance/reverse-applications.js +1 -1
  260. package/dist/lib/instructions/acceptance/suggestion-accept.js +1 -1
  261. package/dist/lib/jobs/handlers/cron-auto-accept-suggestions.js +1 -1
  262. package/dist/lib/jobs/handlers/cron-eval-autorun.js +1 -1
  263. package/dist/lib/jobs/handlers/cron-instruction-evolution.js +1 -1
  264. package/dist/lib/jobs/handlers/cron-instruction-training.js +1 -1
  265. package/dist/lib/jobs/handlers/cron-reconcile-attribution.js +1 -1
  266. package/dist/lib/jobs/handlers/cron-refine-cases.js +1 -1
  267. package/dist/lib/jobs/handlers/cron-refresh-pricing.js +1 -1
  268. package/dist/lib/jobs/handlers/cron-retire-unused-skills.js +1 -1
  269. package/dist/lib/jobs/handlers/cron-suggest-instructions.js +1 -1
  270. package/dist/lib/jobs/handlers/distill-memories.js +1 -1
  271. package/dist/lib/jobs/handlers/harbor-ab-verdict.js +1 -1
  272. package/dist/lib/jobs/handlers/harbor-ab.js +1 -1
  273. package/dist/lib/jobs/handlers/process-changelog.js +1 -1
  274. package/dist/lib/jobs/handlers/process-conversation.js +1 -1
  275. package/dist/lib/jobs/handlers/process-eval.js +1 -1
  276. package/dist/lib/jobs/handlers/process-insights.js +1 -1
  277. package/dist/lib/jobs/handlers/process-judge-review.js +1 -1
  278. package/dist/lib/jobs/handlers/process-launch.js +1 -1
  279. package/dist/lib/jobs/handlers/process-memory-ab.js +1 -1
  280. package/dist/lib/jobs/handlers/process-run-cleanup.js +1 -1
  281. package/dist/lib/jobs/handlers/process-session-goal.js +1 -1
  282. package/dist/lib/jobs/shed-retry.js +1 -1
  283. package/dist/lib/judge-review-runner.js +1 -1
  284. package/dist/lib/llm-client.js +1 -1
  285. package/dist/lib/llm-reply-parsers.js +1 -0
  286. package/dist/lib/manual-tasks.js +1 -1
  287. package/dist/lib/measurement-llm.js +1 -0
  288. package/dist/lib/pi-exec.js +1 -0
  289. package/dist/lib/projects/workspace/eval-workspace.js +1 -1
  290. package/dist/lib/projects/workspace/worktree.js +1 -1
  291. package/dist/lib/refine-cases.js +1 -1
  292. package/dist/lib/research-client.js +1 -1
  293. package/dist/lib/retraction.js +1 -1
  294. package/dist/lib/service-environment.js +1 -0
  295. package/dist/lib/setup-steps.js +1 -1
  296. package/dist/lib/telemetry.js +1 -1
  297. package/dist/lib/terminal-target-heartbeat.js +1 -1
  298. package/dist/lib/tool-cli-map.js +1 -0
  299. package/dist/lib/transcript-instruction-linking.js +1 -1
  300. package/dist/lib/transcript-sync.js +1 -1
  301. package/dist/lib/work-report.js +1 -1
  302. package/oclif.manifest.json +7 -1
  303. package/package.json +5 -4
  304. package/dist/chunk-4FSQSETR.js +0 -12
  305. package/dist/chunk-6WQG6C7F.js +0 -1
  306. package/dist/chunk-C42NTI2V.js +0 -3
  307. package/dist/chunk-F6DAHCJC.js +0 -20
  308. package/dist/chunk-GN3ZHQ46.js +0 -1
  309. package/dist/chunk-H3BCWSYO.js +0 -1
  310. package/dist/chunk-HLNHBZLI.js +0 -1
  311. package/dist/chunk-HLQZR4XJ.js +0 -13
  312. package/dist/chunk-J5HW45PZ.js +0 -48
  313. package/dist/chunk-JNFB22FD.js +0 -1
  314. package/dist/chunk-KCOJLTVX.js +0 -1
  315. package/dist/chunk-MLV2RHRE.js +0 -1
  316. package/dist/chunk-N7GK33PU.js +0 -1
  317. package/dist/chunk-NRYLYMDM.js +0 -1
  318. package/dist/chunk-OZNKMJ5B.js +0 -1
  319. package/dist/chunk-PPXOC7IV.js +0 -1
  320. package/dist/chunk-QXPYGN7I.js +0 -1
  321. package/dist/chunk-R4QIPG4V.js +0 -2
  322. package/dist/chunk-RGUCR7T6.js +0 -1
  323. package/dist/chunk-RO3ZZVCG.js +0 -1
  324. package/dist/chunk-SN3CHV66.js +0 -1
  325. package/dist/chunk-U3XKXJ3A.js +0 -5
  326. package/dist/chunk-UM4CBCXI.js +0 -1
  327. package/dist/chunk-WHQ4BDSM.js +0 -4
  328. package/dist/dist-45KJH5M7.js +0 -1
@@ -1 +1 @@
1
- import{c as X}from"./chunk-HOQPVOMF.js";import{b as D}from"./chunk-GIRPEMTW.js";import{a as x}from"./chunk-MODXEGCU.js";import{d as J,f as B}from"./chunk-U3XKXJ3A.js";import{e as w,f as R}from"./chunk-APDRR6FS.js";import{c as H,d as U}from"./chunk-J5HW45PZ.js";import{a as u}from"./chunk-ZLLER3HP.js";import{readFileSync as q,realpathSync as V}from"node:fs";import y from"node:path";import A from"node:os";function Q(s){let n=y.resolve(s);if(n===y.resolve(A.homedir()))return!1;let a=y.parse(n).root;if(n===a)return!1;try{let o=V(A.tmpdir());if(V(n)===o)return!1}catch{}return!0}u(Q,"isScorableProjectPath");var Z=5,ee=Number(process.env.RULEMETRIC_MAX_SUGGESTION_PROJECTS??10),te=48,ne=.5,O=400,oe=3,re=.6,se=1;function ae(s){let n=s.bloated??[],a=new Set([...s.harmful.map(o=>o.id),...s.candidates.map(o=>o.id)]);return n.filter(o=>!a.has(o.id)).slice(0,se).map(o=>({instructionId:o.id,estimatedTokens:o.estimatedTokens,topProjectId:o.topProjectId??null,score:.55,reason:`Costs ~${o.estimatedTokens} tokens every session and measures neutral across ${o.exposures} exposed session(s) \u2014 enough data to detect an effect, and none found. Consider shortening "${o.name}" rather than removing it.`+(o.containsSafetyLanguage?" CAUTION: it contains guardrail language (destructive-command or credential rules) \u2014 preserve those lines when shortening.":"")}))}u(ae,"buildTrimProposals");async function ie(s,n,a){let o=[],i=0;for(let d of s)try{await a("/api/instruction-experiments",{instructionId:d.instructionId,projectPath:n,source:"groom"}),i++}catch(g){let m=g instanceof Error?g.message:String(g);o.push({...d,reason:`${d.reason} (not measurable by withholding: ${m})`})}return{nominated:i,unmeasurable:o}}u(ie,"nominateRemovals");function ce(s){let n=[];for(let o of s.harmful){let i=o.verdict.delta;n.push({instructionId:o.id,score:Math.min(.95,.75+Math.abs(i)),topProjectId:o.topProjectId??null,reason:`Measured harmful: sessions using "${o.name}" scored ${(i*100).toFixed(1)}pp worse across ${o.exposures} exposed session(s). Observational \u2014 review before archiving.`})}let a=new Set(s.harmful.map(o=>o.id));for(let o of s.candidates)a.has(o.id)||n.push({instructionId:o.id,score:re,topProjectId:o.topProjectId??null,reason:`Unused: "${o.name}" is ${o.reason} (${o.totalExposures} lifetime exposure(s)) but still costs context budget every session.`});return n.slice(0,oe)}u(ce,"buildRemovalProposals");function le(){let s=y.join(A.homedir(),".config","rulemetric","skills-registry.json");try{let n=q(s,"utf-8"),a=JSON.parse(n),o=new Date(a.generatedAt).getTime();return Number.isNaN(o)?"unknown":Date.now()-o>te*60*60*1e3?"stale":"fresh"}catch{return"unknown"}}u(le,"observeSkillsRegistry");var Re=u(async(s,n)=>{let a=J(),o=a!=="none";o?n.logger.info(`Scoring backend: ${a}`):n.logger.warn("No LLM backend available (claude CLI missing and ANTHROPIC_API_KEY unset); skipping relevance scoring. Removal/trim proposals still run \u2014 they need no LLM.");let i;try{i=(await w("/api/sessions/project-paths?limit="+ee)).projectPaths}catch(e){n.logger.warn(`Failed to fetch project paths: ${e instanceof Error?e.message:String(e)}`);return}if(i.length===0){n.logger.info("No recent project paths; nothing to score");return}let d=new Map;try{let e=await w("/api/projects?limit=200");for(let t of e.projects??[])t.primaryCheckoutPath&&d.set(x(t.primaryCheckoutPath),t.id)}catch(e){n.logger.warn(`Failed to fetch projects for id resolution: ${e instanceof Error?e.message:String(e)}`)}let g=new Map;try{let e=await w(`/api/catalog?limit=200&proposable=1&contentPreview=${O}`);for(let t of e)g.set(t.id,{id:t.id,name:t.name,description:t.description??"",tags:t.tags??[],contentPreview:(t.contentPreview??"").slice(0,O)})}catch(e){n.logger.warn(`Failed to fetch catalog: ${e instanceof Error?e.message:String(e)}`)}try{let e=await w("/api/instructions?limit=100");for(let t of e.instructions??[])g.has(t.id)||g.set(t.id,{id:t.id,name:t.name,description:t.description??"",tags:t.tags??[],contentPreview:(t.content??"").slice(0,O)})}catch(e){n.logger.warn(`Failed to fetch personal instructions: ${e instanceof Error?e.message:String(e)}`)}let m=[],p=[];try{let e=await w("/api/insights/groom-candidates");if(!e.captureHealthy)n.logger.info(`Grooming paused: ${e.reason??"capture unhealthy"}`);else{m=ce(e),p=ae(e);let t=e.safetyGuarded+e.harmfulSafetyGuarded;n.logger.info(`Removal proposals: ${m.length} (${e.harmful.length} measured-harmful, ${e.candidates.length} never-used, ${t} withheld by the safety allowlist); trim proposals: ${p.length} (${(e.bloated??[]).length} measured-neutral and expensive, ${e.trimSafetyFlagged??0} flagged as containing guardrail language)`)}}catch(e){n.logger.warn(`Failed to fetch groom candidates: ${e instanceof Error?e.message:String(e)}`)}let b=[...g.values()];if(b.length===0&&m.length===0&&p.length===0){n.logger.info("No candidate instructions and nothing to retire; nothing to score");return}n.logger.info(`Scoring ${b.length} candidates across ${i.length} project(s)`);let M=0,l=null,I=new Set;for(let e of i)try{let t=x(e);if(!Q(t)){n.logger.info(`Skipping ${t}: not a project directory (home/root)`);continue}let f=D(t),k=o&&f.length>0;f.length===0&&n.logger.info(`${t}: insufficient language signals; removal/trim only`);let v=X(t),z={name:y.basename(t),description:v.description,languages:f,topics:v.topics,dependencies:v.dependencies},E=k?U(b):[];k&&n.logger.info(`Scoring ${b.length} candidates for ${t} in ${E.length} batch(es)`);let C=[],$=0;for(let r of E)try{let c=await B(H(z,r),"",4096);if(!c){$++;continue}let T=c.recommendations??[];for(let P of T)typeof P.instructionId=="string"&&typeof P.score=="number"&&typeof P.reason=="string"&&C.push({instructionId:P.instructionId,score:P.score,reason:P.reason})}catch(c){$++,n.logger.warn(`Batch failed for ${t}: ${c instanceof Error?c.message:String(c)}`)}$>0&&n.logger.warn(`${$}/${E.length} batch(es) failed for ${t} (backend ${a}); suggestions are partial`),k&&C.length===0&&n.logger.warn(`No usable LLM output for ${t} (backend ${a})`);let K=C.filter(r=>r.score>=ne).sort((r,c)=>c.score-r.score).slice(0,Z),_=d.get(t),W=l===null||l===t;l===null&&(l=t);let N=u(r=>r.topProjectId?r.topProjectId===_:W,"placeHere"),F=m.filter(N),{nominated:L,unmeasurable:G}=await ie(F,t,R);L>0&&n.logger.info(`${t}: ${L} removal candidate(s) nominated for randomised withholding instead of the feed`);let h=[...K.map(r=>({instructionId:r.instructionId,score:r.score,reason:r.reason,kind:"add"})),...G.map(({topProjectId:r,...c})=>({...c,kind:"remove"})),...p.filter(N).map(({estimatedTokens:r,topProjectId:c,...T})=>({...T,kind:"trim"}))];if(h.length===0){n.logger.info(`Nothing to suggest for ${t}`);continue}await R("/api/instruction-suggestions/batch-upsert",{projectPath:t,..._?{projectId:_}:{},suggestions:h}),n.logger.info(`${t}: ${h.filter(r=>r.kind==="add").length} add + ${h.filter(r=>r.kind==="remove").length} remove + ${h.filter(r=>r.kind==="trim").length} trim`);for(let r of h)r.kind!=="add"&&I.add(r.instructionId);let Y=new Set(G.map(r=>r.instructionId));for(let r of F)Y.has(r.instructionId)||I.add(r.instructionId);M++}catch(t){n.logger.warn(`Failed to score ${e}: ${t instanceof Error?t.message:String(t)}`)}let j=[...m.filter(e=>!I.has(e.instructionId)),...p.filter(e=>!I.has(e.instructionId)).map(({estimatedTokens:e,...t})=>t)];if(j.length>0&&l)try{let e=new Set(p.map(t=>t.instructionId));await R("/api/instruction-suggestions/batch-upsert",{projectPath:l,...d.get(l)?{projectId:d.get(l)}:{},suggestions:j.map(({topProjectId:t,...f})=>({...f,kind:e.has(f.instructionId)?"trim":"remove"}))}),n.logger.info(`Orphan sweep: ${j.length} proposal(s) whose project was not scored this run placed on ${l}`)}catch(e){n.logger.warn(`Orphan sweep failed: ${e instanceof Error?e.message:String(e)}`)}let S=le();if(S==="unknown")n.logger.warn("Skills registry unreadable or has no usable generatedAt; leaving suggestion staleness unchanged");else try{await R("/api/instruction-suggestions/mark-stale",{stale:S==="stale"}),S==="stale"?n.logger.warn("Skills registry is stale (>48h); marked catalog-skill suggestions stale"):n.logger.info("Skills registry is fresh; cleared staleness on catalog-skill suggestions")}catch{}n.logger.info(`Done: scored ${M}/${i.length} projects`)},"cronSuggestInstructions");export{Q as a,ae as b,ie as c,ce as d,Re as e};
1
+ import{c as X}from"./chunk-HOQPVOMF.js";import{b as D}from"./chunk-GIRPEMTW.js";import{a as x}from"./chunk-MODXEGCU.js";import{e as J,g as B}from"./chunk-GN46S7T4.js";import{e as w,f as R}from"./chunk-ZZHIBOMT.js";import{c as H,d as U}from"./chunk-TWPG3TEQ.js";import{a as u}from"./chunk-ZLLER3HP.js";import{readFileSync as q,realpathSync as V}from"node:fs";import y from"node:path";import A from"node:os";function Q(s){let n=y.resolve(s);if(n===y.resolve(A.homedir()))return!1;let a=y.parse(n).root;if(n===a)return!1;try{let o=V(A.tmpdir());if(V(n)===o)return!1}catch{}return!0}u(Q,"isScorableProjectPath");var Z=5,ee=Number(process.env.RULEMETRIC_MAX_SUGGESTION_PROJECTS??10),te=48,ne=.5,O=400,oe=3,re=.6,se=1;function ae(s){let n=s.bloated??[],a=new Set([...s.harmful.map(o=>o.id),...s.candidates.map(o=>o.id)]);return n.filter(o=>!a.has(o.id)).slice(0,se).map(o=>({instructionId:o.id,estimatedTokens:o.estimatedTokens,topProjectId:o.topProjectId??null,score:.55,reason:`Costs ~${o.estimatedTokens} tokens every session and measures neutral across ${o.exposures} exposed session(s) \u2014 enough data to detect an effect, and none found. Consider shortening "${o.name}" rather than removing it.`+(o.containsSafetyLanguage?" CAUTION: it contains guardrail language (destructive-command or credential rules) \u2014 preserve those lines when shortening.":"")}))}u(ae,"buildTrimProposals");async function ie(s,n,a){let o=[],i=0;for(let d of s)try{await a("/api/instruction-experiments",{instructionId:d.instructionId,projectPath:n,source:"groom"}),i++}catch(g){let m=g instanceof Error?g.message:String(g);o.push({...d,reason:`${d.reason} (not measurable by withholding: ${m})`})}return{nominated:i,unmeasurable:o}}u(ie,"nominateRemovals");function ce(s){let n=[];for(let o of s.harmful){let i=o.verdict.delta;n.push({instructionId:o.id,score:Math.min(.95,.75+Math.abs(i)),topProjectId:o.topProjectId??null,reason:`Measured harmful: sessions using "${o.name}" scored ${(i*100).toFixed(1)}pp worse across ${o.exposures} exposed session(s). Observational \u2014 review before archiving.`})}let a=new Set(s.harmful.map(o=>o.id));for(let o of s.candidates)a.has(o.id)||n.push({instructionId:o.id,score:re,topProjectId:o.topProjectId??null,reason:`Unused: "${o.name}" is ${o.reason} (${o.totalExposures} lifetime exposure(s)) but still costs context budget every session.`});return n.slice(0,oe)}u(ce,"buildRemovalProposals");function le(){let s=y.join(A.homedir(),".config","rulemetric","skills-registry.json");try{let n=q(s,"utf-8"),a=JSON.parse(n),o=new Date(a.generatedAt).getTime();return Number.isNaN(o)?"unknown":Date.now()-o>te*60*60*1e3?"stale":"fresh"}catch{return"unknown"}}u(le,"observeSkillsRegistry");var Re=u(async(s,n)=>{let a=J(),o=a!=="none";o?n.logger.info(`Scoring backend: ${a}`):n.logger.warn("No LLM backend available (claude CLI missing and ANTHROPIC_API_KEY unset); skipping relevance scoring. Removal/trim proposals still run \u2014 they need no LLM.");let i;try{i=(await w("/api/sessions/project-paths?limit="+ee)).projectPaths}catch(e){n.logger.warn(`Failed to fetch project paths: ${e instanceof Error?e.message:String(e)}`);return}if(i.length===0){n.logger.info("No recent project paths; nothing to score");return}let d=new Map;try{let e=await w("/api/projects?limit=200");for(let t of e.projects??[])t.primaryCheckoutPath&&d.set(x(t.primaryCheckoutPath),t.id)}catch(e){n.logger.warn(`Failed to fetch projects for id resolution: ${e instanceof Error?e.message:String(e)}`)}let g=new Map;try{let e=await w(`/api/catalog?limit=200&proposable=1&contentPreview=${O}`);for(let t of e)g.set(t.id,{id:t.id,name:t.name,description:t.description??"",tags:t.tags??[],contentPreview:(t.contentPreview??"").slice(0,O)})}catch(e){n.logger.warn(`Failed to fetch catalog: ${e instanceof Error?e.message:String(e)}`)}try{let e=await w("/api/instructions?limit=100");for(let t of e.instructions??[])g.has(t.id)||g.set(t.id,{id:t.id,name:t.name,description:t.description??"",tags:t.tags??[],contentPreview:(t.content??"").slice(0,O)})}catch(e){n.logger.warn(`Failed to fetch personal instructions: ${e instanceof Error?e.message:String(e)}`)}let m=[],p=[];try{let e=await w("/api/insights/groom-candidates");if(!e.captureHealthy)n.logger.info(`Grooming paused: ${e.reason??"capture unhealthy"}`);else{m=ce(e),p=ae(e);let t=e.safetyGuarded+e.harmfulSafetyGuarded;n.logger.info(`Removal proposals: ${m.length} (${e.harmful.length} measured-harmful, ${e.candidates.length} never-used, ${t} withheld by the safety allowlist); trim proposals: ${p.length} (${(e.bloated??[]).length} measured-neutral and expensive, ${e.trimSafetyFlagged??0} flagged as containing guardrail language)`)}}catch(e){n.logger.warn(`Failed to fetch groom candidates: ${e instanceof Error?e.message:String(e)}`)}let b=[...g.values()];if(b.length===0&&m.length===0&&p.length===0){n.logger.info("No candidate instructions and nothing to retire; nothing to score");return}n.logger.info(`Scoring ${b.length} candidates across ${i.length} project(s)`);let M=0,l=null,I=new Set;for(let e of i)try{let t=x(e);if(!Q(t)){n.logger.info(`Skipping ${t}: not a project directory (home/root)`);continue}let f=D(t),k=o&&f.length>0;f.length===0&&n.logger.info(`${t}: insufficient language signals; removal/trim only`);let v=X(t),z={name:y.basename(t),description:v.description,languages:f,topics:v.topics,dependencies:v.dependencies},E=k?U(b):[];k&&n.logger.info(`Scoring ${b.length} candidates for ${t} in ${E.length} batch(es)`);let C=[],$=0;for(let r of E)try{let c=await B(H(z,r),"",4096);if(!c){$++;continue}let T=c.recommendations??[];for(let P of T)typeof P.instructionId=="string"&&typeof P.score=="number"&&typeof P.reason=="string"&&C.push({instructionId:P.instructionId,score:P.score,reason:P.reason})}catch(c){$++,n.logger.warn(`Batch failed for ${t}: ${c instanceof Error?c.message:String(c)}`)}$>0&&n.logger.warn(`${$}/${E.length} batch(es) failed for ${t} (backend ${a}); suggestions are partial`),k&&C.length===0&&n.logger.warn(`No usable LLM output for ${t} (backend ${a})`);let K=C.filter(r=>r.score>=ne).sort((r,c)=>c.score-r.score).slice(0,Z),_=d.get(t),W=l===null||l===t;l===null&&(l=t);let N=u(r=>r.topProjectId?r.topProjectId===_:W,"placeHere"),F=m.filter(N),{nominated:L,unmeasurable:G}=await ie(F,t,R);L>0&&n.logger.info(`${t}: ${L} removal candidate(s) nominated for randomised withholding instead of the feed`);let h=[...K.map(r=>({instructionId:r.instructionId,score:r.score,reason:r.reason,kind:"add"})),...G.map(({topProjectId:r,...c})=>({...c,kind:"remove"})),...p.filter(N).map(({estimatedTokens:r,topProjectId:c,...T})=>({...T,kind:"trim"}))];if(h.length===0){n.logger.info(`Nothing to suggest for ${t}`);continue}await R("/api/instruction-suggestions/batch-upsert",{projectPath:t,..._?{projectId:_}:{},suggestions:h}),n.logger.info(`${t}: ${h.filter(r=>r.kind==="add").length} add + ${h.filter(r=>r.kind==="remove").length} remove + ${h.filter(r=>r.kind==="trim").length} trim`);for(let r of h)r.kind!=="add"&&I.add(r.instructionId);let Y=new Set(G.map(r=>r.instructionId));for(let r of F)Y.has(r.instructionId)||I.add(r.instructionId);M++}catch(t){n.logger.warn(`Failed to score ${e}: ${t instanceof Error?t.message:String(t)}`)}let j=[...m.filter(e=>!I.has(e.instructionId)),...p.filter(e=>!I.has(e.instructionId)).map(({estimatedTokens:e,...t})=>t)];if(j.length>0&&l)try{let e=new Set(p.map(t=>t.instructionId));await R("/api/instruction-suggestions/batch-upsert",{projectPath:l,...d.get(l)?{projectId:d.get(l)}:{},suggestions:j.map(({topProjectId:t,...f})=>({...f,kind:e.has(f.instructionId)?"trim":"remove"}))}),n.logger.info(`Orphan sweep: ${j.length} proposal(s) whose project was not scored this run placed on ${l}`)}catch(e){n.logger.warn(`Orphan sweep failed: ${e instanceof Error?e.message:String(e)}`)}let S=le();if(S==="unknown")n.logger.warn("Skills registry unreadable or has no usable generatedAt; leaving suggestion staleness unchanged");else try{await R("/api/instruction-suggestions/mark-stale",{stale:S==="stale"}),S==="stale"?n.logger.warn("Skills registry is stale (>48h); marked catalog-skill suggestions stale"):n.logger.info("Skills registry is fresh; cleared staleness on catalog-skill suggestions")}catch{}n.logger.info(`Done: scored ${M}/${i.length} projects`)},"cronSuggestInstructions");export{Q as a,ae as b,ie as c,ce as d,Re as e};
@@ -0,0 +1 @@
1
+ import{d as g}from"./chunk-SBGXIPRN.js";import{a as p}from"./chunk-6XTLP2G7.js";import{a as s}from"./chunk-ZLLER3HP.js";import{spawnSync as f}from"node:child_process";import{existsSync as h}from"node:fs";import{dirname as b,join as m,resolve as y}from"node:path";import{fileURLToPath as _}from"node:url";var d=["run.sh","rm_host_claude.py","rm_host_codex.py","summarize.py","cost_delta.py","provenance.py","mcp_container_shell.py","rm-batch-task/environment/Dockerfile","rm-batch-task/environment/items.jsonl","rm-batch-task/inject.md","rm-batch-task/instruction.md","rm-batch-task/solution/solve.sh","rm-batch-task/task.toml","rm-batch-task/tests/test.sh","rm-batch-task/tests/test_outputs.py","rm-locality-task/environment/Dockerfile","rm-locality-task/environment/workspace/deploy/prod/ingest.yaml","rm-locality-task/environment/workspace/deploy/staging/ingest.yaml","rm-locality-task/environment/workspace/docs/architecture/ingest.md","rm-locality-task/environment/workspace/legacy/ingest_v1/config.yaml","rm-locality-task/environment/workspace/packages/shared/defaults.py","rm-locality-task/environment/workspace/services/ingest/config/limits.defaults.yaml","rm-locality-task/environment/workspace/services/ingest/config/limits.yaml","rm-locality-task/environment/workspace/services/ingest/loader.py","rm-locality-task/environment/workspace/tests/fixtures/ingest_config.yaml","rm-locality-task/inject.md","rm-locality-task/instruction.md","rm-locality-task/solution/solve.sh","rm-locality-task/task.toml","rm-locality-task/tests/test.sh","rm-locality-task/tests/test_outputs.py","rm-migrations-task/environment/Dockerfile","rm-migrations-task/environment/applied.txt","rm-migrations-task/environment/migrations/00001_init.sql","rm-migrations-task/environment/migrations/00002_add_email.sql","rm-migrations-task/inject.md","rm-migrations-task/instruction.md","rm-migrations-task/solution/solve.sh","rm-migrations-task/task.toml","rm-migrations-task/tests/test.sh","rm-migrations-task/tests/test_outputs.py","rm-pagination-task/environment/Dockerfile","rm-pagination-task/environment/store.py","rm-pagination-task/inject.md","rm-pagination-task/instruction.md","rm-pagination-task/solution/solve.sh","rm-pagination-task/task.toml","rm-pagination-task/tests/test.sh","rm-pagination-task/tests/test_outputs.py"];var D=5e3,l=b(_(import.meta.url));function R(t={}){let r=t.env??process.env,n=t.exists??h,o=s(e=>d.every(i=>n(m(e,i))),"isHarness"),a=r.RULEMETRIC_HARBOR_DIR;if(a)return o(a)?y(a):null;for(let e of[m(t.moduleDir??l,"harbor"),m(t.moduleDir??l,"..","harbor")])if(o(e))return y(e);for(let e of[t.moduleDir??l,t.cwd??process.cwd()]){let i=e;for(let c=0;c<8;c++){let u=m(i,"scripts","harbor");if(o(u))return u;let k=b(i);if(k===i)break;i=k}}return null}s(R,"resolveHarborHarnessDir");var x={resolveBin:p,run:s((t,r)=>{let n=f(t,r,{encoding:"utf8",timeout:D});return{status:n.status,stdout:n.stdout??""}},"run"),hasEngine:s(()=>{let t=g();return t.claudeBin!=null||t.codexBin!=null},"hasEngine"),harnessDir:s(()=>R(),"harnessDir")};function v(t,r,n){let o=t.resolveBin(r);if(!o)return!1;let{status:a,stdout:e}=t.run(o,n);return a===0&&e.trim().length>0}s(v,"runnable");function O(t=x){let r=s(n=>{try{return n()}catch{return!1}},"safe");return{docker:r(()=>v(t,"docker",["info","--format","{{.ServerVersion}}"])),harbor:r(()=>v(t,"harbor",["--version"])),engine:r(()=>t.hasEngine()),harness:r(()=>t.harnessDir()!=null)}}s(O,"probeHarborReady");export{R as a,O as b};
@@ -1,4 +1,4 @@
1
- import{h as o}from"./chunk-RJX75Y7J.js";import{f}from"./chunk-U3XKXJ3A.js";import{b as y,e as m,h as d}from"./chunk-APDRR6FS.js";import{a as S}from"./chunk-ZLLER3HP.js";var _=1800*1e3,G=300*1e3,R=10,T=`Given these messages from an AI coding session, write a 1-2 sentence summary of what the user is trying to accomplish. Focus on the goal, not the steps. No preamble.
1
+ import{h as o}from"./chunk-FJX7WDPG.js";import{g as f}from"./chunk-GN46S7T4.js";import{b as y,e as m,h as d}from"./chunk-ZZHIBOMT.js";import{a as S}from"./chunk-ZLLER3HP.js";var _=1800*1e3,G=300*1e3,R=10,T=`Given these messages from an AI coding session, write a 1-2 sentence summary of what the user is trying to accomplish. Focus on the goal, not the steps. No preamble.
2
2
 
3
3
  Return strict JSON in the form: {"goalSummary": "..."}`;async function N(n,e={}){let w=e.llm??f,i=e.now??Date.now,v=e.getSession??(async s=>{try{return await o(()=>m(`/api/sessions/${s}`),{label:"session detail",idempotent:!0})}catch(t){if(t instanceof y&&t.statusCode===404)return null;throw t}}),l=e.getEvents??((s,t)=>o(()=>m(`/api/sessions/${s}/events?limit=${t.limit}&sort=${t.sort}`),{label:"session events",idempotent:!0})),P=e.saveGoal??(async(s,t)=>{await o(()=>d(`/api/sessions/${s}/enrich`,{analysis:t}),{label:"session enrich"})}),r=await v(n.sessionId);if(!r)return{skipped:"not_found"};let[A]=await l(n.sessionId,{limit:1,sort:"desc"}),h=new Date(A?.timestamp??r.startedAt).getTime();if(i()-h>_)return{skipped:"stale"};let c=r.analysis??{},g=c.goalSummaryAt?new Date(c.goalSummaryAt).getTime():0;if(g&&i()-g<G)return{skipped:"recent"};let u=(await l(n.sessionId,{limit:R*2,sort:"asc"})).filter(s=>s.content&&(s.eventType==="user_message"||s.eventType==="assistant_response")).map(s=>`${s.eventType==="user_message"?"USER":"ASSISTANT"}: ${s.content}`).join(`
4
4
 
@@ -1 +1 @@
1
- import{c as l}from"./chunk-APDRR6FS.js";import{c as a,l as u}from"./chunk-PZNWH4VQ.js";import{a as o}from"./chunk-ZLLER3HP.js";var c=120*1e3,t=null;async function k(){if(process.env.RULEMETRIC_API_KEY)return!0;let e=a(u());if(!e.isRefreshable(c))return!0;let r=e.loadToken();return r?.refreshToken?t||(t=f(e,r).finally(()=>{t=null}),t):!0}o(k,"ensureFreshToken");async function f(e,r){let s;try{s=await fetch(`${l()}/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:r.refreshToken})})}catch{return!0}if(s.status===401)return e.clearToken(),!1;if(!s.ok)return!0;let n=await s.json().catch(()=>null);if(!n?.accessToken||!n.refreshToken)return!0;let i={accessToken:n.accessToken,refreshToken:n.refreshToken,expiresAt:n.expiresAt??r.expiresAt,email:n.email??r.email};return e.saveToken(i),e.saveEnvFile(i.accessToken),!0}o(f,"doRefresh");export{k as a};
1
+ import{c as l}from"./chunk-ZZHIBOMT.js";import{c as a,l as u}from"./chunk-PZNWH4VQ.js";import{a as o}from"./chunk-ZLLER3HP.js";var c=120*1e3,t=null;async function k(){if(process.env.RULEMETRIC_API_KEY)return!0;let e=a(u());if(!e.isRefreshable(c))return!0;let r=e.loadToken();return r?.refreshToken?t||(t=f(e,r).finally(()=>{t=null}),t):!0}o(k,"ensureFreshToken");async function f(e,r){let s;try{s=await fetch(`${l()}/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:r.refreshToken})})}catch{return!0}if(s.status===401)return e.clearToken(),!1;if(!s.ok)return!0;let n=await s.json().catch(()=>null);if(!n?.accessToken||!n.refreshToken)return!0;let i={accessToken:n.accessToken,refreshToken:n.refreshToken,expiresAt:n.expiresAt??r.expiresAt,email:n.email??r.email};return e.saveToken(i),e.saveEnvFile(i.accessToken),!0}o(f,"doRefresh");export{k as a};
@@ -1 +1 @@
1
- import{b as g,c as m}from"./chunk-N7ODX6PO.js";import{e as s,h as c}from"./chunk-APDRR6FS.js";import{a as i}from"./chunk-ZLLER3HP.js";var u=6e4;function o(t,e){try{t(JSON.stringify({ts:new Date().toISOString(),...e}))}catch{t(`[tt-heartbeat] log_error event=${e.event}`)}}i(o,"structuredLog");function d(t,e){return e.aborted?Promise.resolve(!1):t<=0?Promise.resolve(!0):new Promise(r=>{let a=setTimeout(()=>{e.removeEventListener("abort",n),r(!0)},t),n=i(()=>{clearTimeout(a),e.removeEventListener("abort",n),r(!1)},"onAbort");e.addEventListener("abort",n,{once:!0})})}i(d,"abortableSleep");async function l(t,e){if(t.kind!=="tmux")return;let a=(await g(m(t.target))).code===0?"active":"missing";try{await c(`/api/terminal-targets/${t.id}/status`,{status:a,lastSeenAt:new Date().toISOString()}),o(e,{event:"tt_heartbeat",targetId:t.id,target:t.target,status:a})}catch(n){o(e,{event:"tt_heartbeat_error",targetId:t.id,target:t.target,error:n instanceof Error?n.message:String(n)})}}i(l,"probeAndReport");async function b(t){let e;try{e=await s("/api/terminal-targets?status=active")}catch(r){o(t,{event:"tt_heartbeat_list_error",error:r instanceof Error?r.message:String(r)});return}for(let r of e.targets??[])try{await l(r,t)}catch(a){o(t,{event:"tt_heartbeat_probe_error",targetId:r.id,error:a instanceof Error?a.message:String(a)})}}i(b,"runOneHeartbeatCycle");async function p(t){let e=t.log??(()=>{}),r=t.intervalMs??u;for(o(e,{event:"tt_heartbeat_start",intervalMs:r});!t.signal.aborted&&(await b(e),!!await d(r,t.signal)););o(e,{event:"tt_heartbeat_stop"})}i(p,"startTerminalTargetHeartbeat");export{l as a,b,p as c};
1
+ import{b as g,c as m}from"./chunk-N7ODX6PO.js";import{e as s,h as c}from"./chunk-ZZHIBOMT.js";import{a as i}from"./chunk-ZLLER3HP.js";var u=6e4;function o(t,e){try{t(JSON.stringify({ts:new Date().toISOString(),...e}))}catch{t(`[tt-heartbeat] log_error event=${e.event}`)}}i(o,"structuredLog");function d(t,e){return e.aborted?Promise.resolve(!1):t<=0?Promise.resolve(!0):new Promise(r=>{let a=setTimeout(()=>{e.removeEventListener("abort",n),r(!0)},t),n=i(()=>{clearTimeout(a),e.removeEventListener("abort",n),r(!1)},"onAbort");e.addEventListener("abort",n,{once:!0})})}i(d,"abortableSleep");async function l(t,e){if(t.kind!=="tmux")return;let a=(await g(m(t.target))).code===0?"active":"missing";try{await c(`/api/terminal-targets/${t.id}/status`,{status:a,lastSeenAt:new Date().toISOString()}),o(e,{event:"tt_heartbeat",targetId:t.id,target:t.target,status:a})}catch(n){o(e,{event:"tt_heartbeat_error",targetId:t.id,target:t.target,error:n instanceof Error?n.message:String(n)})}}i(l,"probeAndReport");async function b(t){let e;try{e=await s("/api/terminal-targets?status=active")}catch(r){o(t,{event:"tt_heartbeat_list_error",error:r instanceof Error?r.message:String(r)});return}for(let r of e.targets??[])try{await l(r,t)}catch(a){o(t,{event:"tt_heartbeat_probe_error",targetId:r.id,error:a instanceof Error?a.message:String(a)})}}i(b,"runOneHeartbeatCycle");async function p(t){let e=t.log??(()=>{}),r=t.intervalMs??u;for(o(e,{event:"tt_heartbeat_start",intervalMs:r});!t.signal.aborted&&(await b(e),!!await d(r,t.signal)););o(e,{event:"tt_heartbeat_stop"})}i(p,"startTerminalTargetHeartbeat");export{l as a,b,p as c};
@@ -1 +1 @@
1
- import{l as E}from"./chunk-J5HW45PZ.js";import{a as p,e as w}from"./chunk-PZNWH4VQ.js";import{a as o}from"./chunk-ZLLER3HP.js";import{fileURLToPath as v}from"node:url";import{existsSync as A,readFileSync as b}from"node:fs";import{dirname as L,join as x}from"node:path";function C(){let t=L(v(import.meta.url));for(let e=0;e<8;e++){let s=x(t,"package.json");if(A(s))try{let i=JSON.parse(b(s,"utf8"));if(i.name==="@rulemetric/cli"&&i.version)return i.version}catch{}let n=L(t);if(n===t)break;t=n}return"0.0.0"}o(C,"readCliVersion");var O=C(),I="https://rulemetric.com",l=class extends Error{constructor(s,n){super(n);this.statusCode=s;this.name="ApiError"}static{o(this,"ApiError")}};function S(){let t=p(),e=process.env.RULEMETRIC_API_URL??t.apiUrl;if(!e){if(process.env.RULEMETRIC_STRICT_LOCAL==="1"||t.strictLocal==="1")throw new Error("RULEMETRIC_STRICT_LOCAL is set but no RULEMETRIC_API_URL is configured \u2014 refusing the cloud default. Set RULEMETRIC_API_URL in the environment or ~/.config/rulemetric/env.");e=I}let s=new URL(e);if(s.protocol==="http:"&&s.hostname!=="localhost"&&s.hostname!=="127.0.0.1")throw new Error(`API URL must use HTTPS for non-localhost hosts: ${e}`);return e}o(S,"getBaseUrl");async function a(t,e={}){let n=`${S()}${t}`,i={"Content-Type":"application/json","User-Agent":`rulemetric-cli/${O}`,...e.headers},m=p(),d=process.env.RULEMETRIC_API_KEY||m.apiKey||w()?.accessToken||m.accessToken;d&&(i.Authorization=`Bearer ${d}`);let h=new URL(n),f=h.hostname==="localhost"||h.hostname==="127.0.0.1",P=process.env.HTTPS_PROXY,R=process.env.HTTP_PROXY;f&&(delete process.env.HTTPS_PROXY,delete process.env.HTTP_PROXY);let u=e.timeoutMs?new AbortController:void 0,g=!1,y=u?setTimeout(()=>{g=!0,u.abort()},e.timeoutMs):void 0,r;try{r=await fetch(n,{method:e.method??"GET",headers:i,body:e.body?JSON.stringify(e.body):void 0,signal:u?.signal})}catch(T){if(g){let U=new URL(n).host,_=Math.round(e.timeoutMs/1e3);throw new l(408,`Request to ${U} timed out after ${_}s. This is usually transient or a local proxy/gateway issue \u2014 retry, and if it persists check HTTPS_PROXY / the RuleMetric gateway (:8787).`)}throw T}finally{y&&clearTimeout(y),f&&(P!==void 0&&(process.env.HTTPS_PROXY=P),R!==void 0&&(process.env.HTTP_PROXY=R))}let c;if(r.headers.get("content-type")?.includes("application/json")?c=await r.json():c=await r.text(),!r.ok){let{message:T}=E(r.status,c);throw new l(r.status,T)}return c}o(a,"api");var j=o(t=>a(t),"apiGet"),F=o((t,e)=>a(t,{method:"POST",body:e}),"apiPost"),B=o((t,e)=>a(t,{method:"PUT",body:e}),"apiPut"),D=o((t,e)=>a(t,{method:"PATCH",body:e}),"apiPatch"),G=o(t=>a(t,{method:"DELETE"}),"apiDelete");export{I as a,l as b,S as c,a as d,j as e,F as f,B as g,D as h,G as i};
1
+ import{l as E}from"./chunk-TWPG3TEQ.js";import{a as p,e as w}from"./chunk-PZNWH4VQ.js";import{a as o}from"./chunk-ZLLER3HP.js";import{fileURLToPath as v}from"node:url";import{existsSync as A,readFileSync as b}from"node:fs";import{dirname as L,join as x}from"node:path";function C(){let t=L(v(import.meta.url));for(let e=0;e<8;e++){let s=x(t,"package.json");if(A(s))try{let i=JSON.parse(b(s,"utf8"));if(i.name==="@rulemetric/cli"&&i.version)return i.version}catch{}let n=L(t);if(n===t)break;t=n}return"0.0.0"}o(C,"readCliVersion");var O=C(),I="https://rulemetric.com",l=class extends Error{constructor(s,n){super(n);this.statusCode=s;this.name="ApiError"}static{o(this,"ApiError")}};function S(){let t=p(),e=process.env.RULEMETRIC_API_URL??t.apiUrl;if(!e){if(process.env.RULEMETRIC_STRICT_LOCAL==="1"||t.strictLocal==="1")throw new Error("RULEMETRIC_STRICT_LOCAL is set but no RULEMETRIC_API_URL is configured \u2014 refusing the cloud default. Set RULEMETRIC_API_URL in the environment or ~/.config/rulemetric/env.");e=I}let s=new URL(e);if(s.protocol==="http:"&&s.hostname!=="localhost"&&s.hostname!=="127.0.0.1")throw new Error(`API URL must use HTTPS for non-localhost hosts: ${e}`);return e}o(S,"getBaseUrl");async function a(t,e={}){let n=`${S()}${t}`,i={"Content-Type":"application/json","User-Agent":`rulemetric-cli/${O}`,...e.headers},m=p(),d=process.env.RULEMETRIC_API_KEY||m.apiKey||w()?.accessToken||m.accessToken;d&&(i.Authorization=`Bearer ${d}`);let h=new URL(n),f=h.hostname==="localhost"||h.hostname==="127.0.0.1",P=process.env.HTTPS_PROXY,R=process.env.HTTP_PROXY;f&&(delete process.env.HTTPS_PROXY,delete process.env.HTTP_PROXY);let u=e.timeoutMs?new AbortController:void 0,g=!1,y=u?setTimeout(()=>{g=!0,u.abort()},e.timeoutMs):void 0,r;try{r=await fetch(n,{method:e.method??"GET",headers:i,body:e.body?JSON.stringify(e.body):void 0,signal:u?.signal})}catch(T){if(g){let U=new URL(n).host,_=Math.round(e.timeoutMs/1e3);throw new l(408,`Request to ${U} timed out after ${_}s. This is usually transient or a local proxy/gateway issue \u2014 retry, and if it persists check HTTPS_PROXY / the RuleMetric gateway (:8787).`)}throw T}finally{y&&clearTimeout(y),f&&(P!==void 0&&(process.env.HTTPS_PROXY=P),R!==void 0&&(process.env.HTTP_PROXY=R))}let c;if(r.headers.get("content-type")?.includes("application/json")?c=await r.json():c=await r.text(),!r.ok){let{message:T}=E(r.status,c);throw new l(r.status,T)}return c}o(a,"api");var j=o(t=>a(t),"apiGet"),F=o((t,e)=>a(t,{method:"POST",body:e}),"apiPost"),B=o((t,e)=>a(t,{method:"PUT",body:e}),"apiPut"),D=o((t,e)=>a(t,{method:"PATCH",body:e}),"apiPatch"),G=o(t=>a(t,{method:"DELETE"}),"apiDelete");export{I as a,l as b,S as c,a as d,j as e,F as f,B as g,D as h,G as i};
@@ -1,2 +1,2 @@
1
- import{a as v,b as u,e as y,g as d}from"../../chunk-QTCWOIT4.js";import{a as h}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import"../../chunk-PZNWH4VQ.js";import{a as p}from"../../chunk-ZLLER3HP.js";import{Args as k,Flags as o}from"@oclif/core";import{existsSync as T}from"node:fs";import{homedir as P}from"node:os";import{join as I}from"node:path";var A=I(P(),".gemini","antigravity-ide","brain"),g=class x extends h{static{p(this,"AntigravityBackfill")}static description="Backfill historical events from an Antigravity conversation transcript into a RuleMetric session. Useful for seeding a conversation that existed before hooks were installed \u2014 the live hook intentionally only captures forward.";static examples=["<%= config.bin %> antigravity backfill 26fd215d-f43b-4ea5-b177-dc2c0e696f97 --session 158db9aa-68ee-43fc-961b-f3a180578694","<%= config.bin %> antigravity backfill 26fd215d-f43b-4ea5-b177-dc2c0e696f97 --dry-run"];static args={conversationId:k.string({description:"Antigravity conversationId (UUID) \u2014 the directory name under ~/.gemini/antigravity-ide/brain/",required:!0})};static flags={session:o.string({char:"s",description:"RuleMetric session UUID to POST events into. If omitted, resolved from the hook tmp file ($TMPDIR/rulemetric/<conversationId>) \u2014 fails if neither is present."}),transcript:o.string({description:"Path to the transcript.jsonl file. Defaults to ~/.gemini/antigravity-ide/brain/<conversationId>/.system_generated/logs/transcript.jsonl"}),"after-step":o.integer({description:"Only emit records with step_index > this value. Default: read from existing state file, else -1 (everything)."}),limit:o.integer({description:"Cap on the number of records to process this run."}),"dry-run":o.boolean({default:!1,description:"Classify records without POSTing. Reports counts only."}),"save-state":o.boolean({default:!0,allowNo:!0,description:"After backfill, persist the highest step_index so the live hook resumes from there."})};async run(){let{args:b,flags:e}=await this.parse(x),t=b.conversationId;d.loadEnvFile(),process.env.RULEMETRIC_API_URL||this.error("RULEMETRIC_API_URL is not set. Configure it via env or ~/.config/rulemetric/env.");let l=e.transcript??I(A,t,".system_generated","logs","transcript.jsonl");T(l)||this.error(`Transcript not found: ${l}`);let m=e.session??d.resolveRwSessionId(t);m||this.error(`No RuleMetric session resolved. Pass --session <uuid>, or run the Antigravity hook at least once so $TMPDIR/rulemetric/${t} is populated.`);let n=e["after-step"];n===void 0&&(n=d.load(t)?.lastStepIdx??-1);let i=v(l,n);e.limit!==void 0&&i.length>e.limit&&(i=i.slice(0,e.limit));let R=u(l);if(this.log(`Conversation ${t}: transcript max step = ${R}, after-step = ${n}, records to process = ${i.length}`),i.length===0){this.log("Nothing to backfill.");return}if(e["dry-run"]){let r=0,a=0,c={};for(let S of i){let f=(await import("../../lib/antigravity-transcript.js")).classifyRecord(S,0);f?(r++,c[f.eventType]=(c[f.eventType]??0)+1):a++}this.log(`Dry run: would emit ${r}, skip ${a}. By eventType: ${JSON.stringify(c)}`);return}let w=Date.now(),s=await y(i,m,t,n,{onProgress:p(({attempted:r,total:a})=>{(r%100===0||r===a)&&process.stderr.write(` \u2026${r}/${a}
1
+ import{a as v,b as u,e as y,g as d}from"../../chunk-S5CQSP35.js";import{a as h}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as p}from"../../chunk-ZLLER3HP.js";import{Args as k,Flags as o}from"@oclif/core";import{existsSync as T}from"node:fs";import{homedir as P}from"node:os";import{join as I}from"node:path";var A=I(P(),".gemini","antigravity-ide","brain"),g=class x extends h{static{p(this,"AntigravityBackfill")}static description="Backfill historical events from an Antigravity conversation transcript into a RuleMetric session. Useful for seeding a conversation that existed before hooks were installed \u2014 the live hook intentionally only captures forward.";static examples=["<%= config.bin %> antigravity backfill 26fd215d-f43b-4ea5-b177-dc2c0e696f97 --session 158db9aa-68ee-43fc-961b-f3a180578694","<%= config.bin %> antigravity backfill 26fd215d-f43b-4ea5-b177-dc2c0e696f97 --dry-run"];static args={conversationId:k.string({description:"Antigravity conversationId (UUID) \u2014 the directory name under ~/.gemini/antigravity-ide/brain/",required:!0})};static flags={session:o.string({char:"s",description:"RuleMetric session UUID to POST events into. If omitted, resolved from the hook tmp file ($TMPDIR/rulemetric/<conversationId>) \u2014 fails if neither is present."}),transcript:o.string({description:"Path to the transcript.jsonl file. Defaults to ~/.gemini/antigravity-ide/brain/<conversationId>/.system_generated/logs/transcript.jsonl"}),"after-step":o.integer({description:"Only emit records with step_index > this value. Default: read from existing state file, else -1 (everything)."}),limit:o.integer({description:"Cap on the number of records to process this run."}),"dry-run":o.boolean({default:!1,description:"Classify records without POSTing. Reports counts only."}),"save-state":o.boolean({default:!0,allowNo:!0,description:"After backfill, persist the highest step_index so the live hook resumes from there."})};async run(){let{args:b,flags:e}=await this.parse(x),t=b.conversationId;d.loadEnvFile(),process.env.RULEMETRIC_API_URL||this.error("RULEMETRIC_API_URL is not set. Configure it via env or ~/.config/rulemetric/env.");let l=e.transcript??I(A,t,".system_generated","logs","transcript.jsonl");T(l)||this.error(`Transcript not found: ${l}`);let m=e.session??d.resolveRwSessionId(t);m||this.error(`No RuleMetric session resolved. Pass --session <uuid>, or run the Antigravity hook at least once so $TMPDIR/rulemetric/${t} is populated.`);let n=e["after-step"];n===void 0&&(n=d.load(t)?.lastStepIdx??-1);let i=v(l,n);e.limit!==void 0&&i.length>e.limit&&(i=i.slice(0,e.limit));let R=u(l);if(this.log(`Conversation ${t}: transcript max step = ${R}, after-step = ${n}, records to process = ${i.length}`),i.length===0){this.log("Nothing to backfill.");return}if(e["dry-run"]){let r=0,a=0,c={};for(let S of i){let f=(await import("../../lib/antigravity-transcript.js")).classifyRecord(S,0);f?(r++,c[f.eventType]=(c[f.eventType]??0)+1):a++}this.log(`Dry run: would emit ${r}, skip ${a}. By eventType: ${JSON.stringify(c)}`);return}let w=Date.now(),s=await y(i,m,t,n,{onProgress:p(({attempted:r,total:a})=>{(r%100===0||r===a)&&process.stderr.write(` \u2026${r}/${a}
2
2
  `)},"onProgress")}),$=((Date.now()-w)/1e3).toFixed(1);this.log(`Backfill complete in ${$}s. attempted=${s.attempted} emitted=${s.emitted} skipped=${s.skipped} failed=${s.failed} highestStepIdx=${s.highestStepIdx}`),e["save-state"]?(d.save(t,{lastStepIdx:s.highestStepIdx}),this.log(`State saved \u2192 live hook will resume from step_index > ${s.highestStepIdx}.`)):this.log("State NOT saved (--no-save-state). Live hook will re-emit any new records from after-step.")}};export{g as default};
@@ -1 +1 @@
1
- import{a as n}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{f as r}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import{i as o,l as s}from"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import*as c from"node:path";import{Flags as l}from"@oclif/core";var t=class g extends n{static{a(this,"AuthCreateKey")}static description="Create a long-lived API key for CLI and proxy authentication";static examples=['<%= config.bin %> auth create-key --name "laptop"','<%= config.bin %> auth create-key --name "ci token" --no-save'];static flags={name:l.string({char:"n",description:"Name for this key",required:!0}),save:l.boolean({char:"s",description:"Save key to ~/.config/rulemetric/env for hooks/proxy",default:!0,allowNo:!0})};async run(){let{flags:i}=await this.parse(g),e=await r("/api/auth/api-keys",{name:i.name});this.log(""),this.log("API key created successfully:"),this.log(""),this.log(` Name: ${e.name}`),this.log(` Key: ${e.key}`),this.log(` Prefix: ${e.keyPrefix}`),this.log(""),this.warn("Save this key now \u2014 it will not be shown again."),i.save&&(o(e.key,process.env.RULEMETRIC_API_URL),this.log(""),this.log(`Key saved to ${c.join(s(),"env")} (RULEMETRIC_API_KEY)`),this.log("Hooks and proxy will use this key automatically."))}};export{t as default};
1
+ import{a as n}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{f as r}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import{i as o,l as s}from"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import*as c from"node:path";import{Flags as l}from"@oclif/core";var t=class g extends n{static{a(this,"AuthCreateKey")}static description="Create a long-lived API key for CLI and proxy authentication";static examples=['<%= config.bin %> auth create-key --name "laptop"','<%= config.bin %> auth create-key --name "ci token" --no-save'];static flags={name:l.string({char:"n",description:"Name for this key",required:!0}),save:l.boolean({char:"s",description:"Save key to ~/.config/rulemetric/env for hooks/proxy",default:!0,allowNo:!0})};async run(){let{flags:i}=await this.parse(g),e=await r("/api/auth/api-keys",{name:i.name});this.log(""),this.log("API key created successfully:"),this.log(""),this.log(` Name: ${e.name}`),this.log(` Key: ${e.key}`),this.log(` Prefix: ${e.keyPrefix}`),this.log(""),this.warn("Save this key now \u2014 it will not be shown again."),i.save&&(o(e.key,process.env.RULEMETRIC_API_URL),this.log(""),this.log(`Key saved to ${c.join(s(),"env")} (RULEMETRIC_API_KEY)`),this.log("Hooks and proxy will use this key automatically."))}};export{t as default};
@@ -1,4 +1,4 @@
1
- import{a as f}from"../../chunk-M2VVRQKA.js";import{a as w}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import{c}from"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import{b as n}from"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{b as r,d as a}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import{b as m,d,h as u,i as g}from"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{Flags as p}from"@oclif/core";var h=class y extends w{static{l(this,"AuthLogin")}static description="Log in to RuleMetric";static examples=["<%= config.bin %> auth login","<%= config.bin %> auth login -e user@example.com"];static flags={email:p.string({char:"e",description:"Email address"}),password:p.string({char:"p",description:"Password (for non-interactive use)"}),"api-key":p.string({description:"Authenticate with an API key from https://rulemetric.com/connect (required for Google/GitHub sign-ins, which have no password)",exclusive:["password"]})};async run(){let{flags:s}=await this.parse(y);if(s["api-key"]){await this.loginWithApiKey(s["api-key"]);return}let e=s.email,t=s.password;if(!e||!t){process.stdin.isTTY||this.error("Missing credentials in a non-interactive shell. Pass --email/-e and --password/-p, or set RULEMETRIC_API_KEY (create a key at https://rulemetric.com/connect).");let{input:o,password:k}=await import("@inquirer/prompts");this.log("Signed up with Google or GitHub? You have no password \u2014 press Ctrl-C and run:"),this.log(" rulemetric auth login --api-key <key> (create one at https://rulemetric.com/connect)"),this.log(""),e||(e=await o({message:"Email:"})),t||(t=await k({message:"Password:"}))}let i;try{i=await a("/auth/login",{method:"POST",body:{email:e,password:t},timeoutMs:2e4})}catch(o){throw o instanceof r&&o.statusCode===401&&this.error(`Invalid email or password.
1
+ import{a as f}from"../../chunk-V4PUYPTU.js";import{a as w}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import{c}from"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import{b as n}from"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{b as r,d as a}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import{b as m,d,h as u,i as g}from"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{Flags as p}from"@oclif/core";var h=class y extends w{static{l(this,"AuthLogin")}static description="Log in to RuleMetric";static examples=["<%= config.bin %> auth login","<%= config.bin %> auth login -e user@example.com"];static flags={email:p.string({char:"e",description:"Email address"}),password:p.string({char:"p",description:"Password (for non-interactive use)"}),"api-key":p.string({description:"Authenticate with an API key from https://rulemetric.com/connect (required for Google/GitHub sign-ins, which have no password)",exclusive:["password"]})};async run(){let{flags:s}=await this.parse(y);if(s["api-key"]){await this.loginWithApiKey(s["api-key"]);return}let e=s.email,t=s.password;if(!e||!t){process.stdin.isTTY||this.error("Missing credentials in a non-interactive shell. Pass --email/-e and --password/-p, or set RULEMETRIC_API_KEY (create a key at https://rulemetric.com/connect).");let{input:o,password:k}=await import("@inquirer/prompts");this.log("Signed up with Google or GitHub? You have no password \u2014 press Ctrl-C and run:"),this.log(" rulemetric auth login --api-key <key> (create one at https://rulemetric.com/connect)"),this.log(""),e||(e=await o({message:"Email:"})),t||(t=await k({message:"Password:"}))}let i;try{i=await a("/auth/login",{method:"POST",body:{email:e,password:t},timeoutMs:2e4})}catch(o){throw o instanceof r&&o.statusCode===401&&this.error(`Invalid email or password.
2
2
 
3
3
  If you signed up with Google or GitHub, you have no password \u2014 that is why this cannot work. Create an API key at https://rulemetric.com/connect, then run:
4
4
  rulemetric auth login --api-key <key>`),o}let v=i.expiresAt??new Date(Date.now()+3600*1e3).toISOString();d({accessToken:i.accessToken,refreshToken:i.refreshToken,expiresAt:v,email:i.email}),u(i.accessToken,process.env.RULEMETRIC_API_URL),await n(),await f(this.log.bind(this),this.warn.bind(this),this.config.version),c("auth_login",{},this.config.version),this.log(`Logged in as ${i.email}`)}async loginWithApiKey(s){let e=s.trim();e||this.error("Empty --api-key. Create one at https://rulemetric.com/connect"),process.env.RULEMETRIC_API_KEY=e;try{await a("/api/setup/status",{timeoutMs:2e4})}catch(t){throw delete process.env.RULEMETRIC_API_KEY,t instanceof r&&(t.statusCode===401||t.statusCode===403)&&this.error("That API key was rejected. Check you copied it whole (it is shown only once at creation) or mint a new one at https://rulemetric.com/connect"),t}g(e,process.env.RULEMETRIC_API_URL),m(),await n(),c("auth_login",{method:"api_key"},this.config.version),this.log(`Authenticated with API key ${e.slice(0,11)}...`),this.log("Verify any time with: rulemetric auth status")}};export{h as default};
@@ -1 +1 @@
1
- import{a as s}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import{f as i,j as r}from"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";var e=class t extends s{static{o(this,"AuthLogout")}static description="Log out of RuleMetric";static examples=["<%= config.bin %> auth logout"];async run(){await this.parse(t),i(),r(),this.log("Logged out successfully.")}};export{e as default};
1
+ import{a as s}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import{f as i,j as r}from"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";var e=class t extends s{static{o(this,"AuthLogout")}static description="Log out of RuleMetric";static examples=["<%= config.bin %> auth logout"];async run(){await this.parse(t),i(),r(),this.log("Logged out successfully.")}};export{e as default};
@@ -1,4 +1,4 @@
1
- import{a as k}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{e as n,i as c}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import"../../chunk-PZNWH4VQ.js";import{a as s}from"../../chunk-ZLLER3HP.js";import{Args as y}from"@oclif/core";var a=class m extends k{static{s(this,"AuthRevokeKey")}static description="Revoke an API key (run with no argument to list active keys)";static examples=["<%= config.bin %> auth revoke-key","<%= config.bin %> auth revoke-key rm_abc12345",'<%= config.bin %> auth revoke-key "my-laptop (auto)"'];static args={id:y.string({description:"API key ID, prefix (rm_xxxxxxxx), or name"})};async run(){let{args:o}=await this.parse(m),r=(await n("/api/auth/api-keys")).filter(e=>!e.revokedAt);if(!o.id){if(r.length===0){this.log("No active API keys.");return}this.log(`Active API keys \u2014 pass an id, prefix, or name to revoke one:
1
+ import{a as k}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{e as n,i as c}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as s}from"../../chunk-ZLLER3HP.js";import{Args as y}from"@oclif/core";var a=class m extends k{static{s(this,"AuthRevokeKey")}static description="Revoke an API key (run with no argument to list active keys)";static examples=["<%= config.bin %> auth revoke-key","<%= config.bin %> auth revoke-key rm_abc12345",'<%= config.bin %> auth revoke-key "my-laptop (auto)"'];static args={id:y.string({description:"API key ID, prefix (rm_xxxxxxxx), or name"})};async run(){let{args:o}=await this.parse(m),r=(await n("/api/auth/api-keys")).filter(e=>!e.revokedAt);if(!o.id){if(r.length===0){this.log("No active API keys.");return}this.log(`Active API keys \u2014 pass an id, prefix, or name to revoke one:
2
2
  `);for(let e of r)this.log(` ${e.id} ${e.keyPrefix}... ${e.name}`);return}let i=o.id,t=r.filter(e=>e.id===i||e.name===i||i.startsWith("rm_")&&i.startsWith(e.keyPrefix));t.length===0&&this.error(`No active API key matches "${i}". Run \`rulemetric auth revoke-key\` with no argument to list keys.`),t.length>1&&this.error(`"${i}" matches ${t.length} keys \u2014 use the exact key ID:
3
3
  `+t.map(e=>` ${e.id} ${e.keyPrefix}... ${e.name}`).join(`
4
4
  `)),await c(`/api/auth/api-keys/${t[0].id}`),this.log(`API key ${t[0].keyPrefix}... ("${t[0].name}") revoked.`)}};export{a as default};
@@ -1 +1 @@
1
- import{a as g}from"../../chunk-M2VVRQKA.js";import{a as h}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import{c as d}from"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import{b as l}from"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{b as m,d as p}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import{d as n,h as c}from"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Flags as u}from"@oclif/core";var t=class f extends h{static{o(this,"AuthSignup")}static description="Create a RuleMetric account from the CLI";static examples=["<%= config.bin %> auth signup","<%= config.bin %> auth signup -e user@example.com"];static flags={email:u.string({char:"e",description:"Email address"}),password:u.string({char:"p",description:"Password (min 8 chars; for non-interactive use)"})};async run(){let{flags:a}=await this.parse(f),i=a.email,r=a.password;if(!i||!r){process.stdin.isTTY||this.error("Missing credentials in a non-interactive shell. Pass --email/-e and --password/-p.");let{input:s,password:v}=await import("@inquirer/prompts");i||(i=await s({message:"Email:"})),r||(r=await v({message:"Password (min 8 chars):"}))}let e;try{e=await p("/auth/signup",{method:"POST",body:{email:i,password:r},timeoutMs:2e4})}catch(s){throw s instanceof m&&s.statusCode===409&&this.error(`An account with ${i} already exists. Run: rulemetric auth login -e ${i}`),s}if(e.confirmationRequired||!e.accessToken||!e.refreshToken){this.log(`Account created for ${e.email}.`),this.log("Check your email and click the confirmation link, then run:"),this.log(` rulemetric auth login -e ${e.email}`);return}let w=e.expiresAt??new Date(Date.now()+3600*1e3).toISOString();n({accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:w,email:e.email}),c(e.accessToken,process.env.RULEMETRIC_API_URL),await l(),await g(this.log.bind(this),this.warn.bind(this),this.config.version),d("auth_signup",{},this.config.version),this.log(`Signed up and logged in as ${e.email}`)}};export{t as default};
1
+ import{a as g}from"../../chunk-V4PUYPTU.js";import{a as h}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import{c as d}from"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import{b as l}from"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{b as m,d as p}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import{d as n,h as c}from"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Flags as u}from"@oclif/core";var t=class f extends h{static{o(this,"AuthSignup")}static description="Create a RuleMetric account from the CLI";static examples=["<%= config.bin %> auth signup","<%= config.bin %> auth signup -e user@example.com"];static flags={email:u.string({char:"e",description:"Email address"}),password:u.string({char:"p",description:"Password (min 8 chars; for non-interactive use)"})};async run(){let{flags:a}=await this.parse(f),i=a.email,r=a.password;if(!i||!r){process.stdin.isTTY||this.error("Missing credentials in a non-interactive shell. Pass --email/-e and --password/-p.");let{input:s,password:v}=await import("@inquirer/prompts");i||(i=await s({message:"Email:"})),r||(r=await v({message:"Password (min 8 chars):"}))}let e;try{e=await p("/auth/signup",{method:"POST",body:{email:i,password:r},timeoutMs:2e4})}catch(s){throw s instanceof m&&s.statusCode===409&&this.error(`An account with ${i} already exists. Run: rulemetric auth login -e ${i}`),s}if(e.confirmationRequired||!e.accessToken||!e.refreshToken){this.log(`Account created for ${e.email}.`),this.log("Check your email and click the confirmation link, then run:"),this.log(` rulemetric auth login -e ${e.email}`);return}let w=e.expiresAt??new Date(Date.now()+3600*1e3).toISOString();n({accessToken:e.accessToken,refreshToken:e.refreshToken,expiresAt:w,email:e.email}),c(e.accessToken,process.env.RULEMETRIC_API_URL),await l(),await g(this.log.bind(this),this.warn.bind(this),this.config.version),d("auth_signup",{},this.config.version),this.log(`Signed up and logged in as ${e.email}`)}};export{t as default};
@@ -1 +1 @@
1
- import{a as c}from"../../chunk-W2MV25SB.js";import{a as g}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import{a,e as l,l as t}from"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import*as u from"node:path";var o=class h extends g{static{r(this,"AuthStatus")}static description="Show current authentication status";static examples=["<%= config.bin %> auth status"];async run(){await this.parse(h);let e=l(),i=process.env.RULEMETRIC_API_KEY,s=a().apiKey;if(i||s){let m=i||s,p=i?"RULEMETRIC_API_KEY env var":u.join(t(),"env");this.log(`Authenticated via API key ${m.slice(0,11)}... (${p})`),e&&this.log(`Logged in as: ${e.email}`),this.log(`Config: ${t()}`);return}if(!e){this.log("Not logged in. Run `rulemetric auth login` to authenticate.");return}let n=new Date(e.expiresAt).getTime();if(Number.isNaN(n)||Date.now()>=n){this.log("Session expired. Run `rulemetric auth login` to re-authenticate.");return}this.log(`Logged in as: ${e.email}`),this.log(`Session expires: ${c(e.expiresAt)}`),this.log(`Config: ${t()}`)}};export{o as default};
1
+ import{a as c}from"../../chunk-W2MV25SB.js";import{a as g}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import{a,e as l,l as t}from"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import*as u from"node:path";var o=class h extends g{static{r(this,"AuthStatus")}static description="Show current authentication status";static examples=["<%= config.bin %> auth status"];async run(){await this.parse(h);let e=l(),i=process.env.RULEMETRIC_API_KEY,s=a().apiKey;if(i||s){let m=i||s,p=i?"RULEMETRIC_API_KEY env var":u.join(t(),"env");this.log(`Authenticated via API key ${m.slice(0,11)}... (${p})`),e&&this.log(`Logged in as: ${e.email}`),this.log(`Config: ${t()}`);return}if(!e){this.log("Not logged in. Run `rulemetric auth login` to authenticate.");return}let n=new Date(e.expiresAt).getTime();if(Number.isNaN(n)||Date.now()>=n){this.log("Session expired. Run `rulemetric auth login` to re-authenticate.");return}this.log(`Logged in as: ${e.email}`),this.log(`Session expires: ${c(e.expiresAt)}`),this.log(`Config: ${t()}`)}};export{o as default};
@@ -1,2 +1,2 @@
1
- import{a as f,b as k,c as S,d as x,e as R,f as n,g as y}from"../../chunk-SHYP27B7.js";import{b as C,c as w,f as v,g as b}from"../../chunk-QXPYGN7I.js";import{a as u}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import{l as m}from"../../chunk-PZNWH4VQ.js";import{a as h}from"../../chunk-ZLLER3HP.js";import{existsSync as O}from"node:fs";import{Flags as c}from"@oclif/core";var g=class E extends u{static{h(this,"CaptureScope")}static description="Show or set which projects RuleMetric captures \u2014 the Codex sweep and hook-driven sessions each have their own scope";static examples=["<%= config.bin %> <%= command.id %>","<%= config.bin %> <%= command.id %> --add ~/work/client-a --add ~/work/client-b","<%= config.bin %> <%= command.id %> --tool hooks --add ~/work/client-a","<%= config.bin %> <%= command.id %> --tool hooks --off","<%= config.bin %> <%= command.id %> --remove ~/work/client-a","<%= config.bin %> <%= command.id %> --off","<%= config.bin %> <%= command.id %> --all"];static flags={tool:c.string({description:'Which capture path to edit: "codex" (the worker transcript sweep, the default) or "hooks" (Claude Code / Cursor / Copilot / Antigravity hook sessions).',options:["codex","hooks"],default:"codex"}),add:c.string({description:"Capture sessions under this path (repeatable). Implies an allowlist.",multiple:!0}),remove:c.string({description:"Stop capturing under this path (repeatable).",multiple:!0}),off:c.boolean({description:"Turn this capture path off entirely.",exclusive:["all"]}),all:c.boolean({description:"Capture every project (the default).",exclusive:["off"]}),clear:c.boolean({description:"Remove this scope, restoring the default."})};async run(){let{flags:o}=await this.parse(E),s=m(),d=f(s);if(!((o.add?.length??0)>0||(o.remove?.length??0)>0||o.off||o.all||o.clear)){await this.show(s,d);return}for(let t of[...o.add??[],...o.remove??[]])R(t)||this.error(`Not an absolute path: ${t}
1
+ import{a as f,b as k,c as S,d as x,e as R,f as n,g as y}from"../../chunk-VALRPZXH.js";import{b as C,c as w,g as v,h as b}from"../../chunk-QI3FJKGK.js";import{a as u}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import{l as m}from"../../chunk-PZNWH4VQ.js";import{a as h}from"../../chunk-ZLLER3HP.js";import{existsSync as O}from"node:fs";import{Flags as c}from"@oclif/core";var g=class E extends u{static{h(this,"CaptureScope")}static description="Show or set which projects RuleMetric captures \u2014 the Codex sweep and hook-driven sessions each have their own scope";static examples=["<%= config.bin %> <%= command.id %>","<%= config.bin %> <%= command.id %> --add ~/work/client-a --add ~/work/client-b","<%= config.bin %> <%= command.id %> --tool hooks --add ~/work/client-a","<%= config.bin %> <%= command.id %> --tool hooks --off","<%= config.bin %> <%= command.id %> --remove ~/work/client-a","<%= config.bin %> <%= command.id %> --off","<%= config.bin %> <%= command.id %> --all"];static flags={tool:c.string({description:'Which capture path to edit: "codex" (the worker transcript sweep, the default) or "hooks" (Claude Code / Cursor / Copilot / Antigravity hook sessions).',options:["codex","hooks"],default:"codex"}),add:c.string({description:"Capture sessions under this path (repeatable). Implies an allowlist.",multiple:!0}),remove:c.string({description:"Stop capturing under this path (repeatable).",multiple:!0}),off:c.boolean({description:"Turn this capture path off entirely.",exclusive:["all"]}),all:c.boolean({description:"Capture every project (the default).",exclusive:["off"]}),clear:c.boolean({description:"Remove this scope, restoring the default."})};async run(){let{flags:o}=await this.parse(E),s=m(),d=f(s);if(!((o.add?.length??0)>0||(o.remove?.length??0)>0||o.off||o.all||o.clear)){await this.show(s,d);return}for(let t of[...o.add??[],...o.remove??[]])R(t)||this.error(`Not an absolute path: ${t}
2
2
  Use an absolute path or ~/\u2026 \u2014 relative paths cannot be matched against a session's cwd.`);for(let t of o.add??[]){let a=x(t);O(a)||this.warn(`${a} does not exist yet \u2014 added anyway, but nothing will match until it does.`)}let e;try{e=k(s)}catch(t){o.clear||this.error(t instanceof Error?t.message:String(t));let a=y(s);this.warn(`${f(s)} was not valid JSON \u2014 saved it to ${a} and starting fresh.`),e={}}let i=o.tool??"codex",r=void 0,l=!1;if(o.clear&&({config:e}=n(e,{op:"clear"},r,i)),o.off&&({config:e}=n(e,{op:"mode",mode:"off"},r,i)),o.all&&({config:e}=n(e,{op:"mode",mode:"all"},r,i)),o.remove?.length){let t=n(e,{op:"remove",roots:o.remove},r,i);e=t.config,l=t.emptiedToOff}o.add?.length&&({config:e}=n(e,{op:"add",roots:o.add},r,i)),S(s,e),l&&(this.log(`Removed the last root \u2014 ${i==="hooks"?"hook":"Codex"} capture is now OFF rather than silently capturing everything.`),this.log("Use --all to go back to capturing every project.")),await this.show(s,d),this.log(""),this.log(i==="hooks"?"Takes effect on the next hook fire. No restart needed.":"Takes effect on the next sweep (within ~30s). No restart needed.")}async show(o,s){let d=await C({configDir:o}),p=await w({configDir:o}),e=h((i,r,l,t)=>{if(this.log(`${i}: ${l}`),r.roots.length)for(let a of r.roots)this.log(` \u2022 ${a}`);r.error&&(this.log(" This scope is FAILING CLOSED \u2014 nothing is being captured on this path."),this.log(` Fix the file, or run \`rulemetric capture scope ${i==="Hook capture"?"--tool hooks ":""}--clear\` to start over.`)),r.source==="env"&&this.log(` Set by environment variable, which outranks the config file (${t}).`)},"print");e("Codex capture",d,v(d),"RULEMETRIC_CODEX_CAPTURE / RULEMETRIC_CODEX_ROOTS"),e("Hook capture",p,b(p),"RULEMETRIC_HOOKS_CAPTURE / RULEMETRIC_HOOKS_ROOTS"),this.log(`Config: ${s}`)}};export{g as default};
@@ -1,2 +1,2 @@
1
- import{a as g,b as d,c as p}from"../../chunk-W2MV25SB.js";import{a as c}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import{Flags as i}from"@oclif/core";var o=class m extends c{static{a(this,"Catalog")}static description="Browse the org instruction catalog";static flags={badge:i.string({description:"Filter by badge",options:["recommended","required"]}),scope:i.string({description:"Filter by scope",options:["org","team"]}),search:i.string({description:"Search by name or description"})};async run(){let{flags:e}=await this.parse(m);this.requireAuth();let s=new URLSearchParams;e.badge&&s.set("badge",e.badge),e.scope&&s.set("scope",e.scope),e.search&&s.set("search",e.search);let r=await n(`/api/catalog?${s.toString()}`);if(r.length===0){this.log("No instructions found in catalog.");return}for(let t of r){let l=t.badge?` [${t.badge}]`:"",f=t.tags?.length?` (${t.tags.join(", ")})`:"";this.log(` ${d(t.name,40)} \u2014 ${p(t.scope)}${l} v${t.version}${f} ${g(t.updatedAt)}`)}this.log(`
1
+ import{a as g,b as d,c as p}from"../../chunk-W2MV25SB.js";import{a as c}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import{Flags as i}from"@oclif/core";var o=class m extends c{static{a(this,"Catalog")}static description="Browse the org instruction catalog";static flags={badge:i.string({description:"Filter by badge",options:["recommended","required"]}),scope:i.string({description:"Filter by scope",options:["org","team"]}),search:i.string({description:"Search by name or description"})};async run(){let{flags:e}=await this.parse(m);this.requireAuth();let s=new URLSearchParams;e.badge&&s.set("badge",e.badge),e.scope&&s.set("scope",e.scope),e.search&&s.set("search",e.search);let r=await n(`/api/catalog?${s.toString()}`);if(r.length===0){this.log("No instructions found in catalog.");return}for(let t of r){let l=t.badge?` [${t.badge}]`:"",f=t.tags?.length?` (${t.tags.join(", ")})`:"";this.log(` ${d(t.name,40)} \u2014 ${p(t.scope)}${l} v${t.version}${f} ${g(t.updatedAt)}`)}this.log(`
2
2
  ${r.length} instruction(s) found.`)}};export{o as default};
@@ -1,3 +1,3 @@
1
- import{a as i}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{f as n}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import"../../chunk-PZNWH4VQ.js";import{a as t}from"../../chunk-ZLLER3HP.js";import{Args as c}from"@oclif/core";var o=class s extends i{static{t(this,"CatalogRecommend")}static description="Get AI-powered instruction recommendations for a project";static args={projectId:c.string({description:"ID of the project",required:!0})};async run(){let{args:a}=await this.parse(s);this.requireAuth(),this.log(`Analyzing project and generating recommendations...
1
+ import{a as i}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{f as n}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as t}from"../../chunk-ZLLER3HP.js";import{Args as c}from"@oclif/core";var o=class s extends i{static{t(this,"CatalogRecommend")}static description="Get AI-powered instruction recommendations for a project";static args={projectId:c.string({description:"ID of the project",required:!0})};async run(){let{args:a}=await this.parse(s);this.requireAuth(),this.log(`Analyzing project and generating recommendations...
2
2
  `);let r=await n(`/api/projects/${a.projectId}/recommendations`,{});if(r.error&&this.warn(`Note: ${r.error}`),r.recommendations.length===0){this.log("No recommendations found.");return}for(let e of r.recommendations)this.log(` ${(e.score*100).toFixed(0)}% \u2014 ${e.instructionId}`),this.log(` ${e.reason}
3
3
  `)}};export{o as default};
@@ -1 +1 @@
1
- import{a as o}from"../../chunk-4VN5PG2S.js";import{a as n}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{printTable as t}from"@oclif/table";var a=class s extends n{static{i(this,"CronsList")}static description="List manually-runnable maintenance tasks";static examples=["<%= config.bin %> crons list"];async run(){await this.parse(s),t({data:o.map(e=>({Name:e.name,"Scheduled by":e.scheduledBy,Description:e.description})),columns:["Name","Scheduled by","Description"]}),this.log(""),this.log("Scheduled crons run in Supabase pg_cron \u2014 audit them with:"),this.log(` psql "$DATABASE_URL" -c 'select jobname, schedule, active from cron.job;'`),this.log("Run any task above on demand with: rulemetric crons run <name>")}};export{a as default};
1
+ import{a as o}from"../../chunk-4VN5PG2S.js";import{a as n}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{printTable as t}from"@oclif/table";var a=class s extends n{static{i(this,"CronsList")}static description="List manually-runnable maintenance tasks";static examples=["<%= config.bin %> crons list"];async run(){await this.parse(s),t({data:o.map(e=>({Name:e.name,"Scheduled by":e.scheduledBy,Description:e.description})),columns:["Name","Scheduled by","Description"]}),this.log(""),this.log("Scheduled crons run in Supabase pg_cron \u2014 audit them with:"),this.log(` psql "$DATABASE_URL" -c 'select jobname, schedule, active from cron.job;'`),this.log("Run any task above on demand with: rulemetric crons run <name>")}};export{a as default};
@@ -1,2 +1,2 @@
1
- import{a as u}from"../../chunk-4VN5PG2S.js";import{a as c}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{Args as g,Flags as f}from"@oclif/core";var i=class m extends c{static{l(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:g.string({description:"Task name (run `rulemetric crons list` to see all)",required:!0})};static flags={quiet:f.boolean({char:"q",description:"Suppress per-line log output; print summary only"})};async run(){let{args:s,flags:d}=await this.parse(m);this.requireAuth();let n=u.find(e=>e.name===s.name);n||this.error(`Unknown task: ${s.name}
2
- Run \`rulemetric crons list\` to see available tasks.`);let o;try{({runManualTask:o}=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.\nThese maintenance tasks connect to the database directly \u2014 run them from a full RuleMetric checkout with DATABASE_URL and the worker dependencies installed."),e}this.log(`\u25B6 Running ${n.name} \u2026`);let h=Date.now(),t=await o(s.name);if(!d.quiet)for(let e of t.logs){let r=e.level==="error"||e.level==="warn"?`[${e.level}]`:"";this.log(` ${r} ${e.message}`)}let a=((t.durationMs??Date.now()-h)/1e3).toFixed(1);t.ok?this.log(`\u2713 ${n.name} completed in ${a}s (${t.logs.length} log line${t.logs.length===1?"":"s"})`):this.error(`\u2717 ${n.name} failed after ${a}s: ${t.error}`)}};export{i as default};
1
+ import{a as $}from"../../chunk-4VN5PG2S.js";import{a as k}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{e as b}from"../../chunk-ZZHIBOMT.js";import{A as f,B as g,z as h}from"../../chunk-TWPG3TEQ.js";import{a as p}from"../../chunk-74QIUVWY.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
+ 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-ZGW3N3A6.js";import"../chunk-IZTIYR5Q.js";import"../chunk-5XK6LB2T.js";import"../chunk-P2WSDHIA.js";import"../chunk-25RDT32M.js";import"../chunk-3AV3GTMP.js";import"../chunk-APDRR6FS.js";import"../chunk-J5HW45PZ.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
+ import{a as o}from"../chunk-N4RJ6CN7.js";import"../chunk-IZTIYR5Q.js";import"../chunk-E5YE25QG.js";import"../chunk-YUIRDBQQ.js";import"../chunk-HAYO6JYI.js";import"../chunk-3AV3GTMP.js";import"../chunk-ZZHIBOMT.js";import"../chunk-TWPG3TEQ.js";import"../chunk-74QIUVWY.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-H3BCWSYO.js";import"../chunk-M7QSC64D.js";import"../chunk-LTQ5BJYL.js";import"../chunk-G7V4ZZZ3.js";import"../chunk-6WQG6C7F.js";import{i as z,j as Q,k as Z,m as ee,n as te}from"../chunk-LB24UKHZ.js";import"../chunk-NRYLYMDM.js";import"../chunk-U3XKXJ3A.js";import"../chunk-5MXZJWQS.js";import"../chunk-N7ODX6PO.js";import{a as V}from"../chunk-OZQNSELV.js";import"../chunk-HFGO5762.js";import"../chunk-VS5ROGDP.js";import"../chunk-KCOJLTVX.js";import"../chunk-GN3ZHQ46.js";import"../chunk-U2NT5OSQ.js";import"../chunk-KGURGIZ2.js";import"../chunk-UPFH72PF.js";import"../chunk-WH3IPXXQ.js";import"../chunk-CDY7TQFZ.js";import"../chunk-VBXL7XO7.js";import"../chunk-HLNHBZLI.js";import"../chunk-BZS5QRWB.js";import{d as F}from"../chunk-SBGXIPRN.js";import"../chunk-6XTLP2G7.js";import"../chunk-PJ3WHQ67.js";import{a as X,b as D,c as Y,f as j,g as G}from"../chunk-QXPYGN7I.js";import{a as B}from"../chunk-ZGW3N3A6.js";import"../chunk-IZTIYR5Q.js";import"../chunk-5XK6LB2T.js";import"../chunk-P2WSDHIA.js";import"../chunk-25RDT32M.js";import"../chunk-3AV3GTMP.js";import{a as U,e as y}from"../chunk-APDRR6FS.js";import"../chunk-J5HW45PZ.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-S5U76YUI.js";import"../chunk-M7QSC64D.js";import"../chunk-VLWNSTYW.js";import"../chunk-G7V4ZZZ3.js";import"../chunk-SV73ASP2.js";import{i as z,j as Q,k as Z,m as ee,n as te}from"../chunk-LB24UKHZ.js";import"../chunk-RRM4HQG4.js";import"../chunk-7ML2UCI7.js";import"../chunk-GN46S7T4.js";import"../chunk-PPAHIVG5.js";import"../chunk-5MXZJWQS.js";import"../chunk-CT7FWSIU.js";import"../chunk-AHLVY52I.js";import"../chunk-N7ODX6PO.js";import{a as V}from"../chunk-OZQNSELV.js";import"../chunk-HFGO5762.js";import"../chunk-VS5ROGDP.js";import"../chunk-OUK2AWEI.js";import"../chunk-SWSOEYC7.js";import"../chunk-U2NT5OSQ.js";import"../chunk-KGURGIZ2.js";import"../chunk-GYNZ3OZF.js";import"../chunk-UPFH72PF.js";import"../chunk-OO2ZRKZY.js";import"../chunk-CDY7TQFZ.js";import"../chunk-VBXL7XO7.js";import"../chunk-UJ7EPLKC.js";import"../chunk-PUX6P5KC.js";import"../chunk-SG4UDDHB.js";import{d as F}from"../chunk-SBGXIPRN.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-N4RJ6CN7.js";import"../chunk-IZTIYR5Q.js";import"../chunk-E5YE25QG.js";import"../chunk-YUIRDBQQ.js";import"../chunk-HAYO6JYI.js";import"../chunk-3AV3GTMP.js";import{a as U,e as y}from"../chunk-ZZHIBOMT.js";import"../chunk-TWPG3TEQ.js";import"../chunk-74QIUVWY.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-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{f as s}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.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
+ import{a}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{f as s}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.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-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.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
+ import{a as p,b as e}from"../../chunk-W2MV25SB.js";import{a as o}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.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 C,b as D,c as $}from"../../chunk-R4QIPG4V.js";import{b as L}from"../../chunk-N7GK33PU.js";import{c as m}from"../../chunk-RO3ZZVCG.js";import{e as A}from"../../chunk-MLV2RHRE.js";import"../../chunk-QFKUSNUB.js";import"../../chunk-4N43IBXH.js";import"../../chunk-IEQDLURA.js";import"../../chunk-KINIFUZQ.js";import"../../chunk-VIQ25ORK.js";import"../../chunk-6ZPSVZNH.js";import"../../chunk-RGUCR7T6.js";import"../../chunk-WY3VVX3R.js";import"../../chunk-KV5A77XW.js";import"../../chunk-ZYGBABMZ.js";import"../../chunk-U7TBEC3I.js";import"../../chunk-Y7QIOPN5.js";import"../../chunk-HOQPVOMF.js";import"../../chunk-DUBBL57L.js";import"../../chunk-WHQ4BDSM.js";import"../../chunk-PPXOC7IV.js";import"../../chunk-3MDEGOUG.js";import"../../chunk-JNFB22FD.js";import"../../chunk-HLQZR4XJ.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-SN3CHV66.js";import"../../chunk-6W2GSV4O.js";import"../../chunk-JWFRI32Y.js";import"../../chunk-25Q3Y7TC.js";import"../../chunk-MNQPCNGQ.js";import"../../chunk-PZS55PW2.js";import"../../chunk-WQX4RRBQ.js";import"../../chunk-3ZHVP3KE.js";import"../../chunk-WOJ733IB.js";import"../../chunk-RJX75Y7J.js";import"../../chunk-SJKS3PYX.js";import"../../chunk-2EX27VJ3.js";import"../../chunk-UM4CBCXI.js";import"../../chunk-3UKZJAFS.js";import"../../chunk-4COLIGD7.js";import"../../chunk-VXUKXGRX.js";import"../../chunk-PVGUDJD7.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-SIGZEQ3K.js";import"../../chunk-4FSQSETR.js";import"../../chunk-VH2EAP4J.js";import"../../chunk-J6QMBMC2.js";import"../../chunk-UYPBIXF2.js";import"../../chunk-OZNKMJ5B.js";import"../../chunk-F6DAHCJC.js";import"../../chunk-GBWQENAH.js";import"../../chunk-LJRE3LZ2.js";import"../../chunk-YI2OWO6R.js";import"../../chunk-V2USQH27.js";import"../../chunk-RK663O4M.js";import"../../chunk-6GAIYJ6K.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-MODXEGCU.js";import"../../chunk-C42NTI2V.js";import"../../chunk-RBSEE2Z6.js";import"../../chunk-BG55WDDX.js";import"../../chunk-H3BCWSYO.js";import"../../chunk-M7QSC64D.js";import"../../chunk-LTQ5BJYL.js";import"../../chunk-G7V4ZZZ3.js";import"../../chunk-6WQG6C7F.js";import"../../chunk-LB24UKHZ.js";import"../../chunk-NRYLYMDM.js";import"../../chunk-U3XKXJ3A.js";import"../../chunk-5MXZJWQS.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-OZQNSELV.js";import"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import"../../chunk-KCOJLTVX.js";import"../../chunk-GN3ZHQ46.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-UPFH72PF.js";import"../../chunk-WH3IPXXQ.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-VBXL7XO7.js";import"../../chunk-HLNHBZLI.js";import"../../chunk-BZS5QRWB.js";import"../../chunk-SBGXIPRN.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{b as O,f as y,h as I}from"../../chunk-QXPYGN7I.js";import{a as b}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{f as d}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import{e as P,l as f}from"../../chunk-PZNWH4VQ.js";import{a as e}from"../../chunk-ZLLER3HP.js";import{trace as ce,context as le}from"@opentelemetry/api";import{NodeSDK as U}from"@opentelemetry/sdk-node";import{OTLPTraceExporter as X}from"@opentelemetry/exporter-trace-otlp-http";import{BatchSpanProcessor as B,ConsoleSpanExporter as H,SimpleSpanProcessor as K}from"@opentelemetry/sdk-trace-node";import{Resource as Y}from"@opentelemetry/resources";import{ATTR_SERVICE_NAME as J,ATTR_SERVICE_VERSION as W}from"@opentelemetry/semantic-conventions";function M(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(),a=o.slice(s+1).trim();i&&(n[i]=a)}return n}e(M,"parseOtlpHeaders");var p=null;function S(){return process.env.TELEMETRY_ENABLED!=="false"}e(S,"isTelemetryEnabled");function E(r){if(!S()||p!==null)return"off";let n=new Y({[J]:r.serviceName,[W]:r.serviceVersion??"0.1.0"}),o=process.env.OTEL_EXPORTER_OTLP_ENDPOINT,s,i;if(o){let a=M(process.env.OTEL_EXPORTER_OTLP_HEADERS),l=new X({url:`${o}/v1/traces`,headers:a});i=new B(l),s="otlp"}else if(process.env.OTEL_SPAN_EXPORT==="none")i=void 0,s="silent";else{let a=new H;i=new K(a),s="console"}return p=new U({resource:n,spanProcessors:i?[i]:[]}),p.start(),s}e(E,"initTelemetry");async function g(){p&&(await p.shutdown(),p=null)}e(g,"shutdownTelemetry");import{SpanKind as Ee,SpanStatusCode as Te}from"@opentelemetry/api";import{trace as ke,context as Ne}from"@opentelemetry/api";import*as u from"@sentry/node";var T=!1;function x(r){if(T)return!1;let n=process.env.SENTRY_DSN;return n?(u.init({dsn:n,serverName:r.serviceName,environment:process.env.NODE_ENV??"development",tracesSampleRate:0}),T=!0,!0):!1}e(x,"initSentry");async function h(r){T&&await u.flush(r)}e(h,"flushSentry");import{existsSync as Q,mkdirSync as Z,readFileSync as k,unlinkSync as G,writeFileSync as V}from"node:fs";import{dirname as ee,join as w}from"node:path";import{execFileSync as te}from"node:child_process";var c=w(f(),"evals-agent.lock");function re(r){try{return process.kill(r,0),!0}catch(n){return n.code==="EPERM"}}e(re,"pidAlive");function ne(r){if(!re(r))return!1;try{let n=te("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(ne,"isLiveAgent");function oe(){try{Z(ee(c),{recursive:!0})}catch{}for(let r=0;r<2;r++)try{return V(c,String(process.pid),{flag:"wx"}),{ok:!0}}catch(n){if(n.code!=="EEXIST")throw n;let o=0;try{o=Number(k(c,"utf-8").trim())}catch{}if(o&&o!==process.pid&&ne(o))return{ok:!1,holder:o};try{G(c)}catch{}}try{V(c,String(process.pid))}catch{}return{ok:!0}}e(oe,"acquireAgentLock");function v(){try{Q(c)&&Number(k(c,"utf-8").trim())===process.pid&&G(c)}catch{}}e(v,"releaseAgentLock");var R=class r extends b{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=oe();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",x({serviceName:"rulemetric-agent"})&&this.log("[sentry] error capture enabled");let s=E({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)"),!P()&&!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
- `);let a=new AbortController,l=await O({configDir:f()});if(this.log(`[transcript-sync] Codex capture: ${y(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 j=new L({postSnapshot:e((t,F)=>d(`/api/sessions/${t}/context-snapshots`,F),"postSnapshot"),linkInstructions:e(t=>d("/api/sessions/link-instructions",{sessionId:t}),"linkInstructions"),log:e(t=>this.log(`[transcript-sync] ${t}`),"log")}),q=new C({providers:[D(void 0,void 0,I({configDir:f(),onChange:e(t=>this.log(`[transcript-sync] Codex capture changed: ${y(t)}`),"onChange")}))],statePath:w(f(),"transcript-sync-state.json"),importTranscript:e(t=>d("/api/sessions/import",t),"importTranscript"),emitInstructions:e(t=>j.emit(t),"emitInstructions"),log:e(t=>this.log(`[transcript-sync] ${t}`),"log")});$(q,{signal:a.signal,log:e(t=>this.log(`[transcript-sync] ${t}`),"log")});let N=e(async t=>{this.log(`
3
- [${t}] shutting down agent...`),a.abort(),await Promise.allSettled([h(2e3),g(),m()]),v(),process.exit(0)},"shutdown");process.on("SIGINT",()=>{N("SIGINT")}),process.on("SIGTERM",()=>{N("SIGTERM")});let _=!1;try{await A({signal:a.signal,log:e(t=>this.log(t),"log"),version:this.config.version,readInstalledVersion:e(()=>{try{return JSON.parse(k(w(this.config.root,"package.json"),"utf-8")).version??null}catch{return null}},"readInstalledVersion"),onVersionDrift:e(()=>{_=!0},"onVersionDrift")}),_&&(this.log("[upgrade] Installed CLI version changed \u2014 restarting worker onto the new code."),await Promise.allSettled([h(2e3),g(),m()]),v(),process.exit(1))}finally{v(),await m()}}};export{R as default};
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-HRJDKAJ4.js";import{e as D}from"../../chunk-OYAOLJUH.js";import"../../chunk-NRYVMGJN.js";import"../../chunk-ZA6NXNPR.js";import"../../chunk-IEQDLURA.js";import"../../chunk-KINIFUZQ.js";import"../../chunk-FCTFHY3X.js";import"../../chunk-JRAXWASH.js";import"../../chunk-LDUJWJ6A.js";import"../../chunk-WSWZPNLG.js";import"../../chunk-OLJF4K7L.js";import"../../chunk-DDYGA2DS.js";import"../../chunk-ZYGBABMZ.js";import"../../chunk-YP2CBUXH.js";import"../../chunk-U7BPWFOP.js";import"../../chunk-3ZHVP3KE.js";import"../../chunk-XFLKW6SJ.js";import"../../chunk-HOQPVOMF.js";import"../../chunk-5XEGRU2R.js";import"../../chunk-SPJ73X7A.js";import"../../chunk-E7GQJML3.js";import"../../chunk-PPIZMPNI.js";import"../../chunk-IC6VZHE6.js";import"../../chunk-5RBLIVBF.js";import"../../chunk-EXVXKJ7Y.js";import"../../chunk-INAZLRY5.js";import"../../chunk-OMRH4JXS.js";import"../../chunk-JLBQKV4V.js";import"../../chunk-FJX7WDPG.js";import"../../chunk-EWGE7YTQ.js";import"../../chunk-XAOLOR4Q.js";import"../../chunk-PZS55PW2.js";import"../../chunk-NSPDDSRR.js";import"../../chunk-SJKS3PYX.js";import"../../chunk-ET7753IY.js";import"../../chunk-YNLHJHUP.js";import"../../chunk-3UKZJAFS.js";import"../../chunk-IOX4VJPR.js";import"../../chunk-JRWQJZYQ.js";import"../../chunk-GIRPEMTW.js";import"../../chunk-SIGZEQ3K.js";import"../../chunk-LMCICVE7.js";import"../../chunk-J7UZXRTH.js";import"../../chunk-N7SZWKCU.js";import"../../chunk-BVOXWAJO.js";import"../../chunk-SE3UKA3M.js";import"../../chunk-O62OLKQL.js";import"../../chunk-LJRE3LZ2.js";import"../../chunk-HFSISGCJ.js";import"../../chunk-UQDOOQCM.js";import"../../chunk-E7RH43OS.js";import"../../chunk-JKWB6UXA.js";import"../../chunk-6UEFCMR2.js";import"../../chunk-MODXEGCU.js";import"../../chunk-MHVHGKDK.js";import"../../chunk-RBSEE2Z6.js";import"../../chunk-GQGGFHX7.js";import"../../chunk-S5U76YUI.js";import"../../chunk-M7QSC64D.js";import"../../chunk-VLWNSTYW.js";import"../../chunk-G7V4ZZZ3.js";import"../../chunk-SV73ASP2.js";import"../../chunk-LB24UKHZ.js";import"../../chunk-RRM4HQG4.js";import"../../chunk-7ML2UCI7.js";import"../../chunk-GN46S7T4.js";import"../../chunk-PPAHIVG5.js";import"../../chunk-5MXZJWQS.js";import"../../chunk-CT7FWSIU.js";import"../../chunk-AHLVY52I.js";import"../../chunk-N7ODX6PO.js";import"../../chunk-OZQNSELV.js";import"../../chunk-HFGO5762.js";import"../../chunk-VS5ROGDP.js";import"../../chunk-OUK2AWEI.js";import"../../chunk-SWSOEYC7.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-GYNZ3OZF.js";import"../../chunk-UPFH72PF.js";import"../../chunk-OO2ZRKZY.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-VBXL7XO7.js";import"../../chunk-UJ7EPLKC.js";import"../../chunk-PUX6P5KC.js";import"../../chunk-SG4UDDHB.js";import"../../chunk-SBGXIPRN.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-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{f as m}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.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
+ `);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
+ [${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{b as $}from"../../chunk-KCOJLTVX.js";import"../../chunk-GN3ZHQ46.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-UPFH72PF.js";import"../../chunk-WH3IPXXQ.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-HLNHBZLI.js";import"../../chunk-BZS5QRWB.js";import"../../chunk-SBGXIPRN.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as w}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.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(`
1
+ import{a as k}from"../../chunk-RBSEE2Z6.js";import{e as $}from"../../chunk-OUK2AWEI.js";import"../../chunk-SWSOEYC7.js";import"../../chunk-U2NT5OSQ.js";import"../../chunk-KGURGIZ2.js";import"../../chunk-GYNZ3OZF.js";import"../../chunk-UPFH72PF.js";import"../../chunk-OO2ZRKZY.js";import"../../chunk-CDY7TQFZ.js";import"../../chunk-UJ7EPLKC.js";import"../../chunk-PUX6P5KC.js";import"../../chunk-SG4UDDHB.js";import"../../chunk-SBGXIPRN.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as w}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.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-O2HCD6XL.js";import"../../chunk-VBXL7XO7.js";import{a as m}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{e as c}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.js";import"../../chunk-PZNWH4VQ.js";import{a as u}from"../../chunk-ZLLER3HP.js";import{Args as p,Flags as v}from"@oclif/core";var d=class b extends m{static{u(this,"EvalBenchmarkCommand")}static description="Aggregate eval runs into a benchmark for a target";static examples=["<%= config.bin %> evals benchmark <target-id>","<%= config.bin %> evals benchmark <target-id> --iteration 2"];static args={targetId:p.string({description:"Eval target ID",required:!0})};static flags={iteration:v.integer({description:"Filter runs by iteration",default:1})};async run(){let{args:o,flags:l}=await this.parse(b);this.requireAuth();let g=await c(`/api/eval-targets/${o.targetId}`);this.log(`Aggregating benchmark for "${g.name}" v${g.version}, iteration ${l.iteration}`);let a=await h(o.targetId,l.iteration);a.totalRuns===0&&this.error("No completed runs found. Run evals first with `rulemetric evals run`."),this.log(`
1
+ import{b as h,c as f}from"../../chunk-AT2MMCOJ.js";import"../../chunk-VBXL7XO7.js";import{a as m}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{e as c}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.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{f as p}from"../../chunk-HLNHBZLI.js";import"../../chunk-BZS5QRWB.js";import"../../chunk-SBGXIPRN.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as f}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{e as l,f as w}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.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)...
1
+ import{a as $,b as A}from"../../chunk-647M2I2Y.js";import{f as p}from"../../chunk-UJ7EPLKC.js";import"../../chunk-PUX6P5KC.js";import"../../chunk-SG4UDDHB.js";import"../../chunk-SBGXIPRN.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as f}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{e as l,f as w}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.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-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{f as i}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.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
+ import{a as c}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{f as i}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.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-NBEZ5FAU.js";import{f as b}from"../../chunk-HLNHBZLI.js";import"../../chunk-BZS5QRWB.js";import"../../chunk-SBGXIPRN.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as N}from"../../chunk-ZGW3N3A6.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-5XK6LB2T.js";import"../../chunk-P2WSDHIA.js";import"../../chunk-25RDT32M.js";import"../../chunk-3AV3GTMP.js";import{e as y,f as q,g as w}from"../../chunk-APDRR6FS.js";import"../../chunk-J5HW45PZ.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(`
1
+ import{a as P,b as S}from"../../chunk-UFQ43KXE.js";import{f as b}from"../../chunk-UJ7EPLKC.js";import"../../chunk-PUX6P5KC.js";import"../../chunk-SG4UDDHB.js";import"../../chunk-SBGXIPRN.js";import"../../chunk-6XTLP2G7.js";import"../../chunk-PJ3WHQ67.js";import{a as N}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{e as y,f as q,g as w}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.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(`