@rulemetric/cli 0.14.0 → 0.14.2

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 (251) hide show
  1. package/dist/base-command.js +1 -1
  2. package/dist/{chunk-S5U76YUI.js → chunk-3NWJ7CZ2.js} +1 -1
  3. package/dist/{chunk-OLJF4K7L.js → chunk-5PMTNNA6.js} +1 -1
  4. package/dist/{chunk-ZA6NXNPR.js → chunk-5TM7AOH2.js} +1 -1
  5. package/dist/chunk-5VNEHPGC.js +1 -0
  6. package/dist/{chunk-JKWB6UXA.js → chunk-6AAAHV2B.js} +1 -1
  7. package/dist/{chunk-J7UZXRTH.js → chunk-6T6YFPBW.js} +1 -1
  8. package/dist/{chunk-VLWNSTYW.js → chunk-6TGFU6RU.js} +1 -1
  9. package/dist/chunk-77FH6UZP.js +111 -0
  10. package/dist/{chunk-GN46S7T4.js → chunk-7BCZDVIU.js} +1 -1
  11. package/dist/{chunk-IOX4VJPR.js → chunk-7MTYUTUN.js} +1 -1
  12. package/dist/{chunk-S5CQSP35.js → chunk-BDQTVYYF.js} +1 -1
  13. package/dist/chunk-CQD2R3BA.js +3 -0
  14. package/dist/{chunk-FJX7WDPG.js → chunk-CVPAKEEZ.js} +1 -1
  15. package/dist/{chunk-EXVXKJ7Y.js → chunk-CYCH2EQC.js} +1 -1
  16. package/dist/{chunk-JLBQKV4V.js → chunk-CZBO3A6B.js} +1 -1
  17. package/dist/{chunk-N7SZWKCU.js → chunk-DANMUHNW.js} +1 -1
  18. package/dist/chunk-DQYYHX6K.js +1 -0
  19. package/dist/{chunk-OO2ZRKZY.js → chunk-DVU5PHPM.js} +1 -1
  20. package/dist/{chunk-HAYO6JYI.js → chunk-DX6IPDED.js} +1 -1
  21. package/dist/{chunk-E7RH43OS.js → chunk-DXNUCWUX.js} +1 -1
  22. package/dist/{chunk-2WQUOC6S.js → chunk-EBWV4SUS.js} +1 -1
  23. package/dist/{chunk-JRAXWASH.js → chunk-F5PJN2EY.js} +1 -1
  24. package/dist/chunk-FBSZ6KCM.js +1 -0
  25. package/dist/{chunk-JRWQJZYQ.js → chunk-FS3TAQAE.js} +1 -1
  26. package/dist/{chunk-O62OLKQL.js → chunk-FXQS7AEZ.js} +1 -1
  27. package/dist/chunk-FZMO7XSN.js +4 -0
  28. package/dist/{chunk-H4LUPIHJ.js → chunk-GDLQNY4V.js} +1 -1
  29. package/dist/{chunk-ZZHIBOMT.js → chunk-GIXHG5FK.js} +1 -1
  30. package/dist/{chunk-NSPDDSRR.js → chunk-GLBWNB2N.js} +1 -1
  31. package/dist/chunk-GPBN4ROE.js +2 -0
  32. package/dist/{chunk-AT2MMCOJ.js → chunk-H2FMAJUJ.js} +1 -1
  33. package/dist/chunk-H33XYL7O.js +1 -0
  34. package/dist/{chunk-EWGE7YTQ.js → chunk-H4QPAEEA.js} +1 -1
  35. package/dist/{chunk-YP2CBUXH.js → chunk-HM63AB2C.js} +1 -1
  36. package/dist/{chunk-DDYGA2DS.js → chunk-ISFPPDDB.js} +1 -1
  37. package/dist/{chunk-BVOXWAJO.js → chunk-ISYU5BMU.js} +1 -1
  38. package/dist/{chunk-XAOLOR4Q.js → chunk-J6RQ5AH2.js} +1 -1
  39. package/dist/chunk-JP6ULOEX.js +2 -0
  40. package/dist/{chunk-ET7753IY.js → chunk-KE5K3F7J.js} +1 -1
  41. package/dist/{chunk-YUIRDBQQ.js → chunk-KEVDLLHT.js} +1 -1
  42. package/dist/{chunk-GQGGFHX7.js → chunk-KOYHJFB3.js} +1 -1
  43. package/dist/{chunk-OMRH4JXS.js → chunk-L562Y4RN.js} +1 -1
  44. package/dist/chunk-MOJY6S5J.js +1 -0
  45. package/dist/chunk-MYGVN6X4.js +1 -0
  46. package/dist/{chunk-MX34N7Y5.js → chunk-NWV66NMA.js} +1 -1
  47. package/dist/{chunk-SV73ASP2.js → chunk-O4K4M5G6.js} +1 -1
  48. package/dist/{chunk-YNLHJHUP.js → chunk-PIVEJTNF.js} +1 -1
  49. package/dist/{chunk-N26UEHI3.js → chunk-PJ4RIUI3.js} +1 -1
  50. package/dist/{chunk-PPIZMPNI.js → chunk-PXYK4MBX.js} +1 -1
  51. package/dist/{chunk-UFQ43KXE.js → chunk-Q36QSFSB.js} +1 -1
  52. package/dist/chunk-Q776YUBD.js +1 -0
  53. package/dist/{chunk-XFLKW6SJ.js → chunk-QENSCK77.js} +1 -1
  54. package/dist/{chunk-TTSDPDRH.js → chunk-QNSIBPWG.js} +1 -1
  55. package/dist/{chunk-U7BPWFOP.js → chunk-QPAOX7P2.js} +1 -1
  56. package/dist/{chunk-V4PUYPTU.js → chunk-QPVUGTDP.js} +1 -1
  57. package/dist/{chunk-LMCICVE7.js → chunk-RE7RAZQ5.js} +1 -1
  58. package/dist/{chunk-HFSISGCJ.js → chunk-RR7V5CK5.js} +1 -1
  59. package/dist/{chunk-RRM4HQG4.js → chunk-RSVNQ2XI.js} +1 -1
  60. package/dist/{chunk-FK55FXKQ.js → chunk-RYCVPQYK.js} +1 -1
  61. package/dist/{chunk-XAXEZI6Z.js → chunk-SFZPFNC6.js} +1 -1
  62. package/dist/chunk-T47SFA5X.js +1 -0
  63. package/dist/{chunk-AXJAGWZB.js → chunk-UVCVJKEN.js} +1 -1
  64. package/dist/{chunk-5XEGRU2R.js → chunk-VCUW2NAP.js} +1 -1
  65. package/dist/chunk-VXNICAVG.js +1 -0
  66. package/dist/{chunk-UQDOOQCM.js → chunk-WIKCYUZC.js} +1 -1
  67. package/dist/{chunk-E5YE25QG.js → chunk-WL5ZWQAS.js} +1 -1
  68. package/dist/{chunk-N4RJ6CN7.js → chunk-WUCACPGC.js} +1 -1
  69. package/dist/{chunk-TWPG3TEQ.js → chunk-X6CF5KTW.js} +5 -5
  70. package/dist/{chunk-LDUJWJ6A.js → chunk-XIOYV5A7.js} +1 -1
  71. package/dist/chunk-XQYAVSUQ.js +1 -0
  72. package/dist/{chunk-NRYVMGJN.js → chunk-XXPWPKTD.js} +1 -1
  73. package/dist/chunk-XZW5ZHFC.js +15 -0
  74. package/dist/{chunk-7ML2UCI7.js → chunk-ZK3ACE4T.js} +1 -1
  75. package/dist/{chunk-IC6VZHE6.js → chunk-ZTQUGAZG.js} +1 -1
  76. package/dist/commands/antigravity/backfill.js +1 -1
  77. package/dist/commands/auth/create-key.js +1 -1
  78. package/dist/commands/auth/login.js +1 -1
  79. package/dist/commands/auth/logout.js +1 -1
  80. package/dist/commands/auth/revoke-key.js +1 -1
  81. package/dist/commands/auth/signup.js +1 -1
  82. package/dist/commands/auth/status.js +1 -1
  83. package/dist/commands/capture/scope.js +1 -1
  84. package/dist/commands/catalog/index.js +1 -1
  85. package/dist/commands/catalog/recommend.js +1 -1
  86. package/dist/commands/crons/list.js +1 -1
  87. package/dist/commands/crons/run.js +1 -1
  88. package/dist/commands/dashboard.js +1 -1
  89. package/dist/commands/diagnostics.js +1 -1
  90. package/dist/commands/eval-targets/create.js +1 -1
  91. package/dist/commands/eval-targets/list.js +1 -1
  92. package/dist/commands/evals/agent.js +1 -1
  93. package/dist/commands/evals/auto-run.js +1 -1
  94. package/dist/commands/evals/benchmark.js +1 -1
  95. package/dist/commands/evals/compare.js +1 -1
  96. package/dist/commands/evals/create.js +1 -1
  97. package/dist/commands/evals/optimize-description.js +1 -1
  98. package/dist/commands/evals/optimize.js +1 -1
  99. package/dist/commands/evals/refine-cases.js +1 -1
  100. package/dist/commands/evals/run.js +1 -1
  101. package/dist/commands/evals/validate-judge.js +1 -1
  102. package/dist/commands/experiments/list.js +1 -1
  103. package/dist/commands/gateway/ensure.js +1 -1
  104. package/dist/commands/hooks/install.js +1 -1
  105. package/dist/commands/hooks/run.js +1 -1
  106. package/dist/commands/hooks/uninstall.js +1 -1
  107. package/dist/commands/instructions/create.js +1 -1
  108. package/dist/commands/instructions/dedupe.js +1 -1
  109. package/dist/commands/instructions/delete.js +1 -1
  110. package/dist/commands/instructions/fork.js +1 -1
  111. package/dist/commands/instructions/get.js +1 -1
  112. package/dist/commands/instructions/list.js +1 -1
  113. package/dist/commands/instructions/promote.js +1 -1
  114. package/dist/commands/instructions/pull.js +1 -1
  115. package/dist/commands/instructions/restore.js +1 -1
  116. package/dist/commands/instructions/retract.js +1 -1
  117. package/dist/commands/instructions/upstream.js +1 -1
  118. package/dist/commands/instructions/versions.js +1 -1
  119. package/dist/commands/launcher.js +1 -1
  120. package/dist/commands/local/down.js +1 -1
  121. package/dist/commands/local/up.js +1 -1
  122. package/dist/commands/org/current.js +1 -1
  123. package/dist/commands/org/list.js +1 -1
  124. package/dist/commands/org/switch.js +1 -1
  125. package/dist/commands/packs/add-instruction.js +1 -1
  126. package/dist/commands/packs/apply.js +1 -1
  127. package/dist/commands/packs/create.js +1 -1
  128. package/dist/commands/packs/fork.js +1 -1
  129. package/dist/commands/packs/get.js +1 -1
  130. package/dist/commands/packs/list.js +1 -1
  131. package/dist/commands/packs/remove-instruction.js +1 -1
  132. package/dist/commands/proxy/env.js +1 -1
  133. package/dist/commands/proxy/logs.js +1 -1
  134. package/dist/commands/proxy/restart.js +1 -1
  135. package/dist/commands/proxy/setup.js +1 -1
  136. package/dist/commands/proxy/start.js +1 -1
  137. package/dist/commands/proxy/status.js +1 -1
  138. package/dist/commands/proxy/stop.js +1 -1
  139. package/dist/commands/research/backfill.js +1 -1
  140. package/dist/commands/research/tail-transcript.js +1 -1
  141. package/dist/commands/service/install.js +1 -1
  142. package/dist/commands/service/status.js +1 -1
  143. package/dist/commands/service/uninstall.js +1 -1
  144. package/dist/commands/sessions/analyze.js +1 -1
  145. package/dist/commands/sessions/delete.js +1 -1
  146. package/dist/commands/sessions/end.js +1 -1
  147. package/dist/commands/sessions/import.js +1 -1
  148. package/dist/commands/sessions/list.js +1 -1
  149. package/dist/commands/sessions/start.js +1 -1
  150. package/dist/commands/setup.js +1 -1
  151. package/dist/commands/skills/export-approved.js +1 -1
  152. package/dist/commands/skills/install.js +1 -1
  153. package/dist/commands/skills/list.js +1 -1
  154. package/dist/commands/skills/publish.js +1 -1
  155. package/dist/commands/skills/search.js +1 -1
  156. package/dist/commands/skills/update.js +1 -1
  157. package/dist/commands/suggestions/accept.js +1 -1
  158. package/dist/commands/suggestions/auto.js +1 -1
  159. package/dist/commands/suggestions/dismiss.js +1 -1
  160. package/dist/commands/suggestions/list.js +1 -1
  161. package/dist/commands/suggestions/refresh.js +1 -1
  162. package/dist/commands/suggestions/undo.js +1 -1
  163. package/dist/dashboard/Dashboard.js +1 -1
  164. package/dist/dashboard/data.js +1 -1
  165. package/dist/dashboard/launcher/LauncherOverlay.js +1 -1
  166. package/dist/dashboard/launcher/api.js +1 -1
  167. package/dist/dashboard/launcher/useLaunchJobs.js +1 -1
  168. package/dist/dashboard/panels/measurement.js +1 -0
  169. package/dist/{dist-NHS7HY5Q.js → dist-GSHUC7UU.js} +1 -1
  170. package/dist/lib/active-org-refresh.js +1 -1
  171. package/dist/lib/agent-loop.js +1 -1
  172. package/dist/lib/antigravity-transcript.js +1 -1
  173. package/dist/lib/api-client.js +1 -1
  174. package/dist/lib/autorun-batch.js +1 -0
  175. package/dist/lib/ensure-api-key.js +1 -1
  176. package/dist/lib/ensure-fresh-token.js +1 -1
  177. package/dist/lib/eval-analyzer.js +1 -1
  178. package/dist/lib/eval-benchmark.js +1 -1
  179. package/dist/lib/eval-candidate-run.js +1 -1
  180. package/dist/lib/eval-case-generator.js +1 -1
  181. package/dist/lib/eval-conversation-handler.js +1 -1
  182. package/dist/lib/eval-executor.js +1 -1
  183. package/dist/lib/eval-grader.js +1 -1
  184. package/dist/lib/eval-meta-judge.js +1 -1
  185. package/dist/lib/eval-resume.js +1 -1
  186. package/dist/lib/eval-run-batch.js +1 -1
  187. package/dist/lib/eval-trigger-tester.js +1 -1
  188. package/dist/lib/evolution-enrolment.js +1 -1
  189. package/dist/lib/harbor-readiness.js +1 -1
  190. package/dist/lib/insights/generation/installed-asks.js +1 -1
  191. package/dist/lib/insights/generation/project-evidence.js +1 -0
  192. package/dist/lib/insights/generation/prompts.js +1 -1
  193. package/dist/lib/insights/nomination/nominate.js +1 -1
  194. package/dist/lib/instruction-proposer.js +1 -1
  195. package/dist/lib/instructions/acceptance/accept-events.js +1 -1
  196. package/dist/lib/instructions/acceptance/accept-hook.js +1 -1
  197. package/dist/lib/instructions/acceptance/hook-install.js +1 -1
  198. package/dist/lib/instructions/acceptance/reverse-applications.js +1 -1
  199. package/dist/lib/instructions/acceptance/suggestion-accept.js +1 -1
  200. package/dist/lib/jobs/handlers/cron-auto-accept-suggestions.js +1 -1
  201. package/dist/lib/jobs/handlers/cron-eval-autorun.js +1 -1
  202. package/dist/lib/jobs/handlers/cron-instruction-evolution.js +1 -1
  203. package/dist/lib/jobs/handlers/cron-instruction-training.js +1 -1
  204. package/dist/lib/jobs/handlers/cron-reconcile-attribution.js +1 -1
  205. package/dist/lib/jobs/handlers/cron-refine-cases.js +1 -1
  206. package/dist/lib/jobs/handlers/cron-refresh-pricing.js +1 -1
  207. package/dist/lib/jobs/handlers/cron-retire-unused-skills.js +1 -1
  208. package/dist/lib/jobs/handlers/cron-suggest-instructions.js +1 -1
  209. package/dist/lib/jobs/handlers/distill-memories.js +1 -1
  210. package/dist/lib/jobs/handlers/harbor-ab-verdict.js +1 -1
  211. package/dist/lib/jobs/handlers/harbor-ab.js +1 -1
  212. package/dist/lib/jobs/handlers/process-changelog.js +1 -1
  213. package/dist/lib/jobs/handlers/process-conversation.js +1 -1
  214. package/dist/lib/jobs/handlers/process-eval.js +1 -1
  215. package/dist/lib/jobs/handlers/process-insights.js +1 -1
  216. package/dist/lib/jobs/handlers/process-judge-review.js +1 -1
  217. package/dist/lib/jobs/handlers/process-launch.js +1 -1
  218. package/dist/lib/jobs/handlers/process-memory-ab.js +1 -1
  219. package/dist/lib/jobs/handlers/process-run-cleanup.js +1 -1
  220. package/dist/lib/jobs/handlers/process-session-goal.js +1 -1
  221. package/dist/lib/jobs/shed-retry.js +1 -1
  222. package/dist/lib/judge-review-runner.js +1 -1
  223. package/dist/lib/llm-client.js +1 -1
  224. package/dist/lib/manual-tasks.js +1 -1
  225. package/dist/lib/measurement-llm.js +1 -1
  226. package/dist/lib/pi-exec.js +1 -1
  227. package/dist/lib/projects/workspace/worktree.js +1 -1
  228. package/dist/lib/refine-cases.js +1 -1
  229. package/dist/lib/research-client.js +1 -1
  230. package/dist/lib/retraction.js +1 -1
  231. package/dist/lib/reviewer-detect.js +1 -1
  232. package/dist/lib/setup-steps.js +1 -1
  233. package/dist/lib/telemetry.js +1 -1
  234. package/dist/lib/terminal-target-heartbeat.js +1 -1
  235. package/dist/lib/work-report.js +1 -1
  236. package/oclif.manifest.json +1 -1
  237. package/package.json +4 -4
  238. package/dist/chunk-74QIUVWY.js +0 -1
  239. package/dist/chunk-E7GQJML3.js +0 -1
  240. package/dist/chunk-FCTFHY3X.js +0 -13
  241. package/dist/chunk-HRJDKAJ4.js +0 -1
  242. package/dist/chunk-INAZLRY5.js +0 -1
  243. package/dist/chunk-OUK2AWEI.js +0 -1
  244. package/dist/chunk-OYAOLJUH.js +0 -1
  245. package/dist/chunk-PUX6P5KC.js +0 -2
  246. package/dist/chunk-SBGXIPRN.js +0 -2
  247. package/dist/chunk-SJKS3PYX.js +0 -109
  248. package/dist/chunk-SPJ73X7A.js +0 -4
  249. package/dist/chunk-UJ7EPLKC.js +0 -1
  250. package/dist/chunk-WSWZPNLG.js +0 -1
  251. /package/dist/{chunk-SE3UKA3M.js → chunk-T75KAEJO.js} +0 -0
@@ -1 +1 @@
1
- import{a,b as n,c as m}from"../../chunk-W2MV25SB.js";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{e as i}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 p}from"@oclif/core";import{printTable as l}from"@oclif/table";var e=class c extends s{static{o(this,"InstructionSummarysList")}static description="List your instructions";static examples=["<%= config.bin %> instructions list","<%= config.bin %> instructions list --json"];static enableJsonFlag=!0;static flags={format:p.string({char:"f",description:"Output format",options:["table","json"],default:"table"})};async run(){let{flags:u}=await this.parse(c);this.requireAuth();let t=await i("/api/instructions");return t.length===0?(this.log("No instructions found. Create one with `rulemetric instructions create`."),t):(u.format==="json"?this.log(JSON.stringify(t,null,2)):l({data:t.map(r=>({Name:n(r.name,40),Scope:m(r.scope),Version:r.version,Tags:(r.tags??[]).join(", "),Updated:a(r.updatedAt)})),columns:["Name","Scope","Version","Tags","Updated"]}),t)}};export{e as default};
1
+ import{a,b as n,c as m}from"../../chunk-W2MV25SB.js";import{a as s}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e as i}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Flags as p}from"@oclif/core";import{printTable as l}from"@oclif/table";var e=class c extends s{static{o(this,"InstructionSummarysList")}static description="List your instructions";static examples=["<%= config.bin %> instructions list","<%= config.bin %> instructions list --json"];static enableJsonFlag=!0;static flags={format:p.string({char:"f",description:"Output format",options:["table","json"],default:"table"})};async run(){let{flags:u}=await this.parse(c);this.requireAuth();let t=await i("/api/instructions");return t.length===0?(this.log("No instructions found. Create one with `rulemetric instructions create`."),t):(u.format==="json"?this.log(JSON.stringify(t,null,2)):l({data:t.map(r=>({Name:n(r.name,40),Scope:m(r.scope),Version:r.version,Tags:(r.tags??[]).join(", "),Updated:a(r.updatedAt)})),columns:["Name","Scope","Version","Tags","Updated"]}),t)}};export{e as default};
@@ -1 +1 @@
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{f as i}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 p,Flags as a}from"@oclif/core";var e=class n extends s{static{t(this,"InstructionsPromote")}static description="Promote an instruction to a higher scope (personal \u2192 team \u2192 org)";static examples=["<%= config.bin %> instructions promote <id> --scope team --ref <team-id>","<%= config.bin %> instructions promote <id> --scope org --ref <org-id>"];static args={id:p.string({description:"ID of the instruction to promote",required:!0})};static flags={scope:a.string({description:"Target scope",required:!0,options:["team","org"]}),ref:a.string({description:"Target scope ref (team or org ID)",required:!0})};async run(){let{args:c,flags:r}=await this.parse(n);this.requireAuth();let o=await i(`/api/instructions/${c.id}/promote`,{scope:r.scope,scopeRef:r.ref});this.log(`Promoted "${o.name}" to ${o.scope} scope`)}};export{e as default};
1
+ import{a as s}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as i}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as t}from"../../chunk-ZLLER3HP.js";import{Args as p,Flags as a}from"@oclif/core";var e=class n extends s{static{t(this,"InstructionsPromote")}static description="Promote an instruction to a higher scope (personal \u2192 team \u2192 org)";static examples=["<%= config.bin %> instructions promote <id> --scope team --ref <team-id>","<%= config.bin %> instructions promote <id> --scope org --ref <org-id>"];static args={id:p.string({description:"ID of the instruction to promote",required:!0})};static flags={scope:a.string({description:"Target scope",required:!0,options:["team","org"]}),ref:a.string({description:"Target scope ref (team or org ID)",required:!0})};async run(){let{args:c,flags:r}=await this.parse(n);this.requireAuth();let o=await i(`/api/instructions/${c.id}/promote`,{scope:r.scope,scopeRef:r.ref});this.log(`Promoted "${o.name}" to ${o.scope} scope`)}};export{e as default};
@@ -1 +1 @@
1
- import{a as r}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 i}from"../../chunk-ZLLER3HP.js";import{Args as a}from"@oclif/core";var e=class o extends r{static{i(this,"InstructionsPull")}static description="Pull upstream changes into a forked instruction";static args={id:a.string({description:"ID of the forked instruction",required:!0})};async run(){let{args:n}=await this.parse(o);this.requireAuth();let t=await s(`/api/instructions/${n.id}/pull-upstream`,{});t.hasConflicts?(this.log("Merge conflicts detected. Resolve in the web UI:"),this.log(t.merged??"")):this.log(`Successfully pulled upstream changes into "${t.instruction?.name}"`)}};export{e as default};
1
+ import{a as r}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as s}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{Args as a}from"@oclif/core";var e=class o extends r{static{i(this,"InstructionsPull")}static description="Pull upstream changes into a forked instruction";static args={id:a.string({description:"ID of the forked instruction",required:!0})};async run(){let{args:n}=await this.parse(o);this.requireAuth();let t=await s(`/api/instructions/${n.id}/pull-upstream`,{});t.hasConflicts?(this.log("Merge conflicts detected. Resolve in the web UI:"),this.log(t.merged??"")):this.log(`Successfully pulled upstream changes into "${t.instruction?.name}"`)}};export{e as default};
@@ -1 +1 @@
1
- import{a as s}from"../../chunk-WLVQJH4E.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 e}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import{Args as d}from"@oclif/core";var t=class n extends o{static{r(this,"InstructionsRestore")}static description="Restore an archived instruction";static examples=["<%= config.bin %> instructions restore <id>"];static args={id:d.string({description:"Instruction ID",required:!0})};async run(){let{args:i}=await this.parse(n);this.requireAuth(),s(i.id,"instruction ID");let a=await e(`/api/instructions/${encodeURIComponent(i.id)}/restore`,{});this.log(`Restored: ${a.name} is active again.`),this.log("If it was removed from CLAUDE.md, re-add it with: rulemetric instructions get "+i.id)}};export{t as default};
1
+ import{a as s}from"../../chunk-WLVQJH4E.js";import{a as o}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as e}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import{Args as d}from"@oclif/core";var t=class n extends o{static{r(this,"InstructionsRestore")}static description="Restore an archived instruction";static examples=["<%= config.bin %> instructions restore <id>"];static args={id:d.string({description:"Instruction ID",required:!0})};async run(){let{args:i}=await this.parse(n);this.requireAuth(),s(i.id,"instruction ID");let a=await e(`/api/instructions/${encodeURIComponent(i.id)}/restore`,{});this.log(`Restored: ${a.name} is active again.`),this.log("If it was removed from CLAUDE.md, re-add it with: rulemetric instructions get "+i.id)}};export{t as default};
@@ -1 +1 @@
1
- import{b as f,d as l,e as p}from"../../chunk-O62OLKQL.js";import"../../chunk-UPFH72PF.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 v,Flags as r}from"@oclif/core";var g=class k extends m{static{u(this,"InstructionsRetract")}static description="Remove an instruction, skill, hook or MCP server from disk (dry-run by default)";static examples=["<%= config.bin %> instructions retract <instruction-id>","<%= config.bin %> instructions retract <instruction-id> --apply","<%= config.bin %> instructions retract --kind skill --target agent-browser","<%= config.bin %> instructions retract --kind mcp --target supabase --apply",'<%= config.bin %> instructions retract --kind hook --target "doomed-tool" --apply'];static args={id:v.string({description:"Instruction ID (omit when using --kind/--target)",required:!1})};static flags={apply:r.boolean({description:"Actually write. Without this, nothing is modified.",default:!1}),force:r.boolean({description:"Proceed without a randomised verdict (observational evidence only)",default:!1}),kind:r.string({description:"Retract something that is not an instruction row",options:["claude-md","memory","skill","hook","mcp"]}),target:r.string({description:"File path, skill name, MCP server name, or hook command substring"}),heading:r.string({description:"Markdown heading to remove (defaults to the instruction name)"})};async run(){let{args:n,flags:i}=await this.parse(k);!n.id&&!(i.kind&&i.target)&&this.error("Provide an instruction ID, or both --kind and --target.");let h=process.cwd(),e,a;if(n.id){this.requireAuth();let t=await c(`/api/instructions/${n.id}`);a=t.name;let o=await this.fetchVerdict(n.id);if(!o&&!i.force){this.log(""),this.log(`No randomised verdict exists for "${t.name}".`),this.log(""),this.log('Every removal signal available today \u2014 including "measured harmful" \u2014 comes from the'),this.log("OBSERVATIONAL path, which is confounded (docs/architecture/effectiveness.md \xA712)."),this.log("Deleting a file on that evidence is the exact conflation \xA713 forbids."),this.log(""),this.log("Re-run with --force if you want to act on observational evidence anyway.");return}o?this.log(`Randomised verdict: ${o.decision} (\u0394 ${o.delta}, n=${o.nTreated}/${o.nControl})`):this.log("\u26A0 Proceeding on OBSERVATIONAL evidence (--force). This signal is confounded.");let s=t.contextIdentity?f(t.contextIdentity):null;if(!s){this.log(""),this.log(`"${t.name}" has no local file behind it (context identity: ${t.contextIdentity??"none"}).`),this.log("Catalog rows live only in the database \u2014 there is nothing on disk to retract.");return}e=l({kind:s.kind,target:s.target,heading:i.heading??t.name,body:s.kind==="claude_md_section"?t.content:void 0,cwd:h})}else{let t={"claude-md":"claude_md_section",memory:"memory_section",skill:"skill_file",hook:"settings_hook",mcp:"mcp_server"};a=i.target,e=l({kind:t[i.kind],target:i.target,heading:i.heading,cwd:h})}if(this.log(""),!e.ok){this.log(`Cannot retract "${a}":`),this.log(""),this.log(e.refusal??"unknown reason"),this.log(""),this.log("Nothing was modified.");return}this.log(`${e.deletesFile?"DELETE":"EDIT"} ${e.path}`),this.log(""),this.log(e.preview),this.log("");for(let t of e.warnings)this.log(`\u26A0 ${t}`);if(!i.apply){this.log(""),this.log("Dry run \u2014 nothing was modified. Re-run with --apply to write.");return}let y=new Date().toISOString().replace(/[:.]/g,"-"),d=p(e,y);d.applied||this.error(`Retraction failed: ${d.error}. Nothing was modified.`),this.log(""),this.log(`\u2713 Retracted from ${e.path}`),this.log(` Backup: ${d.backupPath}`),this.log(" Undo: restore that file, or `git checkout -- <path>` if it is tracked.")}async fetchVerdict(n){try{return(await c(`/api/instruction-verdicts?instructionId=${n}`)).verdicts?.[0]??null}catch{return null}}};export{g as default};
1
+ import{b as f,d as l,e as p}from"../../chunk-FXQS7AEZ.js";import"../../chunk-UPFH72PF.js";import{a as m}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e as c}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as u}from"../../chunk-ZLLER3HP.js";import{Args as v,Flags as r}from"@oclif/core";var g=class k extends m{static{u(this,"InstructionsRetract")}static description="Remove an instruction, skill, hook or MCP server from disk (dry-run by default)";static examples=["<%= config.bin %> instructions retract <instruction-id>","<%= config.bin %> instructions retract <instruction-id> --apply","<%= config.bin %> instructions retract --kind skill --target agent-browser","<%= config.bin %> instructions retract --kind mcp --target supabase --apply",'<%= config.bin %> instructions retract --kind hook --target "doomed-tool" --apply'];static args={id:v.string({description:"Instruction ID (omit when using --kind/--target)",required:!1})};static flags={apply:r.boolean({description:"Actually write. Without this, nothing is modified.",default:!1}),force:r.boolean({description:"Proceed without a randomised verdict (observational evidence only)",default:!1}),kind:r.string({description:"Retract something that is not an instruction row",options:["claude-md","memory","skill","hook","mcp"]}),target:r.string({description:"File path, skill name, MCP server name, or hook command substring"}),heading:r.string({description:"Markdown heading to remove (defaults to the instruction name)"})};async run(){let{args:n,flags:i}=await this.parse(k);!n.id&&!(i.kind&&i.target)&&this.error("Provide an instruction ID, or both --kind and --target.");let h=process.cwd(),e,a;if(n.id){this.requireAuth();let t=await c(`/api/instructions/${n.id}`);a=t.name;let o=await this.fetchVerdict(n.id);if(!o&&!i.force){this.log(""),this.log(`No randomised verdict exists for "${t.name}".`),this.log(""),this.log('Every removal signal available today \u2014 including "measured harmful" \u2014 comes from the'),this.log("OBSERVATIONAL path, which is confounded (docs/architecture/effectiveness.md \xA712)."),this.log("Deleting a file on that evidence is the exact conflation \xA713 forbids."),this.log(""),this.log("Re-run with --force if you want to act on observational evidence anyway.");return}o?this.log(`Randomised verdict: ${o.decision} (\u0394 ${o.delta}, n=${o.nTreated}/${o.nControl})`):this.log("\u26A0 Proceeding on OBSERVATIONAL evidence (--force). This signal is confounded.");let s=t.contextIdentity?f(t.contextIdentity):null;if(!s){this.log(""),this.log(`"${t.name}" has no local file behind it (context identity: ${t.contextIdentity??"none"}).`),this.log("Catalog rows live only in the database \u2014 there is nothing on disk to retract.");return}e=l({kind:s.kind,target:s.target,heading:i.heading??t.name,body:s.kind==="claude_md_section"?t.content:void 0,cwd:h})}else{let t={"claude-md":"claude_md_section",memory:"memory_section",skill:"skill_file",hook:"settings_hook",mcp:"mcp_server"};a=i.target,e=l({kind:t[i.kind],target:i.target,heading:i.heading,cwd:h})}if(this.log(""),!e.ok){this.log(`Cannot retract "${a}":`),this.log(""),this.log(e.refusal??"unknown reason"),this.log(""),this.log("Nothing was modified.");return}this.log(`${e.deletesFile?"DELETE":"EDIT"} ${e.path}`),this.log(""),this.log(e.preview),this.log("");for(let t of e.warnings)this.log(`\u26A0 ${t}`);if(!i.apply){this.log(""),this.log("Dry run \u2014 nothing was modified. Re-run with --apply to write.");return}let y=new Date().toISOString().replace(/[:.]/g,"-"),d=p(e,y);d.applied||this.error(`Retraction failed: ${d.error}. Nothing was modified.`),this.log(""),this.log(`\u2713 Retracted from ${e.path}`),this.log(` Backup: ${d.backupPath}`),this.log(" Undo: restore that file, or `git checkout -- <path>` if it is tracked.")}async fetchVerdict(n){try{return(await c(`/api/instruction-verdicts?instructionId=${n}`)).verdicts?.[0]??null}catch{return null}}};export{g as default};
@@ -1 +1 @@
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{e as s}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{Args as n}from"@oclif/core";var e=class o extends a{static{i(this,"InstructionsUpstream")}static description="Check if a forked instruction has upstream updates";static args={id:n.string({description:"ID of the forked instruction",required:!0})};async run(){let{args:r}=await this.parse(o);this.requireAuth();let t=await s(`/api/instructions/${r.id}/upstream`);t.hasUpdate?(this.log(`Upstream update available: ${t.parentName} is at ${t.upstreamVersion} (you have ${t.currentVersion})`),this.log(`Run: rulemetric instructions pull ${r.id}`)):this.log("Up to date with upstream.")}};export{e as default};
1
+ import{a}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e as s}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{Args as n}from"@oclif/core";var e=class o extends a{static{i(this,"InstructionsUpstream")}static description="Check if a forked instruction has upstream updates";static args={id:n.string({description:"ID of the forked instruction",required:!0})};async run(){let{args:r}=await this.parse(o);this.requireAuth();let t=await s(`/api/instructions/${r.id}/upstream`);t.hasUpdate?(this.log(`Upstream update available: ${t.parentName} is at ${t.upstreamVersion} (you have ${t.currentVersion})`),this.log(`Run: rulemetric instructions pull ${r.id}`)):this.log("Up to date with upstream.")}};export{e as default};
@@ -1 +1 @@
1
- import{a as m}from"../../chunk-WLVQJH4E.js";import{a}from"../../chunk-W2MV25SB.js";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{e as n}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{Args as c}from"@oclif/core";import{printTable as d}from"@oclif/table";var i=class u extends s{static{o(this,"InstructionsVersions")}static description="List version history for an instruction";static examples=["<%= config.bin %> instructions versions <id>"];static enableJsonFlag=!0;static args={id:c.string({description:"Instruction ID",required:!0})};async run(){let{args:e}=await this.parse(u);this.requireAuth(),m(e.id,"instruction ID");let r=await n(`/api/instructions/${encodeURIComponent(e.id)}/versions`);return r.length===0?(this.log("No versions found."),r):(d({data:r.map(t=>({Version:String(t.versionNumber),"Change Summary":t.changeSummary??"(none)","Created At":a(t.createdAt)})),columns:["Version","Change Summary","Created At"]}),r)}};export{i as default};
1
+ import{a as m}from"../../chunk-WLVQJH4E.js";import{a}from"../../chunk-W2MV25SB.js";import{a as s}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Args as c}from"@oclif/core";import{printTable as d}from"@oclif/table";var i=class u extends s{static{o(this,"InstructionsVersions")}static description="List version history for an instruction";static examples=["<%= config.bin %> instructions versions <id>"];static enableJsonFlag=!0;static args={id:c.string({description:"Instruction ID",required:!0})};async run(){let{args:e}=await this.parse(u);this.requireAuth(),m(e.id,"instruction ID");let r=await n(`/api/instructions/${encodeURIComponent(e.id)}/versions`);return r.length===0?(this.log("No versions found."),r):(d({data:r.map(t=>({Version:String(t.versionNumber),"Change Summary":t.changeSummary??"(none)","Created At":a(t.createdAt)})),columns:["Version","Change Summary","Created At"]}),r)}};export{i as default};
@@ -1 +1 @@
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 e}from"../chunk-ZLLER3HP.js";import{Flags as s}from"@oclif/core";var a=class r extends o{static{e(this,"Launcher")}static description="Open the launcher overlay (alias for `dashboard --launcher`)";static examples=["<%= config.bin %> launcher","<%= config.bin %> launcher --period today"];static flags={period:s.string({char:"p",default:"week",options:["today","week","30days","month","all"],description:"Initial time period for the dashboard panels behind the overlay"})};async run(){let{flags:i}=await this.parse(r),{renderDashboard:t}=await import("../dashboard/Dashboard.js");await t(i.period,{openLauncher:!0})}};export{a as default};
1
+ import{a as o}from"../chunk-WUCACPGC.js";import"../chunk-IZTIYR5Q.js";import"../chunk-WL5ZWQAS.js";import"../chunk-KEVDLLHT.js";import"../chunk-DX6IPDED.js";import"../chunk-3AV3GTMP.js";import"../chunk-GIXHG5FK.js";import"../chunk-X6CF5KTW.js";import"../chunk-XQYAVSUQ.js";import"../chunk-PZNWH4VQ.js";import{a as e}from"../chunk-ZLLER3HP.js";import{Flags as s}from"@oclif/core";var a=class r extends o{static{e(this,"Launcher")}static description="Open the launcher overlay (alias for `dashboard --launcher`)";static examples=["<%= config.bin %> launcher","<%= config.bin %> launcher --period today"];static flags={period:s.string({char:"p",default:"week",options:["today","week","30days","month","all"],description:"Initial time period for the dashboard panels behind the overlay"})};async run(){let{flags:i}=await this.parse(r),{renderDashboard:t}=await import("../dashboard/Dashboard.js");await t(i.period,{openLauncher:!0})}};export{a as default};
@@ -1 +1 @@
1
- import{c as t,d as c}from"../../chunk-HRXACKAH.js";import{a as l}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 u}from"@oclif/core";import{execFileSync as m,execSync as f,spawnSync as h}from"node:child_process";import{existsSync as d,rmSync as g}from"node:fs";import{homedir as b}from"node:os";import{join as n}from"node:path";var a=n(b(),"Library","LaunchAgents",`${c}.plist`),s=class p extends l{static{i(this,"LocalDown")}static description="Stop the local RuleMetric server and database stack. Data is preserved (restart with `rulemetric local up`); use --delete-data to also wipe the local database.";static flags={"delete-data":u.boolean({default:!1,description:"Also delete the local database volumes (irreversible)"})};async run(){let{flags:o}=await this.parse(p);if(process.platform==="darwin"&&d(a)){let e=f("id -u",{encoding:"utf-8"}).trim();try{m("launchctl",["bootout",`gui/${e}`,a],{stdio:["ignore","pipe","pipe"]}),this.log("[OK] Stopped the local server")}catch{}g(a,{force:!0})}if(d(n(t,"supabase","config.toml"))){let e=o["delete-data"]?["stop","--no-backup"]:["stop"],r=h("supabase",e,{cwd:t,stdio:"inherit"});r.status!==0?this.warn(`\`supabase ${e.join(" ")}\` exited ${r.status} \u2014 the stack may not have been running.`):this.log(o["delete-data"]?"[OK] Database stack stopped and data deleted":"[OK] Database stack stopped (data preserved)")}else this.log("No local stack configured (nothing to stop). Run: rulemetric local up")}};export{s as default};
1
+ import{c as t,d as c}from"../../chunk-HRXACKAH.js";import{a as l}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{Flags as u}from"@oclif/core";import{execFileSync as m,execSync as f,spawnSync as h}from"node:child_process";import{existsSync as d,rmSync as g}from"node:fs";import{homedir as b}from"node:os";import{join as n}from"node:path";var a=n(b(),"Library","LaunchAgents",`${c}.plist`),s=class p extends l{static{i(this,"LocalDown")}static description="Stop the local RuleMetric server and database stack. Data is preserved (restart with `rulemetric local up`); use --delete-data to also wipe the local database.";static flags={"delete-data":u.boolean({default:!1,description:"Also delete the local database volumes (irreversible)"})};async run(){let{flags:o}=await this.parse(p);if(process.platform==="darwin"&&d(a)){let e=f("id -u",{encoding:"utf-8"}).trim();try{m("launchctl",["bootout",`gui/${e}`,a],{stdio:["ignore","pipe","pipe"]}),this.log("[OK] Stopped the local server")}catch{}g(a,{force:!0})}if(d(n(t,"supabase","config.toml"))){let e=o["delete-data"]?["stop","--no-backup"]:["stop"],r=h("supabase",e,{cwd:t,stdio:"inherit"});r.status!==0?this.warn(`\`supabase ${e.join(" ")}\` exited ${r.status} \u2014 the stack may not have been running.`):this.log(o["delete-data"]?"[OK] Database stack stopped and data deleted":"[OK] Database stack stopped (data preserved)")}else this.log("No local stack configured (nothing to stop). Run: rulemetric local up")}};export{s as default};
@@ -1,4 +1,4 @@
1
- import{a as o,b as O,c as x,d as U}from"../../chunk-XB4OMOSE.js";import{a as E,c as p,d as h,h as m,i as f,j as D,l as C,m as I,n as _}from"../../chunk-HRXACKAH.js";import{a as $}from"../../chunk-V4PUYPTU.js";import{a as A}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import{c as T}from"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import{b as R}from"../../chunk-HAYO6JYI.js";import"../../chunk-3AV3GTMP.js";import{b as S,d}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import{d as L,h as P}from"../../chunk-PZNWH4VQ.js";import{a as w}from"../../chunk-ZLLER3HP.js";import{Flags as l}from"@oclif/core";import{execSync as H,spawnSync as a}from"node:child_process";import{mkdirSync as M}from"node:fs";import{homedir as b}from"node:os";import{dirname as G,join as n}from"node:path";var K=n(b(),"Library","LaunchAgents",`${h}.plist`),g=n(b(),".config","rulemetric","logs"),v=class B extends A{static{w(this,"LocalUp")}static description="Run RuleMetric fully locally: start a local Supabase stack (Docker), apply migrations, and serve the API + dashboard from the @rulemetric/local runtime \u2014 all data on this machine, zero cloud contact. Downloads the runtime package on first run.";static examples=["<%= config.bin %> local up --email you@example.com --password <pw>","<%= config.bin %> local up --port 3000","<%= config.bin %> local up --foreground"];static flags={port:l.integer({char:"p",default:3e3,description:"Local API + dashboard port"}),email:l.string({char:"e",description:"Create the first user with this email (with --password)"}),password:l.string({description:"Password for the first user (min 8 chars)"}),foreground:l.boolean({default:!1,description:"Run the server in this terminal instead of installing a launchd service (works on any OS; skips user provisioning)"}),yes:l.boolean({char:"y",default:!1,description:"Skip the runtime-download confirmation"})};async run(){let{flags:s}=await this.parse(B),t=s.port;!s.foreground&&process.platform!=="darwin"&&this.error(`The managed local service is macOS-only (launchd) for now. On this OS, run the server in the foreground instead:
1
+ import{a as o,b as O,c as x,d as U}from"../../chunk-XB4OMOSE.js";import{a as E,c as p,d as h,h as m,i as f,j as D,l as C,m as I,n as _}from"../../chunk-HRXACKAH.js";import{a as $}from"../../chunk-QPVUGTDP.js";import{a as A}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import{c as T}from"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import{b as R}from"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{b as S,d}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import{d as L,h as P}from"../../chunk-PZNWH4VQ.js";import{a as w}from"../../chunk-ZLLER3HP.js";import{Flags as l}from"@oclif/core";import{execSync as H,spawnSync as a}from"node:child_process";import{mkdirSync as M}from"node:fs";import{homedir as b}from"node:os";import{dirname as G,join as n}from"node:path";var K=n(b(),"Library","LaunchAgents",`${h}.plist`),g=n(b(),".config","rulemetric","logs"),v=class B extends A{static{w(this,"LocalUp")}static description="Run RuleMetric fully locally: start a local Supabase stack (Docker), apply migrations, and serve the API + dashboard from the @rulemetric/local runtime \u2014 all data on this machine, zero cloud contact. Downloads the runtime package on first run.";static examples=["<%= config.bin %> local up --email you@example.com --password <pw>","<%= config.bin %> local up --port 3000","<%= config.bin %> local up --foreground"];static flags={port:l.integer({char:"p",default:3e3,description:"Local API + dashboard port"}),email:l.string({char:"e",description:"Create the first user with this email (with --password)"}),password:l.string({description:"Password for the first user (min 8 chars)"}),foreground:l.boolean({default:!1,description:"Run the server in this terminal instead of installing a launchd service (works on any OS; skips user provisioning)"}),yes:l.boolean({char:"y",default:!1,description:"Skip the runtime-download confirmation"})};async run(){let{flags:s}=await this.parse(B),t=s.port;!s.foreground&&process.platform!=="darwin"&&this.error(`The managed local service is macOS-only (launchd) for now. On this OS, run the server in the foreground instead:
2
2
  rulemetric local up --foreground`),a("docker",["info"],{stdio:"ignore"}).status!==0&&this.error(`Docker is not running (or not installed). The local database runs in Docker.
3
3
  Install/start Docker Desktop (or colima), then re-run: rulemetric local up`),a("supabase",["--version"],{stdio:"ignore"}).status!==0&&this.error(`The Supabase CLI is required to manage the local database stack.
4
4
  Install it: brew install supabase/tap/supabase (or see supabase.com/docs/guides/cli)
@@ -1 +1 @@
1
- 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{a as c,b as t,c as l,d}from"../../chunk-3AV3GTMP.js";import{b as g,e}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import{g as a}from"../../chunk-PZNWH4VQ.js";import{a as s}from"../../chunk-ZLLER3HP.js";var o=class u extends f{static{s(this,"OrgCurrent")}static description="Show the current active organization";static examples=["<%= config.bin %> org current"];async run(){await this.parse(u);let n=process.env.RULEMETRIC_ORG_ID?.trim();if(n){this.log(`${n} (env override)`);return}a()||this.error("Not logged in. Run `rulemetric auth login` to authenticate.");let i=c();if(i&&d(i))try{let r=await e("/api/profile");if(!r.activeOrgId)l(),i=null;else if(r.activeOrgId!==i.orgId){let m=(await e("/api/orgs")).find(p=>p.id===r.activeOrgId);i={orgId:r.activeOrgId,orgSlug:m?.slug,syncedAt:Date.now()},t(i)}else i={...i,syncedAt:Date.now()},t(i)}catch(r){if(!(r instanceof g))throw r}if(!i){this.log("No active organization. Run `rulemetric org switch <slug>`.");return}i.orgSlug?this.log(`${i.orgSlug} (${i.orgId})`):this.log(i.orgId)}};export{o as default};
1
+ import{a as f}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import{a as c,b as t,c as l,d}from"../../chunk-3AV3GTMP.js";import{b as g,e}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import{g as a}from"../../chunk-PZNWH4VQ.js";import{a as s}from"../../chunk-ZLLER3HP.js";var o=class u extends f{static{s(this,"OrgCurrent")}static description="Show the current active organization";static examples=["<%= config.bin %> org current"];async run(){await this.parse(u);let n=process.env.RULEMETRIC_ORG_ID?.trim();if(n){this.log(`${n} (env override)`);return}a()||this.error("Not logged in. Run `rulemetric auth login` to authenticate.");let i=c();if(i&&d(i))try{let r=await e("/api/profile");if(!r.activeOrgId)l(),i=null;else if(r.activeOrgId!==i.orgId){let m=(await e("/api/orgs")).find(p=>p.id===r.activeOrgId);i={orgId:r.activeOrgId,orgSlug:m?.slug,syncedAt:Date.now()},t(i)}else i={...i,syncedAt:Date.now()},t(i)}catch(r){if(!(r instanceof g))throw r}if(!i){this.log("No active organization. Run `rulemetric org switch <slug>`.");return}i.orgSlug?this.log(`${i.orgSlug} (${i.orgId})`):this.log(i.orgId)}};export{o as default};
@@ -1 +1 @@
1
- import{a as d}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import{a as c}from"../../chunk-3AV3GTMP.js";import{e as g}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as s}from"../../chunk-ZLLER3HP.js";var p=process.env.RULEMETRIC_WEB_URL??"https://rulemetric.com",o=class l extends d{static{s(this,"OrgList")}static description="List organizations the current user is a member of";static examples=["<%= config.bin %> org list"];async run(){await this.parse(l),this.requireAuth();let e=await g("/api/orgs");if(e.length===0){this.log("No organizations."),this.log(`Create one in the web UI: ${p}`);return}let i=c()?.orgId??null,r=Math.max(4,...e.map(t=>t.slug.length)),a=Math.max(4,...e.map(t=>t.name.length)),n=Math.max(4,...e.map(t=>t.role.length)),m=` ACTIVE ${"SLUG".padEnd(r)} ${"NAME".padEnd(a)} ${"ROLE".padEnd(n)}`;this.log(m);for(let t of e){let h=t.id===i?"*":" ";this.log(` ${h} ${t.slug.padEnd(r)} ${t.name.padEnd(a)} ${t.role.padEnd(n)}`)}i||(this.log(""),this.log("No active organization. Run `rulemetric org switch <slug>` to set one."))}};export{o as default};
1
+ import{a as d}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import{a as c}from"../../chunk-3AV3GTMP.js";import{e as g}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as s}from"../../chunk-ZLLER3HP.js";var p=process.env.RULEMETRIC_WEB_URL??"https://rulemetric.com",o=class l extends d{static{s(this,"OrgList")}static description="List organizations the current user is a member of";static examples=["<%= config.bin %> org list"];async run(){await this.parse(l),this.requireAuth();let e=await g("/api/orgs");if(e.length===0){this.log("No organizations."),this.log(`Create one in the web UI: ${p}`);return}let i=c()?.orgId??null,r=Math.max(4,...e.map(t=>t.slug.length)),a=Math.max(4,...e.map(t=>t.name.length)),n=Math.max(4,...e.map(t=>t.role.length)),m=` ACTIVE ${"SLUG".padEnd(r)} ${"NAME".padEnd(a)} ${"ROLE".padEnd(n)}`;this.log(m);for(let t of e){let h=t.id===i?"*":" ";this.log(` ${h} ${t.slug.padEnd(r)} ${t.name.padEnd(a)} ${t.role.padEnd(n)}`)}i||(this.log(""),this.log("No active organization. Run `rulemetric org switch <slug>` to set one."))}};export{o as default};
@@ -1 +1 @@
1
- import{a as l}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import"../../chunk-HAYO6JYI.js";import{b as a,c as g}from"../../chunk-3AV3GTMP.js";import{e as s,h as e}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{Args as d,Flags as m}from"@oclif/core";var t=class c extends l{static{o(this,"OrgSwitch")}static description="Switch the active organization";static examples=["<%= config.bin %> org switch acme","<%= config.bin %> org switch --clear"];static args={slug:d.string({description:"Organization slug to switch to",required:!1})};static flags={clear:m.boolean({description:"Clear the active organization (personal mode)",default:!1})};async run(){let{args:i,flags:n}=await this.parse(c);if(this.requireAuth(),n.clear){await e("/api/profile",{activeOrgId:null}),g(),this.log("Active org cleared (personal mode).");return}i.slug||this.error("Slug is required. Run `rulemetric org list` to see your orgs, or use --clear to unset.");let r=(await s("/api/orgs")).find(u=>u.slug===i.slug);r||this.error(`Not a member of "${i.slug}". Run \`rulemetric org list\` to see your orgs.`),await e("/api/profile",{activeOrgId:r.id}),a({orgId:r.id,orgSlug:r.slug,syncedAt:Date.now()}),this.log(`Active org: ${r.slug}`)}};export{t as default};
1
+ import{a as l}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import{b as a,c as g}from"../../chunk-3AV3GTMP.js";import{e as s,h as e}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Args as d,Flags as m}from"@oclif/core";var t=class c extends l{static{o(this,"OrgSwitch")}static description="Switch the active organization";static examples=["<%= config.bin %> org switch acme","<%= config.bin %> org switch --clear"];static args={slug:d.string({description:"Organization slug to switch to",required:!1})};static flags={clear:m.boolean({description:"Clear the active organization (personal mode)",default:!1})};async run(){let{args:i,flags:n}=await this.parse(c);if(this.requireAuth(),n.clear){await e("/api/profile",{activeOrgId:null}),g(),this.log("Active org cleared (personal mode).");return}i.slug||this.error("Slug is required. Run `rulemetric org list` to see your orgs, or use --clear to unset.");let r=(await s("/api/orgs")).find(u=>u.slug===i.slug);r||this.error(`Not a member of "${i.slug}". Run \`rulemetric org list\` to see your orgs.`),await e("/api/profile",{activeOrgId:r.id}),a({orgId:r.id,orgSlug:r.slug,syncedAt:Date.now()}),this.log(`Active org: ${r.slug}`)}};export{t as default};
@@ -1 +1 @@
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{f as s}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import{Args as a}from"@oclif/core";var i=class n extends o{static{r(this,"PacksAddInstruction")}static description="Add an instruction to a pack";static examples=["<%= config.bin %> packs add-instruction <pack-id> <instruction-id>"];static args={packId:a.string({description:"Pack ID",required:!0}),instructionId:a.string({description:"Instruction ID",required:!0})};async run(){let{args:t}=await this.parse(n);this.requireAuth(),await s(`/api/packs/${t.packId}/instructions`,{instructionId:t.instructionId}),this.log("Instruction added to pack.")}};export{i as default};
1
+ import{a as o}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as s}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import{Args as a}from"@oclif/core";var i=class n extends o{static{r(this,"PacksAddInstruction")}static description="Add an instruction to a pack";static examples=["<%= config.bin %> packs add-instruction <pack-id> <instruction-id>"];static args={packId:a.string({description:"Pack ID",required:!0}),instructionId:a.string({description:"Instruction ID",required:!0})};async run(){let{args:t}=await this.parse(n);this.requireAuth(),await s(`/api/packs/${t.packId}/instructions`,{instructionId:t.instructionId}),this.log("Instruction added to pack.")}};export{i as default};
@@ -1 +1 @@
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{f as i}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import{Args as c,Flags as l}from"@oclif/core";var t=class o extends s{static{r(this,"PacksApply")}static description="Apply a pack to a project (bulk-link all instructions)";static examples=["<%= config.bin %> packs apply <pack-id> --project <project-id>"];static args={id:c.string({description:"Pack ID",required:!0})};static flags={project:l.string({char:"p",description:"Project ID",required:!0})};async run(){let{args:a,flags:p}=await this.parse(o);this.requireAuth();let e=await i(`/api/packs/${a.id}/apply`,{projectId:p.project});this.log(`Applied pack: ${e.linked} of ${e.total} instructions linked to project.`)}};export{t as default};
1
+ import{a as s}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as i}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as r}from"../../chunk-ZLLER3HP.js";import{Args as c,Flags as l}from"@oclif/core";var t=class o extends s{static{r(this,"PacksApply")}static description="Apply a pack to a project (bulk-link all instructions)";static examples=["<%= config.bin %> packs apply <pack-id> --project <project-id>"];static args={id:c.string({description:"Pack ID",required:!0})};static flags={project:l.string({char:"p",description:"Project ID",required:!0})};async run(){let{args:a,flags:p}=await this.parse(o);this.requireAuth();let e=await i(`/api/packs/${a.id}/apply`,{projectId:p.project});this.log(`Applied pack: ${e.linked} of ${e.total} instructions linked to project.`)}};export{t as default};
@@ -1 +1 @@
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{f 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 t}from"@oclif/core";var i=class c extends o{static{a(this,"PacksCreate")}static description="Create a new instruction pack";static examples=['<%= config.bin %> packs create --name "Security Pack" --description "Security-focused instructions"'];static flags={name:t.string({char:"n",description:"Pack name",required:!0}),description:t.string({char:"d",description:"Pack description",required:!0}),scope:t.string({char:"s",description:"Pack scope",options:["org","team","personal"],default:"personal"}),tags:t.string({char:"t",description:"Comma-separated tags"})};async run(){let{flags:e}=await this.parse(c);this.requireAuth();let r={name:e.name,description:e.description,scope:e.scope};e.tags&&(r.tags=e.tags.split(",").map(p=>p.trim()));let s=await n("/api/packs",r);this.log(`Created pack: ${s.name} (${s.id})`)}};export{i as default};
1
+ import{a as o}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as n}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import{Flags as t}from"@oclif/core";var i=class c extends o{static{a(this,"PacksCreate")}static description="Create a new instruction pack";static examples=['<%= config.bin %> packs create --name "Security Pack" --description "Security-focused instructions"'];static flags={name:t.string({char:"n",description:"Pack name",required:!0}),description:t.string({char:"d",description:"Pack description",required:!0}),scope:t.string({char:"s",description:"Pack scope",options:["org","team","personal"],default:"personal"}),tags:t.string({char:"t",description:"Comma-separated tags"})};async run(){let{flags:e}=await this.parse(c);this.requireAuth();let r={name:e.name,description:e.description,scope:e.scope};e.tags&&(r.tags=e.tags.split(",").map(p=>p.trim()));let s=await n("/api/packs",r);this.log(`Created pack: ${s.name} (${s.id})`)}};export{i as default};
@@ -1 +1 @@
1
- import{a as e}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 o}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 p}from"@oclif/core";var r=class s extends e{static{t(this,"PacksFork")}static description="Fork a pack to your personal scope";static examples=["<%= config.bin %> packs fork <pack-id>"];static args={id:p.string({description:"ID of the pack to fork",required:!0})};async run(){let{args:a}=await this.parse(s);this.requireAuth();let i=await o(`/api/packs/${a.id}/fork`,{});this.log(`Forked pack: ${i.name} (${i.id})`)}};export{r as default};
1
+ import{a as e}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as o}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as t}from"../../chunk-ZLLER3HP.js";import{Args as p}from"@oclif/core";var r=class s extends e{static{t(this,"PacksFork")}static description="Fork a pack to your personal scope";static examples=["<%= config.bin %> packs fork <pack-id>"];static args={id:p.string({description:"ID of the pack to fork",required:!0})};async run(){let{args:a}=await this.parse(s);this.requireAuth();let i=await o(`/api/packs/${a.id}/fork`,{});this.log(`Forked pack: ${i.name} (${i.id})`)}};export{r as default};
@@ -1,3 +1,3 @@
1
- import{b as a,c as r}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}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{Args as g}from"@oclif/core";import{printTable as m}from"@oclif/table";var s=class c extends o{static{n(this,"PacksGet")}static description="Get pack detail with instruction list";static examples=["<%= config.bin %> packs get <pack-id>"];static args={id:g.string({description:"Pack ID",required:!0})};async run(){let{args:p}=await this.parse(c);this.requireAuth();let i=await e(`/api/packs/${p.id}`);this.log(`
1
+ import{b as a,c as r}from"../../chunk-W2MV25SB.js";import{a as o}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{Args as g}from"@oclif/core";import{printTable as m}from"@oclif/table";var s=class c extends o{static{n(this,"PacksGet")}static description="Get pack detail with instruction list";static examples=["<%= config.bin %> packs get <pack-id>"];static args={id:g.string({description:"Pack ID",required:!0})};async run(){let{args:p}=await this.parse(c);this.requireAuth();let i=await e(`/api/packs/${p.id}`);this.log(`
2
2
  Pack: ${i.name}`),this.log(`Description: ${i.description}`),this.log(`Scope: ${r(i.scope)} | Version: ${i.version} | Tier: ${i.tier}`),this.log(`Tags: ${(i.tags??[]).join(", ")||"(none)"}`),this.log(`Instructions: ${i.instructionCount}
3
3
  `),i.instructions.length>0&&m({data:i.instructions.map(t=>({"#":String(t.position),Name:a(t.name,40),Scope:r(t.scope),Version:t.version})),columns:["#","Name","Scope","Version"]})}};export{s as default};
@@ -1 +1 @@
1
- import{a as o,b as n,c}from"../../chunk-W2MV25SB.js";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{e as a}from"../../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 p}from"@oclif/core";import{printTable as g}from"@oclif/table";var e=class m extends s{static{i(this,"PacksList")}static description="List your instruction packs";static examples=["<%= config.bin %> packs list","<%= config.bin %> packs list --json"];static enableJsonFlag=!0;static flags={format:p.string({char:"f",description:"Output format",options:["table","json"],default:"table"})};async run(){let{flags:u}=await this.parse(m);this.requireAuth();let r=await a("/api/packs");return r.length===0?(this.log("No packs found. Create one with `rulemetric packs create`."),r):(u.format==="json"?this.log(JSON.stringify(r,null,2)):g({data:r.map(t=>({Name:n(t.name,40),Scope:c(t.scope),Tier:t.tier,Count:String(t.instructionCount),Tags:(t.tags??[]).join(", "),Updated:o(t.updatedAt)})),columns:["Name","Scope","Tier","Count","Tags","Updated"]}),r)}};export{e as default};
1
+ import{a as o,b as n,c}from"../../chunk-W2MV25SB.js";import{a as s}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e as a}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{Flags as p}from"@oclif/core";import{printTable as g}from"@oclif/table";var e=class m extends s{static{i(this,"PacksList")}static description="List your instruction packs";static examples=["<%= config.bin %> packs list","<%= config.bin %> packs list --json"];static enableJsonFlag=!0;static flags={format:p.string({char:"f",description:"Output format",options:["table","json"],default:"table"})};async run(){let{flags:u}=await this.parse(m);this.requireAuth();let r=await a("/api/packs");return r.length===0?(this.log("No packs found. Create one with `rulemetric packs create`."),r):(u.format==="json"?this.log(JSON.stringify(r,null,2)):g({data:r.map(t=>({Name:n(t.name,40),Scope:c(t.scope),Tier:t.tier,Count:String(t.instructionCount),Tags:(t.tags??[]).join(", "),Updated:o(t.updatedAt)})),columns:["Name","Scope","Tier","Count","Tags","Updated"]}),r)}};export{e as default};
@@ -1 +1 @@
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{i as e}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 o}from"@oclif/core";var i=class a extends s{static{t(this,"PacksRemoveInstruction")}static description="Remove an instruction from a pack";static examples=["<%= config.bin %> packs remove-instruction <pack-id> <instruction-id>"];static args={packId:o.string({description:"Pack ID",required:!0}),instructionId:o.string({description:"Instruction ID",required:!0})};async run(){let{args:r}=await this.parse(a);this.requireAuth(),await e(`/api/packs/${r.packId}/instructions/${r.instructionId}`),this.log("Instruction removed from pack.")}};export{i as default};
1
+ import{a as s}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{i as e}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as t}from"../../chunk-ZLLER3HP.js";import{Args as o}from"@oclif/core";var i=class a extends s{static{t(this,"PacksRemoveInstruction")}static description="Remove an instruction from a pack";static examples=["<%= config.bin %> packs remove-instruction <pack-id> <instruction-id>"];static args={packId:o.string({description:"Pack ID",required:!0}),instructionId:o.string({description:"Instruction ID",required:!0})};async run(){let{args:r}=await this.parse(a);this.requireAuth(),await e(`/api/packs/${r.packId}/instructions/${r.instructionId}`),this.log("Instruction removed from pack.")}};export{i as default};
@@ -1,3 +1,3 @@
1
- import{e as f}from"../../chunk-QWCEZEDO.js";import"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.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 m}from"../../chunk-ZLLER3HP.js";import{Flags as i}from"@oclif/core";import{existsSync as v}from"node:fs";import{homedir as x}from"node:os";import{join as g}from"node:path";var o=g(x(),".mitmproxy","mitmproxy-ca-cert.pem"),l=class d extends h{static{m(this,"ProxyEnv")}static description="Print shell env vars to route any client through the RuleMetric proxy";static examples=["<%= config.bin %> proxy env","<%= config.bin %> proxy env --shell fish",'eval "$(rulemetric proxy env)"',"rulemetric proxy env --python"];static flags={shell:i.string({char:"s",default:"posix",description:"Shell format (posix, fish, powershell)",options:["posix","fish","powershell"]}),python:i.boolean({default:!1,description:"Include Python-specific env vars (REQUESTS_CA_BUNDLE, SSL_CERT_FILE)"}),node:i.boolean({default:!1,description:"Include Node.js-specific env vars (NODE_EXTRA_CA_CERTS)"}),all:i.boolean({default:!1,description:"Include env vars for all runtimes"}),vscode:i.boolean({default:!1,description:"Output VS Code settings.json snippet for Copilot proxy"})};async run(){let{flags:s}=await this.parse(d),y=s.shell,c=s.all,a=s.python||c,p=s.node||c,u=v(o),n=`http://localhost:${f}`;if(u||(this.warn(`CA certificate not found at ${o}
1
+ import{e as f}from"../../chunk-QWCEZEDO.js";import"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import{a as h}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as m}from"../../chunk-ZLLER3HP.js";import{Flags as i}from"@oclif/core";import{existsSync as v}from"node:fs";import{homedir as x}from"node:os";import{join as g}from"node:path";var o=g(x(),".mitmproxy","mitmproxy-ca-cert.pem"),l=class d extends h{static{m(this,"ProxyEnv")}static description="Print shell env vars to route any client through the RuleMetric proxy";static examples=["<%= config.bin %> proxy env","<%= config.bin %> proxy env --shell fish",'eval "$(rulemetric proxy env)"',"rulemetric proxy env --python"];static flags={shell:i.string({char:"s",default:"posix",description:"Shell format (posix, fish, powershell)",options:["posix","fish","powershell"]}),python:i.boolean({default:!1,description:"Include Python-specific env vars (REQUESTS_CA_BUNDLE, SSL_CERT_FILE)"}),node:i.boolean({default:!1,description:"Include Node.js-specific env vars (NODE_EXTRA_CA_CERTS)"}),all:i.boolean({default:!1,description:"Include env vars for all runtimes"}),vscode:i.boolean({default:!1,description:"Output VS Code settings.json snippet for Copilot proxy"})};async run(){let{flags:s}=await this.parse(d),y=s.shell,c=s.all,a=s.python||c,p=s.node||c,u=v(o),n=`http://localhost:${f}`;if(u||(this.warn(`CA certificate not found at ${o}
2
2
  Run 'rulemetric hooks install' or 'rulemetric proxy setup' to generate it.`),this.exit(1)),s.vscode){let e={"http.proxy":n,"http.proxyStrictSSL":u,"github.copilot.advanced":{"debug.overrideProxyUrl":n}};this.log(JSON.stringify(e,null,2));return}let r=[{key:"HTTPS_PROXY",value:n,comment:"Route HTTPS through RuleMetric gateway"},{key:"HTTP_PROXY",value:n,comment:"Route HTTP through RuleMetric gateway"}];r.push({key:"SSL_CERT_FILE",value:o,comment:"Trust mitmproxy CA (generic \u2014 works with most libraries)"}),(p||!a&&!p)&&r.push({key:"NODE_EXTRA_CA_CERTS",value:o,comment:"Trust mitmproxy CA (Node.js)"}),a&&(r.push({key:"REQUESTS_CA_BUNDLE",value:o,comment:"Trust mitmproxy CA (Python requests / httpx)"}),r.push({key:"CURL_CA_BUNDLE",value:o,comment:"Trust mitmproxy CA (curl / libcurl)"}));let t=[];for(let e of r)switch(y){case"fish":e.comment&&t.push(`# ${e.comment}`),t.push(`set -gx ${e.key} "${e.value}"`);break;case"powershell":e.comment&&t.push(`# ${e.comment}`),t.push(`$env:${e.key} = "${e.value}"`);break;default:e.comment&&t.push(`# ${e.comment}`),t.push(`export ${e.key}="${e.value}"`)}this.log(t.join(`
3
3
  `))}};export{l as default};
@@ -1,3 +1,3 @@
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"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{Flags as a}from"@oclif/core";import{existsSync as f,readFileSync as p}from"node:fs";import{homedir as x}from"node:os";import{join as n}from"node:path";import{spawn as m}from"node:child_process";var g=n(x(),".config","rulemetric"),s=n(g,"proxy.log"),d=n(g,"proxy.pid"),h="rulemetric-proxy",r=class u extends c{static{l(this,"ProxyLogs")}static description="View context capture proxy logs";static examples=["<%= config.bin %> proxy logs","<%= config.bin %> proxy logs --follow","<%= config.bin %> proxy logs --lines 50"];static flags={follow:a.boolean({char:"f",default:!1,description:"Follow log output (like tail -f)"}),lines:a.integer({char:"n",default:30,description:"Number of lines to show"})};async run(){let{flags:i}=await this.parse(u);if(f(d)&&p(d,"utf-8").trim().startsWith("docker:")){let o=["logs"];i.follow&&o.push("-f"),o.push("--tail",String(i.lines),h);let t=m("docker",o,{stdio:"inherit"});process.on("SIGINT",()=>{t.kill(),process.exit(0)}),await new Promise(e=>{t.on("exit",()=>e())});return}if(!f(s)){this.log(`No proxy log file found at ${s}`),this.log("Start the proxy first: rulemetric proxy start");return}if(i.follow){let o=m("tail",["-f","-n",String(i.lines),s],{stdio:"inherit"});process.on("SIGINT",()=>{o.kill(),process.exit(0)}),await new Promise(t=>{o.on("exit",()=>t())})}else{let e=p(s,"utf-8").split(`
1
+ import{a as c}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{Flags as a}from"@oclif/core";import{existsSync as f,readFileSync as p}from"node:fs";import{homedir as x}from"node:os";import{join as n}from"node:path";import{spawn as m}from"node:child_process";var g=n(x(),".config","rulemetric"),s=n(g,"proxy.log"),d=n(g,"proxy.pid"),h="rulemetric-proxy",r=class u extends c{static{l(this,"ProxyLogs")}static description="View context capture proxy logs";static examples=["<%= config.bin %> proxy logs","<%= config.bin %> proxy logs --follow","<%= config.bin %> proxy logs --lines 50"];static flags={follow:a.boolean({char:"f",default:!1,description:"Follow log output (like tail -f)"}),lines:a.integer({char:"n",default:30,description:"Number of lines to show"})};async run(){let{flags:i}=await this.parse(u);if(f(d)&&p(d,"utf-8").trim().startsWith("docker:")){let o=["logs"];i.follow&&o.push("-f"),o.push("--tail",String(i.lines),h);let t=m("docker",o,{stdio:"inherit"});process.on("SIGINT",()=>{t.kill(),process.exit(0)}),await new Promise(e=>{t.on("exit",()=>e())});return}if(!f(s)){this.log(`No proxy log file found at ${s}`),this.log("Start the proxy first: rulemetric proxy start");return}if(i.follow){let o=m("tail",["-f","-n",String(i.lines),s],{stdio:"inherit"});process.on("SIGINT",()=>{o.kill(),process.exit(0)}),await new Promise(t=>{o.on("exit",()=>t())})}else{let e=p(s,"utf-8").split(`
2
2
  `).slice(-i.lines).join(`
3
3
  `);this.log(e)}}};export{r as default};
@@ -1 +1 @@
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"../../chunk-PZNWH4VQ.js";import{a as e}from"../../chunk-ZLLER3HP.js";import{Flags as i}from"@oclif/core";import{setTimeout as p}from"node:timers/promises";var o=class a extends s{static{e(this,"ProxyRestart")}static description="Restart the context capture proxy (stop + start)";static examples=["<%= config.bin %> proxy restart"];static flags={port:i.integer({char:"p",description:"Proxy listen port"}),docker:i.boolean({char:"d",default:!1,description:"Run in Docker mode"})};async run(){let{flags:t}=await this.parse(a);await this.config.runCommand("proxy:stop",[]),await p(500);let r=["--skip-checks"];t.docker&&r.push("--docker"),t.port&&r.push("--port",String(t.port)),await this.config.runCommand("proxy:start",r)}};export{o as default};
1
+ import{a as s}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as e}from"../../chunk-ZLLER3HP.js";import{Flags as i}from"@oclif/core";import{setTimeout as p}from"node:timers/promises";var o=class a extends s{static{e(this,"ProxyRestart")}static description="Restart the context capture proxy (stop + start)";static examples=["<%= config.bin %> proxy restart"];static flags={port:i.integer({char:"p",description:"Proxy listen port"}),docker:i.boolean({char:"d",default:!1,description:"Run in Docker mode"})};async run(){let{flags:t}=await this.parse(a);await this.config.runCommand("proxy:stop",[]),await p(500);let r=["--skip-checks"];t.docker&&r.push("--docker"),t.port&&r.push("--port",String(t.port)),await this.config.runCommand("proxy:start",r)}};export{o as default};
@@ -1,4 +1,4 @@
1
- import{a as g}from"../../chunk-PJ3WHQ67.js";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{g as x}from"../../chunk-PZNWH4VQ.js";import{a as h}from"../../chunk-ZLLER3HP.js";import{Flags as _}from"@oclif/core";import{execSync as P,spawnSync as m}from"node:child_process";import{existsSync as f,readFileSync as y,appendFileSync as T,writeFileSync as k,mkdirSync as v}from"node:fs";import{homedir as d}from"node:os";import{dirname as E,join as u}from"node:path";var c=u(d(),".mitmproxy","mitmproxy-ca-cert.pem"),$=u(d(),".config","rulemetric"),A=8787,R=class C extends S{static{h(this,"ProxySetup")}static description="Set up context capture proxy (installs mitmproxy, configures shell)";static examples=["<%= config.bin %> proxy setup","<%= config.bin %> proxy setup --shell zsh","<%= config.bin %> proxy setup --check"];static flags={shell:_.string({description:"Shell to configure (auto-detected if omitted)",options:["zsh","bash","fish","powershell"]}),port:_.integer({char:"p",default:A,description:"Proxy listen port"}),check:_.boolean({description:"Only check prerequisites, do not install anything",default:!1})};async run(){let{flags:e}=await this.parse(C),i=e.check,t=e.port;this.log("RuleMetric Proxy Setup"),this.log(`=====================
1
+ import{a as g}from"../../chunk-PJ3WHQ67.js";import{a as S}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import{g as x}from"../../chunk-PZNWH4VQ.js";import{a as h}from"../../chunk-ZLLER3HP.js";import{Flags as _}from"@oclif/core";import{execSync as P,spawnSync as m}from"node:child_process";import{existsSync as f,readFileSync as y,appendFileSync as T,writeFileSync as k,mkdirSync as v}from"node:fs";import{homedir as d}from"node:os";import{dirname as E,join as u}from"node:path";var c=u(d(),".mitmproxy","mitmproxy-ca-cert.pem"),$=u(d(),".config","rulemetric"),A=8787,R=class C extends S{static{h(this,"ProxySetup")}static description="Set up context capture proxy (installs mitmproxy, configures shell)";static examples=["<%= config.bin %> proxy setup","<%= config.bin %> proxy setup --shell zsh","<%= config.bin %> proxy setup --check"];static flags={shell:_.string({description:"Shell to configure (auto-detected if omitted)",options:["zsh","bash","fish","powershell"]}),port:_.integer({char:"p",default:A,description:"Proxy listen port"}),check:_.boolean({description:"Only check prerequisites, do not install anything",default:!1})};async run(){let{flags:e}=await this.parse(C),i=e.check,t=e.port;this.log("RuleMetric Proxy Setup"),this.log(`=====================
2
2
  `);let l=[await this.checkAuth(),await this.checkMitmproxy(),await this.checkCACert(),await this.checkHooks(),this.checkShellEnv(t)],r=!0;for(let n of l){let p=n.ok?"[OK]":"[!!]";this.log(`${p} ${n.name}: ${n.message}`),n.ok||(r=!1)}if(r){this.log("\nAll checks passed. Run `rulemetric proxy start` to begin capturing.");return}if(i){this.log("\nSome checks failed. Run `rulemetric proxy setup` (without --check) to fix.");return}this.log(`
3
3
  Fixing issues...
4
4
  `);for(let n of l){if(n.ok||!n.fix)continue;this.log(`Fixing: ${n.name}...`),await n.fix()?this.log(` Fixed.
@@ -1,4 +1,4 @@
1
- import{a as K}from"../../chunk-OMXUK4M6.js";import{b as F,d as N}from"../../chunk-SZ62CP55.js";import{a as U}from"../../chunk-PJ3WHQ67.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"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import{g as $}from"../../chunk-PZNWH4VQ.js";import{a as u}from"../../chunk-ZLLER3HP.js";import{Flags as _}from"@oclif/core";import{execSync as H,spawn as q,spawnSync as m}from"node:child_process";import{appendFileSync as G,existsSync as l,mkdirSync as P,openSync as V,readFileSync as b,writeFileSync as Y}from"node:fs";import{createRequire as W}from"node:module";import{homedir as x}from"node:os";import{dirname as A,join as c,resolve as f}from"node:path";import{fileURLToPath as X}from"node:url";var g=A(X(import.meta.url)),J=8788,S=c(x(),".config","rulemetric"),T=c(S,"proxy.pid"),D=c(S,"proxy.log"),w="rulemetric/proxy",v="rulemetric-proxy";function j(s,o){try{let d=W(import.meta.url).resolve(`@rulemetric/proxy/${s}`);if(l(d))return d}catch{}for(let t of o)if(l(t))return t;return null}u(j,"resolveProxyFile");function B(){let s=[f(g,"../../../../../packages/proxy/addon/rulemetric_addon.py"),f(g,"../../../node_modules/@rulemetric/proxy/addon/rulemetric_addon.py"),f(g,"../../../../../node_modules/@rulemetric/proxy/addon/rulemetric_addon.py")],o=j("addon/rulemetric_addon.py",s);if(o)return o;throw new Error(`Could not find rulemetric_addon.py. Is @rulemetric/proxy installed?
1
+ import{a as K}from"../../chunk-OMXUK4M6.js";import{b as F,d as N}from"../../chunk-SZ62CP55.js";import{a as U}from"../../chunk-PJ3WHQ67.js";import{a as M}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import{g as $}from"../../chunk-PZNWH4VQ.js";import{a as u}from"../../chunk-ZLLER3HP.js";import{Flags as _}from"@oclif/core";import{execSync as H,spawn as q,spawnSync as m}from"node:child_process";import{appendFileSync as G,existsSync as l,mkdirSync as P,openSync as V,readFileSync as b,writeFileSync as Y}from"node:fs";import{createRequire as W}from"node:module";import{homedir as x}from"node:os";import{dirname as A,join as c,resolve as f}from"node:path";import{fileURLToPath as X}from"node:url";var g=A(X(import.meta.url)),J=8788,S=c(x(),".config","rulemetric"),T=c(S,"proxy.pid"),D=c(S,"proxy.log"),w="rulemetric/proxy",v="rulemetric-proxy";function j(s,o){try{let d=W(import.meta.url).resolve(`@rulemetric/proxy/${s}`);if(l(d))return d}catch{}for(let t of o)if(l(t))return t;return null}u(j,"resolveProxyFile");function B(){let s=[f(g,"../../../../../packages/proxy/addon/rulemetric_addon.py"),f(g,"../../../node_modules/@rulemetric/proxy/addon/rulemetric_addon.py"),f(g,"../../../../../node_modules/@rulemetric/proxy/addon/rulemetric_addon.py")],o=j("addon/rulemetric_addon.py",s);if(o)return o;throw new Error(`Could not find rulemetric_addon.py. Is @rulemetric/proxy installed?
2
2
  Searched (after module resolution):
3
3
  `+s.map(t=>` ${t}`).join(`
4
4
  `))}u(B,"findAddonPath");function z(){let s=[f(g,"../../../../../packages/proxy/Dockerfile"),f(g,"../../../node_modules/@rulemetric/proxy/Dockerfile"),f(g,"../../../../../node_modules/@rulemetric/proxy/Dockerfile")],o=j("Dockerfile",s);if(o)return A(o);throw new Error("Could not find proxy Dockerfile. Is @rulemetric/proxy installed?")}u(z,"findDockerfilePath");function Q(){return m("docker",["image","inspect",w],{stdio:"ignore"}).status===0}u(Q,"dockerImageExists");function Z(){let s=m("docker",["container","inspect","-f","{{.State.Running}}",v],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]});return s.status===0&&s.stdout?.trim()==="true"}u(Z,"dockerContainerRunning");var L=class s extends M{static{u(this,"ProxyStart")}static description="Start context capture proxy";static examples=["<%= config.bin %> proxy start","<%= config.bin %> proxy start --docker","<%= config.bin %> proxy start --port 9090","<%= config.bin %> proxy start --web"];static flags={port:_.integer({char:"p",default:J,description:"Proxy listen port"}),docker:_.boolean({char:"d",default:!1,description:"Run proxy in Docker (no local mitmproxy needed)"}),web:_.boolean({default:!1,description:"Launch mitmweb debug UI instead of mitmdump (local mode only)"}),"skip-checks":_.boolean({default:!1,description:"Skip prerequisite checks"}),build:_.boolean({default:!1,description:"Force rebuild Docker image"})};async run(){let{flags:o}=await this.parse(s),t=o.port;o.docker?await this.startDocker(t,o.build):await this.startLocal(t,o.web,o["skip-checks"])}async startDocker(o,t){try{H("docker info",{stdio:"ignore"})}catch{this.error("Docker is not running. Start Docker Desktop and try again.")}Z()&&this.error("Proxy container already running. Stop it first: rulemetric proxy stop");let d=this.findComposeFile(),k=c(x(),".mitmproxy");P(k,{recursive:!0});let E=process.env.TMPDIR||"/tmp";P(c(E,"rulemetric"),{recursive:!0});let y={PROXY_PORT:String(o),RULEMETRIC_PROJECT_PATH:process.cwd()};if(!process.env.RULEMETRIC_API_KEY&&!process.env.RULEMETRIC_ACCESS_TOKEN){let n=c(x(),".config","rulemetric","env");if(l(n))for(let h of b(n,"utf-8").split(`
@@ -1 +1 @@
1
- import{e as m,f as o,k as l,l as d}from"../../chunk-QWCEZEDO.js";import"../../chunk-KKDHD4XA.js";import{b as p,c as u,d as g}from"../../chunk-SZ62CP55.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"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import{spawnSync as x}from"node:child_process";import{existsSync as M,readFileSync as P}from"node:fs";import{homedir as I}from"node:os";import{join as y}from"node:path";var D=y(I(),".config","rulemetric"),f=y(D,"proxy.pid"),e=class h extends c{static{a(this,"ProxyStatus")}static description="Check gateway and context capture proxy status";static examples=["<%= config.bin %> proxy status"];async run(){if(await this.parse(h),l()){let n=d();this.log(`Gateway: running (PID ${n}) on :${m}`)}else this.log("Gateway: not running");if(!M(f)){this.log("Mitmproxy: not running \u2014 routing direct (no capture)");return}let i=P(f,"utf-8").trim();if(i.startsWith("docker:")){let n=i.slice(7),r=x("docker",["container","inspect","-f","{{.State.Status}}",n],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}),s=r.stdout?.trim();r.status===0&&s==="running"?this.log(`Mitmproxy: running in Docker (container: ${n}) on :${o} \u2014 capturing context`):this.log(`Mitmproxy: container ${s||"not running"} (stale)`);return}let t=Number.parseInt(i,10);if(Number.isNaN(t)){this.log("Mitmproxy: not running (invalid PID file)");return}g(t,p)?this.log(`Mitmproxy: running (PID ${t}) on :${o} \u2014 capturing context`):u(t)?this.log(`Mitmproxy: not running (PID ${t} was reused by another process \u2014 stale PID file)`):this.log("Mitmproxy: not running (stale PID file)")}};export{e as default};
1
+ import{e as m,f as o,k as l,l as d}from"../../chunk-QWCEZEDO.js";import"../../chunk-KKDHD4XA.js";import{b as p,c as u,d as g}from"../../chunk-SZ62CP55.js";import{a as c}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a}from"../../chunk-ZLLER3HP.js";import{spawnSync as x}from"node:child_process";import{existsSync as M,readFileSync as P}from"node:fs";import{homedir as I}from"node:os";import{join as y}from"node:path";var D=y(I(),".config","rulemetric"),f=y(D,"proxy.pid"),e=class h extends c{static{a(this,"ProxyStatus")}static description="Check gateway and context capture proxy status";static examples=["<%= config.bin %> proxy status"];async run(){if(await this.parse(h),l()){let n=d();this.log(`Gateway: running (PID ${n}) on :${m}`)}else this.log("Gateway: not running");if(!M(f)){this.log("Mitmproxy: not running \u2014 routing direct (no capture)");return}let i=P(f,"utf-8").trim();if(i.startsWith("docker:")){let n=i.slice(7),r=x("docker",["container","inspect","-f","{{.State.Status}}",n],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}),s=r.stdout?.trim();r.status===0&&s==="running"?this.log(`Mitmproxy: running in Docker (container: ${n}) on :${o} \u2014 capturing context`):this.log(`Mitmproxy: container ${s||"not running"} (stale)`);return}let t=Number.parseInt(i,10);if(Number.isNaN(t)){this.log("Mitmproxy: not running (invalid PID file)");return}g(t,p)?this.log(`Mitmproxy: running (PID ${t}) on :${o} \u2014 capturing context`):u(t)?this.log(`Mitmproxy: not running (PID ${t} was reused by another process \u2014 stale PID file)`):this.log("Mitmproxy: not running (stale PID file)")}};export{e as default};
@@ -1 +1 @@
1
- import{b as m,d as a}from"../../chunk-SZ62CP55.js";import{a as d}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 l}from"../../chunk-ZLLER3HP.js";import{spawnSync as s}from"node:child_process";import{existsSync as f,readFileSync as y,unlinkSync as n}from"node:fs";import{homedir as h}from"node:os";import{dirname as g,join as p,resolve as x}from"node:path";import{fileURLToPath as I}from"node:url";var P=g(I(import.meta.url)),k=p(h(),".config","rulemetric"),t=p(k,"proxy.pid"),c=class u extends d{static{l(this,"ProxyStop")}static description="Stop the context capture proxy";static examples=["<%= config.bin %> proxy stop"];async run(){if(await this.parse(u),!f(t)){this.log("No proxy process found (no PID file).");return}let e=y(t,"utf-8").trim();if(e.startsWith("docker:")){let r=e.slice(7),i=this.findComposeFile();i?(s("docker",["compose","-f",i,"stop","proxy"],{stdio:"inherit"}),s("docker",["compose","-f",i,"rm","-f","proxy"],{stdio:"ignore"})):(s("docker",["stop",r],{stdio:"ignore"}),s("docker",["rm",r],{stdio:"ignore"})),this.log("Proxy container stopped.");try{n(t)}catch{}return}let o=Number.parseInt(e,10);if(Number.isNaN(o)){n(t),this.log("Invalid PID file removed.");return}if(a(o,m))try{process.kill(o,"SIGTERM"),this.log(`Proxy stopped (PID ${o}).`)}catch(r){r.code==="ESRCH"?this.log("Proxy process not running (stale PID file removed)."):this.error(`Failed to stop proxy: ${r.message}`)}else this.log("Proxy process not running (stale PID file removed).");try{n(t)}catch{}this.log(""),this.log("Gateway is still running \u2014 Claude Code will route direct until proxy restarts.")}findComposeFile(){let e=[p(process.cwd(),"docker-compose.yml"),x(P,"../../../../../docker-compose.yml")];for(let o of e)if(f(o))return o;return null}};export{c as default};
1
+ import{b as m,d as a}from"../../chunk-SZ62CP55.js";import{a as d}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{spawnSync as s}from"node:child_process";import{existsSync as f,readFileSync as y,unlinkSync as n}from"node:fs";import{homedir as h}from"node:os";import{dirname as g,join as p,resolve as x}from"node:path";import{fileURLToPath as I}from"node:url";var P=g(I(import.meta.url)),k=p(h(),".config","rulemetric"),t=p(k,"proxy.pid"),c=class u extends d{static{l(this,"ProxyStop")}static description="Stop the context capture proxy";static examples=["<%= config.bin %> proxy stop"];async run(){if(await this.parse(u),!f(t)){this.log("No proxy process found (no PID file).");return}let e=y(t,"utf-8").trim();if(e.startsWith("docker:")){let r=e.slice(7),i=this.findComposeFile();i?(s("docker",["compose","-f",i,"stop","proxy"],{stdio:"inherit"}),s("docker",["compose","-f",i,"rm","-f","proxy"],{stdio:"ignore"})):(s("docker",["stop",r],{stdio:"ignore"}),s("docker",["rm",r],{stdio:"ignore"})),this.log("Proxy container stopped.");try{n(t)}catch{}return}let o=Number.parseInt(e,10);if(Number.isNaN(o)){n(t),this.log("Invalid PID file removed.");return}if(a(o,m))try{process.kill(o,"SIGTERM"),this.log(`Proxy stopped (PID ${o}).`)}catch(r){r.code==="ESRCH"?this.log("Proxy process not running (stale PID file removed)."):this.error(`Failed to stop proxy: ${r.message}`)}else this.log("Proxy process not running (stale PID file removed).");try{n(t)}catch{}this.log(""),this.log("Gateway is still running \u2014 Claude Code will route direct until proxy restarts.")}findComposeFile(){let e=[p(process.cwd(),"docker-compose.yml"),x(P,"../../../../../docker-compose.yml")];for(let o of e)if(f(o))return o;return null}};export{c as default};
@@ -1 +1 @@
1
- import{e as s}from"../../chunk-NVKX36YN.js";import{b as n}from"../../chunk-AXJAGWZB.js";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"../../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 d}from"@oclif/core";import l from"node:path";import f from"node:os";var i=class c extends a{static{o(this,"ResearchBackfill")}static description="Scan every ~/.claude/projects transcript for past rate-limit (429) events and POST them as observations. Opt-in seed for the usage-research dataset \u2014 forward-only tail is the default capture path.";static examples=["<%= config.bin %> research backfill","<%= config.bin %> research backfill --claude-dir /custom/.claude --dry-run"];static flags={"claude-dir":d.string({description:"Override the Claude Code projects directory (defaults to ~/.claude)",default:l.join(f.homedir(),".claude"),noCacheDefault:!0}),"dry-run":d.boolean({description:"Print observation count without POSTing",default:!1})};async run(){let{flags:e}=await this.parse(c);this.requireAuth(),this.log(`Scanning ${l.join(e["claude-dir"],"projects")} for rate-limit events...`);let r=await s(e["claude-dir"]);if(this.log(`Found ${r.length} rate-limit observation(s).`),r.length===0)return;if(e["dry-run"]){this.log("Dry run \u2014 nothing posted.");return}let t=await n(r);if(this.log(`Posted ${t.posted} observation(s); ${t.failed} failed.`),t.failed>0)for(let u of t.errors)this.warn(u)}};export{i as default};
1
+ import{e as s}from"../../chunk-NVKX36YN.js";import{b as n}from"../../chunk-UVCVJKEN.js";import{a}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Flags as d}from"@oclif/core";import l from"node:path";import f from"node:os";var i=class c extends a{static{o(this,"ResearchBackfill")}static description="Scan every ~/.claude/projects transcript for past rate-limit (429) events and POST them as observations. Opt-in seed for the usage-research dataset \u2014 forward-only tail is the default capture path.";static examples=["<%= config.bin %> research backfill","<%= config.bin %> research backfill --claude-dir /custom/.claude --dry-run"];static flags={"claude-dir":d.string({description:"Override the Claude Code projects directory (defaults to ~/.claude)",default:l.join(f.homedir(),".claude"),noCacheDefault:!0}),"dry-run":d.boolean({description:"Print observation count without POSTing",default:!1})};async run(){let{flags:e}=await this.parse(c);this.requireAuth(),this.log(`Scanning ${l.join(e["claude-dir"],"projects")} for rate-limit events...`);let r=await s(e["claude-dir"]);if(this.log(`Found ${r.length} rate-limit observation(s).`),r.length===0)return;if(e["dry-run"]){this.log("Dry run \u2014 nothing posted.");return}let t=await n(r);if(this.log(`Posted ${t.posted} observation(s); ${t.failed} failed.`),t.failed>0)for(let u of t.errors)this.warn(u)}};export{i as default};
@@ -1 +1 @@
1
- import{d,g as c,h as p}from"../../chunk-NVKX36YN.js";import{b as l}from"../../chunk-AXJAGWZB.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"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{Args as v,Flags as g}from"@oclif/core";import w from"node:path";var r=class h extends f{static{n(this,"ResearchTailTranscript")}static description="Read new lines from a Claude Code transcript since the last cached offset, POST any 429 events, and persist the new offset. Invoked by the session-end hook \u2014 safe to re-run.";static hidden=!0;static args={transcript:v.string({description:"Absolute path to a Claude Code .jsonl transcript",required:!0})};static flags={"no-post":g.boolean({description:"Parse and advance the offset without POSTing (debug)",default:!1})};async run(){let{args:u,flags:m}=await this.parse(h),e=w.resolve(u.transcript);try{this.requireAuth()}catch{return}let s=await c(),o=s[e]??0,{observations:a,newOffset:i}=await d(e,o);if(a.length>0&&!m["no-post"])try{let t=await l(a);process.env.RULEMETRIC_DEBUG&&this.log(`tail-transcript: posted ${t.posted}, failed ${t.failed}`)}catch(t){process.env.RULEMETRIC_DEBUG&&this.warn(`tail-transcript POST error: ${String(t)}`)}i!==o&&(s[e]=i,await p(s))}};export{r as default};
1
+ import{d,g as c,h as p}from"../../chunk-NVKX36YN.js";import{b as l}from"../../chunk-UVCVJKEN.js";import{a as f}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{Args as v,Flags as g}from"@oclif/core";import w from"node:path";var r=class h extends f{static{n(this,"ResearchTailTranscript")}static description="Read new lines from a Claude Code transcript since the last cached offset, POST any 429 events, and persist the new offset. Invoked by the session-end hook \u2014 safe to re-run.";static hidden=!0;static args={transcript:v.string({description:"Absolute path to a Claude Code .jsonl transcript",required:!0})};static flags={"no-post":g.boolean({description:"Parse and advance the offset without POSTing (debug)",default:!1})};async run(){let{args:u,flags:m}=await this.parse(h),e=w.resolve(u.transcript);try{this.requireAuth()}catch{return}let s=await c(),o=s[e]??0,{observations:a,newOffset:i}=await d(e,o);if(a.length>0&&!m["no-post"])try{let t=await l(a);process.env.RULEMETRIC_DEBUG&&this.log(`tail-transcript: posted ${t.posted}, failed ${t.failed}`)}catch(t){process.env.RULEMETRIC_DEBUG&&this.warn(`tail-transcript POST error: ${String(t)}`)}i!==o&&(s[e]=i,await p(s))}};export{r as default};
@@ -1,4 +1,4 @@
1
- import{a as D}from"../../chunk-MMM4B3KH.js";import{a as B}from"../../chunk-6XEC6474.js";import"../../chunk-N7ODX6PO.js";import{a as M}from"../../chunk-N4RJ6CN7.js";import"../../chunk-IZTIYR5Q.js";import{c as U}from"../../chunk-E5YE25QG.js";import"../../chunk-YUIRDBQQ.js";import{b as x}from"../../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 $}from"../../chunk-ZLLER3HP.js";import{Flags as E}from"@oclif/core";import{existsSync as g,mkdirSync as w,readFileSync as I,writeFileSync as N}from"node:fs";import{execSync as K,execFileSync as h,spawnSync as W}from"node:child_process";import{homedir as y,userInfo as Z}from"node:os";import{dirname as P,join as o}from"node:path";var H="com.rulemetric.api",L=o(y(),"Library","LaunchAgents",`${H}.plist`),F="com.rulemetric.worker",v=o(y(),"Library","LaunchAgents",`${F}.plist`),X="com.rulemetric.gateway",G=o(y(),"Library","LaunchAgents",`${X}.plist`),q="com.rulemetric.proxy",V=o(y(),"Library","LaunchAgents",`${q}.plist`),tt="com.rulemetric.worker.restart",C=o(y(),"Library","LaunchAgents",`${tt}.plist`),T=o(y(),".config","rulemetric"),p=o(T,"logs"),et=8787,Y=8788,J=o(y(),".config","systemd","user"),A="rulemetric-worker.service",O=o(J,A),j=class S extends M{static{$(this,"ServiceInstall")}static description="Install RuleMetric services. Default (in a repo checkout): API + worker + gateway + capture proxy as launchd agents. With --worker-only: just the job worker, targeting the globally-installed CLI \u2014 no repo, no build (works from `npm i -g @rulemetric/cli`, macOS launchd or Linux systemd).";static examples=["<%= config.bin %> service install","<%= config.bin %> service install --port 3000","<%= config.bin %> service install --skip-build","<%= config.bin %> service install --no-proxy","<%= config.bin %> service install --worker-only"];static flags={port:E.integer({char:"p",default:3e3,description:"API server port"}),force:E.boolean({char:"f",default:!1,description:"Overwrite existing service configuration and reclaim conflicting ports"}),"skip-build":E.boolean({default:!1,description:"Skip the pre-install workspace build (API/web/cli dist must already exist)"}),"no-proxy":E.boolean({default:!1,description:"Skip gateway + mitmproxy plists (just install API + worker)"}),"worker-only":E.boolean({default:!1,description:"Install ONLY the job worker as a persistent service, targeting the globally-installed CLI (no repo checkout, no build, no API/gateway/proxy). Sources auth from ~/.config/rulemetric/env. macOS (launchd) + Linux (systemd --user)."})};async run(){let{flags:r}=await this.parse(S),t=r.port,e=r["skip-build"],s=r["no-proxy"];if(r["worker-only"]){await this.runWorkerOnly(r.force);return}if(process.platform!=="darwin"&&this.error("The full service install is macOS-only (launchd). For just the job worker on Linux (or a clean npm install), use: rulemetric service install --worker-only"),g(L)&&!r.force){this.log(`Service already installed at ${L}`),this.log("Use --force to overwrite, or run: rulemetric service status");return}try{if((await fetch(`http://localhost:${t}/health`)).ok&&!r.force){this.warn(`Port ${t} is already in use (API may be running via start.sh or in another terminal).`),this.warn("Stop it first with scripts/dev/stop.sh, or use --force to take over the port.");return}}catch{}let i=this.findProjectRoot();i||this.error("Could not find RuleMetric project root. Run this command from within the momento-mori repo, or set RULEMETRIC_PROJECT_ROOT.");let n=o(i,".env.local");g(n)||this.error(`.env.local not found at ${n}. The API needs Supabase credentials to start.`);let a=this.guardAlwaysOnDatabaseUrl(this.loadEnvVars(i)),c=this.findBinary("node"),d=this.findBinary("pnpm");(!c||!d)&&this.error("Could not find node or pnpm. Ensure they are in your PATH.");let u=null;if(s||(u=this.findBinary("mitmdump"),u||this.error(`mitmdump not found in PATH. Install with: pipx install mitmproxy (or brew install mitmproxy), then re-run.
1
+ import{a as D}from"../../chunk-MMM4B3KH.js";import{a as B}from"../../chunk-6XEC6474.js";import"../../chunk-N7ODX6PO.js";import{a as M}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import{c as U}from"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import{b as x}from"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as $}from"../../chunk-ZLLER3HP.js";import{Flags as E}from"@oclif/core";import{existsSync as g,mkdirSync as w,readFileSync as I,writeFileSync as N}from"node:fs";import{execSync as K,execFileSync as h,spawnSync as W}from"node:child_process";import{homedir as y,userInfo as Z}from"node:os";import{dirname as P,join as o}from"node:path";var H="com.rulemetric.api",L=o(y(),"Library","LaunchAgents",`${H}.plist`),F="com.rulemetric.worker",v=o(y(),"Library","LaunchAgents",`${F}.plist`),X="com.rulemetric.gateway",G=o(y(),"Library","LaunchAgents",`${X}.plist`),q="com.rulemetric.proxy",V=o(y(),"Library","LaunchAgents",`${q}.plist`),tt="com.rulemetric.worker.restart",C=o(y(),"Library","LaunchAgents",`${tt}.plist`),T=o(y(),".config","rulemetric"),p=o(T,"logs"),et=8787,Y=8788,J=o(y(),".config","systemd","user"),A="rulemetric-worker.service",O=o(J,A),j=class S extends M{static{$(this,"ServiceInstall")}static description="Install RuleMetric services. Default (in a repo checkout): API + worker + gateway + capture proxy as launchd agents. With --worker-only: just the job worker, targeting the globally-installed CLI \u2014 no repo, no build (works from `npm i -g @rulemetric/cli`, macOS launchd or Linux systemd).";static examples=["<%= config.bin %> service install","<%= config.bin %> service install --port 3000","<%= config.bin %> service install --skip-build","<%= config.bin %> service install --no-proxy","<%= config.bin %> service install --worker-only"];static flags={port:E.integer({char:"p",default:3e3,description:"API server port"}),force:E.boolean({char:"f",default:!1,description:"Overwrite existing service configuration and reclaim conflicting ports"}),"skip-build":E.boolean({default:!1,description:"Skip the pre-install workspace build (API/web/cli dist must already exist)"}),"no-proxy":E.boolean({default:!1,description:"Skip gateway + mitmproxy plists (just install API + worker)"}),"worker-only":E.boolean({default:!1,description:"Install ONLY the job worker as a persistent service, targeting the globally-installed CLI (no repo checkout, no build, no API/gateway/proxy). Sources auth from ~/.config/rulemetric/env. macOS (launchd) + Linux (systemd --user)."})};async run(){let{flags:r}=await this.parse(S),t=r.port,e=r["skip-build"],s=r["no-proxy"];if(r["worker-only"]){await this.runWorkerOnly(r.force);return}if(process.platform!=="darwin"&&this.error("The full service install is macOS-only (launchd). For just the job worker on Linux (or a clean npm install), use: rulemetric service install --worker-only"),g(L)&&!r.force){this.log(`Service already installed at ${L}`),this.log("Use --force to overwrite, or run: rulemetric service status");return}try{if((await fetch(`http://localhost:${t}/health`)).ok&&!r.force){this.warn(`Port ${t} is already in use (API may be running via start.sh or in another terminal).`),this.warn("Stop it first with scripts/dev/stop.sh, or use --force to take over the port.");return}}catch{}let i=this.findProjectRoot();i||this.error("Could not find RuleMetric project root. Run this command from within the momento-mori repo, or set RULEMETRIC_PROJECT_ROOT.");let n=o(i,".env.local");g(n)||this.error(`.env.local not found at ${n}. The API needs Supabase credentials to start.`);let a=this.guardAlwaysOnDatabaseUrl(this.loadEnvVars(i)),c=this.findBinary("node"),d=this.findBinary("pnpm");(!c||!d)&&this.error("Could not find node or pnpm. Ensure they are in your PATH.");let u=null;if(s||(u=this.findBinary("mitmdump"),u||this.error(`mitmdump not found in PATH. Install with: pipx install mitmproxy (or brew install mitmproxy), then re-run.
2
2
  Or skip the capture proxy with --no-proxy.`)),e)this.log("[..] Skipping pre-install build (--skip-build)");else{this.log("[..] Building workspace artifacts (api, web, cli) via turbo...");let R=W(d,["exec","turbo","run","build",...["--filter","@rulemetric/api...","--filter","@rulemetric/web...","--filter","@rulemetric/cli"]],{cwd:i,stdio:"inherit"});R.status!==0&&this.error(`Workspace build failed (exit ${R.status}). Fix the build first, or use --skip-build if dist/ already exists.`),this.log("[OK] Build complete")}let f=o(i,"apps","api","dist","index.js");g(f)||this.error(`API entry not found at ${f}. Re-run without --skip-build, or: pnpm --filter @rulemetric/api... build`);let k=o(i,"apps","web","dist","index.html");if(g(k)||this.warn(`Web bundle not found at ${k}. Dashboard at :${t} will 404 until you build apps/web.`),!s){let b=o(i,"apps","cli","dist","lib","gateway-entry.js");g(b)||this.error(`Gateway entry not found at ${b}. Re-run without --skip-build, or: pnpm --filter @rulemetric/cli build`)}r.force&&this.killStaleProcess(t,null,"API on :"+t),s||(this.killStaleProcess(et,o(T,"gateway.pid"),"gateway"),this.killStaleProcess(Y,o(T,"proxy.pid"),"mitmproxy")),w(o(y(),"Library","LaunchAgents"),{recursive:!0}),w(p,{recursive:!0});let m=K("id -u",{encoding:"utf-8"}).trim(),z=this.buildPlist({port:t,projectRoot:i,nodePath:c,pnpmPath:d,envVars:a});this.bootoutAndWrite(m,L,z,"API"),this.bootstrapPlist(m,L,"API"),this.log(`[..] Waiting for API on :${t}...`),await this.waitForApi(t,15)?(this.log(`[OK] RuleMetric API running on :${t}`),g(k)&&this.log(`[OK] Dashboard available at http://localhost:${t}`)):(this.warn("API did not respond within 15s. Check logs:"),this.log(` tail -f ${p}/api-stdout.log`),this.log(` tail -f ${p}/api-stderr.log`)),this.log(""),this.log("Installing worker service..."),this.killStaleAgents();let Q=this.buildWorkerPlist({cliBin:o(i,"apps","cli","bin","run.js"),cliDist:o(i,"apps","cli","dist"),workingDir:i,nodePath:c,pnpmPath:d,envVars:a});if(this.bootoutAndWrite(m,v,Q,"Worker"),this.bootstrapPlist(m,v,"Worker"),!s){this.log(""),this.log("Installing gateway + capture proxy services...");let b=this.buildGatewayPlist({projectRoot:i,nodePath:c});this.bootoutAndWrite(m,G,b,"Gateway"),this.bootstrapPlist(m,G,"Gateway");let R=this.buildProxyPlist({projectRoot:i,mitmdumpPath:u,envVars:a});this.bootoutAndWrite(m,V,R,"Proxy"),this.bootstrapPlist(m,V,"Proxy")}if(g(C)){try{h("launchctl",["bootout",`gui/${m}`,C],{encoding:"utf-8"})}catch{}try{h("rm",["-f",C]),this.log("[OK] Removed stale daily worker-restart agent (no longer needed on agent path)")}catch{}}this.log(""),s?this.log("Installed: API + worker. Gateway/proxy skipped (--no-proxy)."):this.log("Installed: API + worker + gateway + capture proxy."),this.log("All services start at login, restart on crash, and pick up rebuilds via WatchPaths."),this.log(""),this.log("NOTE: Env vars are baked in at install time. If you change"),this.log(".env.local or credentials, re-run: rulemetric service install --force"),this.log(""),this.log("Manage with:"),this.log(" rulemetric service status \u2014 check if running"),this.log(" rulemetric service uninstall \u2014 remove all services"),await x();let _=await B();this.log(""),_.available?this.log(`[OK] tmux found${_.version?` (v${_.version})`:""} \u2014 live send enabled`):this.log("[!!] tmux not found \u2014 live send will fall back to opening Terminal. Install with: brew install tmux")}async runWorkerOnly(r){let t=process.platform;t!=="darwin"&&t!=="linux"&&this.error(`--worker-only supports macOS (launchd) and Linux (systemd) only; detected '${t}'.`);let e=this.findBinary("node");e||this.error("Could not find `node` in PATH.");let s=o(this.config.root,"bin","run.js");g(s)||this.error(`Could not locate the installed CLI entry at ${s}. Reinstall the CLI (e.g. npm i -g @rulemetric/cli) and re-run.`);let i=o(this.config.root,"dist"),n=this.loadGlobalWorkerEnv();if(!n.RULEMETRIC_API_KEY&&!n.RULEMETRIC_ACCESS_TOKEN&&this.error("Not authenticated \u2014 no RULEMETRIC_API_KEY/RULEMETRIC_ACCESS_TOKEN in ~/.config/rulemetric/env.\nRun `rulemetric auth login` first, then re-run `rulemetric service install --worker-only`."),n.RULEMETRIC_API_URL||(n.RULEMETRIC_API_URL="https://rulemetric.com"),w(p,{recursive:!0}),this.killStaleAgents(),t==="darwin"){if(g(v)&&!r){this.log(`Worker already installed at ${v}.`),this.log("Use --force to overwrite, or run: rulemetric service status");return}w(o(y(),"Library","LaunchAgents"),{recursive:!0});let a=K("id -u",{encoding:"utf-8"}).trim(),c=this.buildWorkerPlist({cliBin:s,cliDist:i,workingDir:y(),nodePath:e,nodeEnv:"production",envVars:n});this.bootoutAndWrite(a,v,c,"Worker"),this.bootstrapPlist(a,v,"Worker"),this.log(""),this.log("[OK] Worker installed (launchd). Starts at login, restarts on crash."),this.log(` Logs: tail -f ${o(p,"worker-stdout.log")}`)}else{if(g(O)&&!r){this.log(`Worker already installed at ${O}.`),this.log(`Use --force to overwrite, or: systemctl --user status ${A}`);return}w(J,{recursive:!0});let a=this.buildWorkerSystemdUnit({cliBin:s,nodePath:e,envVars:n});N(O,a,{mode:384}),this.log(`[OK] Wrote ${O}`);try{h("systemctl",["--user","daemon-reload"]),h("systemctl",["--user","enable","--now",A]),this.log("[OK] Worker enabled + started (systemctl --user).");try{h("loginctl",["enable-linger",Z().username]),this.log("[OK] Enabled linger \u2014 worker survives logout/reboot.")}catch{this.log("[!!] Could not enable linger (worker will stop on logout)."),this.log(' Run: sudo loginctl enable-linger "$USER"')}this.log(` Logs: journalctl --user -u ${A} -f`)}catch(c){this.warn(`Wrote the unit but \`systemctl --user\` failed: ${c instanceof Error?c.message:String(c)}`),this.log(`Enable it manually: systemctl --user daemon-reload && systemctl --user enable --now ${A}`)}}this.log(""),this.log("Manage with:"),this.log(" rulemetric service status \u2014 check if running"),this.log(" rulemetric service uninstall \u2014 remove the worker"),await x(),U("worker_started",{mode:"worker-only"},this.config.version)}loadGlobalWorkerEnv(){let r={},t=o(T,"env");if(g(t))for(let e of I(t,"utf-8").split(`
3
3
  `)){let s=e.trim();if(!s||s.startsWith("#"))continue;let i=s.indexOf("=");i>0&&(r[s.slice(0,i)]=s.slice(i+1))}return Object.fromEntries(Object.entries(r).filter(([e])=>D.has(e)))}buildWorkerSystemdUnit(r){let{cliBin:t,nodePath:e,envVars:s}=r,i={...s,NODE_ENV:"production",PATH:[...new Set([P(e),o(y(),".local","bin"),"/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"])].join(":"),PG_POOL_MAX:s.PG_POOL_MAX??"3",PG_IDLE_TIMEOUT:s.PG_IDLE_TIMEOUT??"10"},n=Object.entries(i).map(([a,c])=>`Environment="${a}=${c.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`).join(`
4
4
  `);return`[Unit]
@@ -1 +1 @@
1
- import{a as b}from"../../chunk-6XEC6474.js";import"../../chunk-N7ODX6PO.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"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as T}from"../../chunk-ZLLER3HP.js";import{existsSync as c,readFileSync as A}from"node:fs";import{execFileSync as x,execSync as M}from"node:child_process";import{homedir as l}from"node:os";import{join as a}from"node:path";var k="com.rulemetric.api",g=a(l(),"Library","LaunchAgents",`${k}.plist`),u="com.rulemetric.worker",o=a(l(),"Library","LaunchAgents",`${u}.plist`),v="com.rulemetric.gateway",E=a(l(),"Library","LaunchAgents",`${v}.plist`),L="com.rulemetric.proxy",R=a(l(),"Library","LaunchAgents",`${L}.plist`),_=a(l(),".config","rulemetric","logs"),y=8787,$=8788,p="rulemetric-worker.service",W=a(l(),".config","systemd","user",p),P=class extends w{static{T(this,"ServiceStatus")}static description="Check the status of installed RuleMetric services (launchd on macOS; systemd --user worker on Linux)";async run(){if(process.platform!=="darwin"){if(process.platform==="linux"){this.reportLinuxWorkerStatus();return}this.error(`Service status supports macOS (launchd) and Linux (systemd --user, worker-only installs) only; detected '${process.platform}'.`)}if(!c(g)){if(c(o)){this.reportWorkerOnlyStatus();return}this.log("Service: not installed"),this.log("Run: rulemetric service install (repo checkout) or rulemetric service install --worker-only");return}let t=this.readServiceState(k,g),e=this.readApiPort(g),r=await this.probeApiHealth(e),d=await this.probeDashboard(e),s=this.readServiceState(u,o),h=this.readWorkerMode(),i=this.readServiceState(v,E),S=this.isPortListening(y),n=this.readServiceState(L,R),m=this.isPortListening($),O=`${r} (port ${e})${d?" \u2014 dashboard served":""}`;this.log(`API: ${this.fmtState(t)} \u2014 ${O}`);let I=h==="listen"?" [mode: listen \u2014 DEPRECATED, run `rulemetric service install --force` to upgrade]":"";this.log(`Worker: ${this.fmtState(s)}${I}`),this.log(`Gateway: ${this.fmtState(i)} \u2014 ${S?`listening :${y}`:`NOT listening :${y}`}`),this.log(`Proxy: ${this.fmtState(n)} \u2014 ${m?`listening :${$}`:`NOT listening :${$}`}`);let f=await b();this.log(`Tmux: ${f.available?f.version?`v${f.version}`:"available":"not found"}`),this.log(""),this.log(`Plists: ${g}`),this.log(` ${o}`),i.installed&&this.log(` ${E}`),n.installed&&this.log(` ${R}`),this.log(`Logs: ${_}/{api,worker,gateway,proxy}-{stdout,stderr}.log`);let D=t.launchdStatus==="running"&&r==="healthy"&&s.launchdStatus==="running"&&(!i.installed||i.launchdStatus==="running"&&S)&&(!n.installed||n.launchdStatus==="running"&&m);this.log(""),D?this.log("All good \u2014 sessions tracked, jobs processed, capture pipeline live."):(t.launchdStatus!=="running"&&(this.log("API is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${k}`)),s.installed&&s.launchdStatus!=="running"&&(this.log("Worker is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${u}`)),i.installed&&(i.launchdStatus!=="running"||!S)&&(this.log("Gateway is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${v}`)),n.installed&&(n.launchdStatus!=="running"||!m)&&(this.log("Proxy is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${L}`)),(!i.installed||!n.installed)&&this.log("Gateway/proxy not installed. Run: rulemetric service install --force"))}reportWorkerOnlyStatus(){let t=this.readServiceState(u,o),r=this.readWorkerMode()==="listen"?" [mode: listen \u2014 DEPRECATED, run `rulemetric service install --worker-only --force` to upgrade]":"";this.log(`Worker: ${this.fmtState(t)}${r} (worker-only install)`),this.log(""),this.log(`Plist: ${o}`),this.log(`Logs: ${_}/worker-{stdout,stderr}.log`),this.log(""),t.launchdStatus==="running"?this.log("All good \u2014 jobs processed by the background worker."):(this.log("Worker is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${u}`))}reportLinuxWorkerStatus(){if(!c(W)){this.log("Service: not installed"),this.log("Run: rulemetric service install --worker-only");return}let t;try{t=x("systemctl",["--user","is-active",p],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch(e){t=(e.stdout??"").toString().trim()||"not loaded"}this.log(`Worker: ${t} (systemd --user, worker-only install)`),this.log(""),this.log(`Unit: ${W}`),this.log(`Logs: journalctl --user -u ${p} -f`),this.log(""),t==="active"?this.log("All good \u2014 jobs processed by the background worker."):(this.log("Worker is not running. Try:"),this.log(` systemctl --user restart ${p}`))}readServiceState(t,e){if(!c(e))return{installed:!1,launchdStatus:"not installed",pid:null};try{let d=M(`launchctl list ${t} 2>/dev/null`,{encoding:"utf-8"}),s=d.match(/"PID"\s*=\s*(\d+)/),h=d.match(/"LastExitStatus"\s*=\s*(\d+)/);if(s)return{installed:!0,launchdStatus:"running",pid:s[1]};if(h){let i=h[1];return{installed:!0,launchdStatus:i==="0"?"stopped (clean exit)":`stopped (exit ${i})`,pid:null}}return{installed:!0,launchdStatus:"loaded",pid:null}}catch{return{installed:!0,launchdStatus:"not loaded",pid:null}}}fmtState(t){return t.installed?`${t.launchdStatus}${t.pid?` (PID ${t.pid})`:""}`:"not installed"}readApiPort(t){try{let r=A(t,"utf-8").match(/<key>PORT<\/key>\s*<string>(\d+)<\/string>/);if(r)return Number.parseInt(r[1])}catch{}return 3e3}readWorkerMode(){if(!c(o))return null;try{let e=A(o,"utf-8").match(/<string>evals<\/string>\s*<string>(listen|agent)<\/string>/);if(e)return e[1]}catch{}return null}async probeApiHealth(t){try{let e=await fetch(`http://localhost:${t}/health`);return e.ok?"healthy":`unhealthy (${e.status})`}catch{return"unreachable"}}async probeDashboard(t){try{let e=await fetch(`http://localhost:${t}/`);return e.ok?(e.headers.get("content-type")??"").includes("text/html"):!1}catch{return!1}}isPortListening(t){try{return x("lsof",["-ti",`:${t}`,"-sTCP:LISTEN"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim().length>0}catch{return!1}}};export{P as default};
1
+ import{a as b}from"../../chunk-6XEC6474.js";import"../../chunk-N7ODX6PO.js";import{a as w}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as T}from"../../chunk-ZLLER3HP.js";import{existsSync as c,readFileSync as A}from"node:fs";import{execFileSync as x,execSync as M}from"node:child_process";import{homedir as l}from"node:os";import{join as a}from"node:path";var k="com.rulemetric.api",g=a(l(),"Library","LaunchAgents",`${k}.plist`),u="com.rulemetric.worker",o=a(l(),"Library","LaunchAgents",`${u}.plist`),v="com.rulemetric.gateway",E=a(l(),"Library","LaunchAgents",`${v}.plist`),L="com.rulemetric.proxy",R=a(l(),"Library","LaunchAgents",`${L}.plist`),_=a(l(),".config","rulemetric","logs"),y=8787,$=8788,p="rulemetric-worker.service",W=a(l(),".config","systemd","user",p),P=class extends w{static{T(this,"ServiceStatus")}static description="Check the status of installed RuleMetric services (launchd on macOS; systemd --user worker on Linux)";async run(){if(process.platform!=="darwin"){if(process.platform==="linux"){this.reportLinuxWorkerStatus();return}this.error(`Service status supports macOS (launchd) and Linux (systemd --user, worker-only installs) only; detected '${process.platform}'.`)}if(!c(g)){if(c(o)){this.reportWorkerOnlyStatus();return}this.log("Service: not installed"),this.log("Run: rulemetric service install (repo checkout) or rulemetric service install --worker-only");return}let t=this.readServiceState(k,g),e=this.readApiPort(g),r=await this.probeApiHealth(e),d=await this.probeDashboard(e),s=this.readServiceState(u,o),h=this.readWorkerMode(),i=this.readServiceState(v,E),S=this.isPortListening(y),n=this.readServiceState(L,R),m=this.isPortListening($),O=`${r} (port ${e})${d?" \u2014 dashboard served":""}`;this.log(`API: ${this.fmtState(t)} \u2014 ${O}`);let I=h==="listen"?" [mode: listen \u2014 DEPRECATED, run `rulemetric service install --force` to upgrade]":"";this.log(`Worker: ${this.fmtState(s)}${I}`),this.log(`Gateway: ${this.fmtState(i)} \u2014 ${S?`listening :${y}`:`NOT listening :${y}`}`),this.log(`Proxy: ${this.fmtState(n)} \u2014 ${m?`listening :${$}`:`NOT listening :${$}`}`);let f=await b();this.log(`Tmux: ${f.available?f.version?`v${f.version}`:"available":"not found"}`),this.log(""),this.log(`Plists: ${g}`),this.log(` ${o}`),i.installed&&this.log(` ${E}`),n.installed&&this.log(` ${R}`),this.log(`Logs: ${_}/{api,worker,gateway,proxy}-{stdout,stderr}.log`);let D=t.launchdStatus==="running"&&r==="healthy"&&s.launchdStatus==="running"&&(!i.installed||i.launchdStatus==="running"&&S)&&(!n.installed||n.launchdStatus==="running"&&m);this.log(""),D?this.log("All good \u2014 sessions tracked, jobs processed, capture pipeline live."):(t.launchdStatus!=="running"&&(this.log("API is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${k}`)),s.installed&&s.launchdStatus!=="running"&&(this.log("Worker is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${u}`)),i.installed&&(i.launchdStatus!=="running"||!S)&&(this.log("Gateway is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${v}`)),n.installed&&(n.launchdStatus!=="running"||!m)&&(this.log("Proxy is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${L}`)),(!i.installed||!n.installed)&&this.log("Gateway/proxy not installed. Run: rulemetric service install --force"))}reportWorkerOnlyStatus(){let t=this.readServiceState(u,o),r=this.readWorkerMode()==="listen"?" [mode: listen \u2014 DEPRECATED, run `rulemetric service install --worker-only --force` to upgrade]":"";this.log(`Worker: ${this.fmtState(t)}${r} (worker-only install)`),this.log(""),this.log(`Plist: ${o}`),this.log(`Logs: ${_}/worker-{stdout,stderr}.log`),this.log(""),t.launchdStatus==="running"?this.log("All good \u2014 jobs processed by the background worker."):(this.log("Worker is not running. Try:"),this.log(` launchctl kickstart gui/$(id -u)/${u}`))}reportLinuxWorkerStatus(){if(!c(W)){this.log("Service: not installed"),this.log("Run: rulemetric service install --worker-only");return}let t;try{t=x("systemctl",["--user","is-active",p],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()}catch(e){t=(e.stdout??"").toString().trim()||"not loaded"}this.log(`Worker: ${t} (systemd --user, worker-only install)`),this.log(""),this.log(`Unit: ${W}`),this.log(`Logs: journalctl --user -u ${p} -f`),this.log(""),t==="active"?this.log("All good \u2014 jobs processed by the background worker."):(this.log("Worker is not running. Try:"),this.log(` systemctl --user restart ${p}`))}readServiceState(t,e){if(!c(e))return{installed:!1,launchdStatus:"not installed",pid:null};try{let d=M(`launchctl list ${t} 2>/dev/null`,{encoding:"utf-8"}),s=d.match(/"PID"\s*=\s*(\d+)/),h=d.match(/"LastExitStatus"\s*=\s*(\d+)/);if(s)return{installed:!0,launchdStatus:"running",pid:s[1]};if(h){let i=h[1];return{installed:!0,launchdStatus:i==="0"?"stopped (clean exit)":`stopped (exit ${i})`,pid:null}}return{installed:!0,launchdStatus:"loaded",pid:null}}catch{return{installed:!0,launchdStatus:"not loaded",pid:null}}}fmtState(t){return t.installed?`${t.launchdStatus}${t.pid?` (PID ${t.pid})`:""}`:"not installed"}readApiPort(t){try{let r=A(t,"utf-8").match(/<key>PORT<\/key>\s*<string>(\d+)<\/string>/);if(r)return Number.parseInt(r[1])}catch{}return 3e3}readWorkerMode(){if(!c(o))return null;try{let e=A(o,"utf-8").match(/<string>evals<\/string>\s*<string>(listen|agent)<\/string>/);if(e)return e[1]}catch{}return null}async probeApiHealth(t){try{let e=await fetch(`http://localhost:${t}/health`);return e.ok?"healthy":`unhealthy (${e.status})`}catch{return"unreachable"}}async probeDashboard(t){try{let e=await fetch(`http://localhost:${t}/`);return e.ok?(e.headers.get("content-type")??"").includes("text/html"):!1}catch{return!1}}isPortListening(t){try{return x("lsof",["-ti",`:${t}`,"-sTCP:LISTEN"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim().length>0}catch{return!1}}};export{P as default};
@@ -1 +1 @@
1
- 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"../../chunk-PZNWH4VQ.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{existsSync as m,unlinkSync as d}from"node:fs";import{execSync as g,execFileSync as s}from"node:child_process";import{homedir as y}from"node:os";import{join as p}from"node:path";var v=[{label:"com.rulemetric.api",description:"API"},{label:"com.rulemetric.worker",description:"Worker"},{label:"com.rulemetric.gateway",description:"Gateway"},{label:"com.rulemetric.proxy",description:"Proxy"},{label:"com.rulemetric.worker.restart",description:"Worker restart agent"}];function h(a){return p(y(),"Library","LaunchAgents",`${a}.plist`)}n(h,"plistPathFor");var l="rulemetric-worker.service",i=p(y(),".config","systemd","user",l),c=class extends u{static{n(this,"ServiceUninstall")}static description="Remove RuleMetric services (macOS launchd: API/worker/gateway/proxy; Linux: the --worker-only systemd unit)";async run(){if(process.platform==="linux"){this.uninstallLinuxWorker();return}process.platform!=="darwin"&&this.error("Service uninstall supports macOS (launchd) and Linux (systemd) only.");let r=v.filter(t=>m(h(t.label)));if(r.length===0){this.log("No RuleMetric services are installed.");return}let o=g("id -u",{encoding:"utf-8"}).trim();for(let t of r){let e=h(t.label);this.stopService(o,e,t.label,t.description),this.removePlist(e,t.description)}this.log(""),this.log("All RuleMetric services removed. They will no longer start automatically."),this.log("Use scripts/dev/start.sh (dev) or `rulemetric service install` (always-on) to bring them back.")}stopService(r,o,t,e){try{s("launchctl",["bootout",`gui/${r}`,o],{encoding:"utf-8"}),this.log(`[OK] ${e} stopped`);return}catch{}try{s("launchctl",["unload",o],{encoding:"utf-8"}),this.log(`[OK] ${e} stopped (legacy)`);return}catch{try{g(`launchctl list ${t} 2>&1`,{encoding:"utf-8"}).includes("PID")?(this.warn(`${e} appears to still be running. Try manually:`),this.warn(` launchctl bootout gui/${r} "${o}"`)):this.log(`[OK] ${e} was not running`)}catch{this.log(`[OK] ${e} was not running`)}}}removePlist(r,o){try{d(r),this.log(`[OK] Removed ${r}`)}catch(t){this.warn(`Could not remove ${o} plist: ${t.message}. Try: rm "${r}"`)}}uninstallLinuxWorker(){if(!m(i)){this.log("No RuleMetric worker is installed (no systemd unit found).");return}try{s("systemctl",["--user","disable","--now",l],{encoding:"utf-8"}),this.log("[OK] Worker stopped + disabled (systemctl --user)")}catch(r){this.warn(`Could not disable the worker unit: ${r.message}`),this.warn(` systemctl --user disable --now ${l}`)}try{d(i),this.log(`[OK] Removed ${i}`)}catch(r){this.warn(`Could not remove ${i}: ${r.message}. Try: rm "${i}"`)}try{s("systemctl",["--user","daemon-reload"],{encoding:"utf-8"})}catch{}this.log(""),this.log("RuleMetric worker removed. It will no longer start automatically.")}};export{c as default};
1
+ import{a as u}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{existsSync as m,unlinkSync as d}from"node:fs";import{execSync as g,execFileSync as s}from"node:child_process";import{homedir as y}from"node:os";import{join as p}from"node:path";var v=[{label:"com.rulemetric.api",description:"API"},{label:"com.rulemetric.worker",description:"Worker"},{label:"com.rulemetric.gateway",description:"Gateway"},{label:"com.rulemetric.proxy",description:"Proxy"},{label:"com.rulemetric.worker.restart",description:"Worker restart agent"}];function h(a){return p(y(),"Library","LaunchAgents",`${a}.plist`)}n(h,"plistPathFor");var l="rulemetric-worker.service",i=p(y(),".config","systemd","user",l),c=class extends u{static{n(this,"ServiceUninstall")}static description="Remove RuleMetric services (macOS launchd: API/worker/gateway/proxy; Linux: the --worker-only systemd unit)";async run(){if(process.platform==="linux"){this.uninstallLinuxWorker();return}process.platform!=="darwin"&&this.error("Service uninstall supports macOS (launchd) and Linux (systemd) only.");let r=v.filter(t=>m(h(t.label)));if(r.length===0){this.log("No RuleMetric services are installed.");return}let o=g("id -u",{encoding:"utf-8"}).trim();for(let t of r){let e=h(t.label);this.stopService(o,e,t.label,t.description),this.removePlist(e,t.description)}this.log(""),this.log("All RuleMetric services removed. They will no longer start automatically."),this.log("Use scripts/dev/start.sh (dev) or `rulemetric service install` (always-on) to bring them back.")}stopService(r,o,t,e){try{s("launchctl",["bootout",`gui/${r}`,o],{encoding:"utf-8"}),this.log(`[OK] ${e} stopped`);return}catch{}try{s("launchctl",["unload",o],{encoding:"utf-8"}),this.log(`[OK] ${e} stopped (legacy)`);return}catch{try{g(`launchctl list ${t} 2>&1`,{encoding:"utf-8"}).includes("PID")?(this.warn(`${e} appears to still be running. Try manually:`),this.warn(` launchctl bootout gui/${r} "${o}"`)):this.log(`[OK] ${e} was not running`)}catch{this.log(`[OK] ${e} was not running`)}}}removePlist(r,o){try{d(r),this.log(`[OK] Removed ${r}`)}catch(t){this.warn(`Could not remove ${o} plist: ${t.message}. Try: rm "${r}"`)}}uninstallLinuxWorker(){if(!m(i)){this.log("No RuleMetric worker is installed (no systemd unit found).");return}try{s("systemctl",["--user","disable","--now",l],{encoding:"utf-8"}),this.log("[OK] Worker stopped + disabled (systemctl --user)")}catch(r){this.warn(`Could not disable the worker unit: ${r.message}`),this.warn(` systemctl --user disable --now ${l}`)}try{d(i),this.log(`[OK] Removed ${i}`)}catch(r){this.warn(`Could not remove ${i}: ${r.message}. Try: rm "${i}"`)}try{s("systemctl",["--user","daemon-reload"],{encoding:"utf-8"})}catch{}this.log(""),this.log("RuleMetric worker removed. It will no longer start automatically.")}};export{c as default};
@@ -1 +1 @@
1
- import{a}from"../../chunk-WLVQJH4E.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 r}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 l}from"@oclif/core";var s=class n extends o{static{t(this,"SessionsAnalyze")}static description="Trigger AI analysis on a session";static examples=["<%= config.bin %> sessions analyze <session-id>"];static args={id:l.string({description:"Session ID",required:!0})};async run(){let{args:i}=await this.parse(n);this.requireAuth(),a(i.id,"session ID");let e=await r(`/api/sessions/${i.id}/analyze`,{});this.log(`Analysis queued (job ${e.jobId}, status: ${e.status}).`),this.log("A running worker picks it up automatically \u2014 start one with `rulemetric evals agent`"),this.log("(or install it persistently: `rulemetric service install --worker-only`)."),this.log("Results appear on the session once processed \u2014 see the session detail page in the dashboard.")}};export{s as default};
1
+ import{a}from"../../chunk-WLVQJH4E.js";import{a as o}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as r}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as t}from"../../chunk-ZLLER3HP.js";import{Args as l}from"@oclif/core";var s=class n extends o{static{t(this,"SessionsAnalyze")}static description="Trigger AI analysis on a session";static examples=["<%= config.bin %> sessions analyze <session-id>"];static args={id:l.string({description:"Session ID",required:!0})};async run(){let{args:i}=await this.parse(n);this.requireAuth(),a(i.id,"session ID");let e=await r(`/api/sessions/${i.id}/analyze`,{});this.log(`Analysis queued (job ${e.jobId}, status: ${e.status}).`),this.log("A running worker picks it up automatically \u2014 start one with `rulemetric evals agent`"),this.log("(or install it persistently: `rulemetric service install --worker-only`)."),this.log("Results appear on the session once processed \u2014 see the session detail page in the dashboard.")}};export{s as default};
@@ -1 +1 @@
1
- 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{e as f,i as g}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 w,Flags as b}from"@oclif/core";var a=class m extends u{static{h(this,"SessionsDelete")}static description="Permanently delete captured sessions and everything stored with them (events, context snapshots, offloaded blobs)";static examples=["<%= config.bin %> sessions delete 4f9d\u2026","<%= config.bin %> sessions delete 4f9d\u2026 8a21\u2026","<%= config.bin %> sessions delete --project /work/client-a --yes"];static args={ids:w.string({description:"Session id(s) to delete",required:!1})};static strict=!1;static flags={project:b.string({description:"Delete every session captured under this project path (use with --yes)."}),yes:b.boolean({description:"Skip the confirmation prompt. Required for --project in non-interactive use.",default:!1})};async run(){let{argv:v,flags:o}=await this.parse(m);this.requireAuth();let n=v.map(t=>t.trim()).filter(Boolean);n.length===0&&!o.project&&this.error("Nothing to delete. Pass one or more session ids, or --project <path> for a bulk scrub."),n.length>0&&o.project&&this.error("Pass either session ids or --project, not both.");let s=n;if(o.project){s=[];let t=0,e=100;for(;;){let r=await f(`/api/sessions?projectPath=${encodeURIComponent(o.project)}&hideEmpty=false&limit=${e}&offset=${t}`);if(s.push(...r.map($=>$.id)),r.length<e)break;t+=e}if(s.length===0){this.log(`No sessions found under ${o.project}. Nothing to delete.`);return}this.log(`${s.length} session(s) captured under ${o.project}.`)}if(!o.yes){process.stdin.isTTY||this.error(`Refusing to delete ${s.length} session(s) without --yes in a non-interactive shell.`);let{createInterface:t}=await import("node:readline/promises"),e=t({input:process.stdin,output:process.stdout}),r=await e.question(`Permanently delete ${s.length} session(s) and all captured content? This cannot be undone. [y/N] `);if(e.close(),r.trim().toLowerCase()!=="y"){this.log("Aborted \u2014 nothing deleted.");return}}let d=0,c=0,p=0,l=0,i=0;for(let t of s)try{let e=await g(`/api/sessions/${t}`);d+=e.eventsDeleted??0,c+=e.snapshotsDeleted??0,p+=e.blobsDeleted??0,l+=e.blobsFailed??0,this.log(`deleted ${t} (${e.eventsDeleted??0} events, ${e.snapshotsDeleted??0} snapshots)`)}catch(e){i+=1,this.warn(`failed to delete ${t}: ${e.message}`)}this.log(""),this.log(`Deleted ${s.length-i}/${s.length} session(s): ${d} events, ${c} snapshots, ${p} storage blob(s) removed.`),l>0&&this.warn(`${l} storage blob(s) could not be removed (rows are gone; blobs are orphaned).`),i>0&&this.error(`${i} session(s) failed to delete \u2014 see warnings above.`)}};export{a as default};
1
+ import{a as u}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e as f,i as g}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as h}from"../../chunk-ZLLER3HP.js";import{Args as w,Flags as b}from"@oclif/core";var a=class m extends u{static{h(this,"SessionsDelete")}static description="Permanently delete captured sessions and everything stored with them (events, context snapshots, offloaded blobs)";static examples=["<%= config.bin %> sessions delete 4f9d\u2026","<%= config.bin %> sessions delete 4f9d\u2026 8a21\u2026","<%= config.bin %> sessions delete --project /work/client-a --yes"];static args={ids:w.string({description:"Session id(s) to delete",required:!1})};static strict=!1;static flags={project:b.string({description:"Delete every session captured under this project path (use with --yes)."}),yes:b.boolean({description:"Skip the confirmation prompt. Required for --project in non-interactive use.",default:!1})};async run(){let{argv:v,flags:o}=await this.parse(m);this.requireAuth();let n=v.map(t=>t.trim()).filter(Boolean);n.length===0&&!o.project&&this.error("Nothing to delete. Pass one or more session ids, or --project <path> for a bulk scrub."),n.length>0&&o.project&&this.error("Pass either session ids or --project, not both.");let s=n;if(o.project){s=[];let t=0,e=100;for(;;){let r=await f(`/api/sessions?projectPath=${encodeURIComponent(o.project)}&hideEmpty=false&limit=${e}&offset=${t}`);if(s.push(...r.map($=>$.id)),r.length<e)break;t+=e}if(s.length===0){this.log(`No sessions found under ${o.project}. Nothing to delete.`);return}this.log(`${s.length} session(s) captured under ${o.project}.`)}if(!o.yes){process.stdin.isTTY||this.error(`Refusing to delete ${s.length} session(s) without --yes in a non-interactive shell.`);let{createInterface:t}=await import("node:readline/promises"),e=t({input:process.stdin,output:process.stdout}),r=await e.question(`Permanently delete ${s.length} session(s) and all captured content? This cannot be undone. [y/N] `);if(e.close(),r.trim().toLowerCase()!=="y"){this.log("Aborted \u2014 nothing deleted.");return}}let d=0,c=0,p=0,l=0,i=0;for(let t of s)try{let e=await g(`/api/sessions/${t}`);d+=e.eventsDeleted??0,c+=e.snapshotsDeleted??0,p+=e.blobsDeleted??0,l+=e.blobsFailed??0,this.log(`deleted ${t} (${e.eventsDeleted??0} events, ${e.snapshotsDeleted??0} snapshots)`)}catch(e){i+=1,this.warn(`failed to delete ${t}: ${e.message}`)}this.log(""),this.log(`Deleted ${s.length-i}/${s.length} session(s): ${d} events, ${c} snapshots, ${p} storage blob(s) removed.`),l>0&&this.warn(`${l} storage blob(s) could not be removed (rows are gone; blobs are orphaned).`),i>0&&this.error(`${i} session(s) failed to delete \u2014 see warnings above.`)}};export{a as default};
@@ -1,2 +1,2 @@
1
- import{a as d}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"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{readdirSync as f,readFileSync as h,unlinkSync as p,statSync as S}from"node:fs";import{tmpdir as g}from"node:os";import{join as r}from"node:path";var v=[".log",".seq",".ctxhash",".pid",".lock"],c=class u extends d{static{l(this,"SessionsEnd")}static description="End the active capture session";static examples=["<%= config.bin %> sessions end"];async run(){await this.parse(u),this.requireAuth();let i=r(g(),"rulemetric"),s=this.findActiveSession(i);s||this.error("No active session found. Start one with: rulemetric sessions start --tool <name>");try{await m(`/api/sessions/${s.rwSessionId}/close`,{})}catch(e){this.error(`Could not end session ${s.rwSessionId} via API: ${e.message}. Local session files were left in place \u2014 fix the connection/auth issue and retry.`)}this.cleanupSessionFiles(i,s.externalId),this.log(`Session ended: ${s.rwSessionId}`)}findActiveSession(i){let s;try{s=f(i)}catch{return null}let e=[];for(let t of s){if(v.some(o=>t.endsWith(o)))continue;let n=r(i,t);try{let o=S(n);if(!o.isFile())continue;let a=h(n,"utf-8").trim();if(!a)continue;e.push({externalId:t,rwSessionId:a.split(`
1
+ import{a as d}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as m}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{readdirSync as f,readFileSync as h,unlinkSync as p,statSync as S}from"node:fs";import{tmpdir as g}from"node:os";import{join as r}from"node:path";var v=[".log",".seq",".ctxhash",".pid",".lock"],c=class u extends d{static{l(this,"SessionsEnd")}static description="End the active capture session";static examples=["<%= config.bin %> sessions end"];async run(){await this.parse(u),this.requireAuth();let i=r(g(),"rulemetric"),s=this.findActiveSession(i);s||this.error("No active session found. Start one with: rulemetric sessions start --tool <name>");try{await m(`/api/sessions/${s.rwSessionId}/close`,{})}catch(e){this.error(`Could not end session ${s.rwSessionId} via API: ${e.message}. Local session files were left in place \u2014 fix the connection/auth issue and retry.`)}this.cleanupSessionFiles(i,s.externalId),this.log(`Session ended: ${s.rwSessionId}`)}findActiveSession(i){let s;try{s=f(i)}catch{return null}let e=[];for(let t of s){if(v.some(o=>t.endsWith(o)))continue;let n=r(i,t);try{let o=S(n);if(!o.isFile())continue;let a=h(n,"utf-8").trim();if(!a)continue;e.push({externalId:t,rwSessionId:a.split(`
2
2
  `)[0].trim(),path:n,mtime:o.mtimeMs})}catch{continue}}return e.length===0?null:(e.sort((t,n)=>n.mtime-t.mtime),e[0])}cleanupSessionFiles(i,s){let e=r(i,s);for(let t of["",".seq",".ctxhash",".log"])try{p(e+t)}catch{}}};export{c as default};
@@ -1 +1 @@
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"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import*as o from"node:fs";import{Args as l,Flags as d}from"@oclif/core";var e=class a extends n{static{i(this,"SessionsImport")}static description="Import a session file (JSONL, JSON)";static examples=["<%= config.bin %> sessions import ~/.claude/projects/my-project/session-abc.jsonl","<%= config.bin %> sessions import ./copilot-export.json --tool vscode_copilot"];static args={path:l.string({description:"Path to session file",required:!0})};static flags={tool:d.string({description:"Override tool detection (claude_code, cursor, vscode_copilot)"})};async run(){let{args:t,flags:c}=await this.parse(a);this.requireAuth(),o.existsSync(t.path)||this.error(`File not found: ${t.path}`);let p=o.readFileSync(t.path,"utf-8"),s=await r("/api/sessions/import",{content:p,tool:c.tool});this.log(`Imported session ${s.id} (${s.tool}, ${s.eventCount} events)`)}};export{e as default};
1
+ import{a as n}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{f as r}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as i}from"../../chunk-ZLLER3HP.js";import*as o from"node:fs";import{Args as l,Flags as d}from"@oclif/core";var e=class a extends n{static{i(this,"SessionsImport")}static description="Import a session file (JSONL, JSON)";static examples=["<%= config.bin %> sessions import ~/.claude/projects/my-project/session-abc.jsonl","<%= config.bin %> sessions import ./copilot-export.json --tool vscode_copilot"];static args={path:l.string({description:"Path to session file",required:!0})};static flags={tool:d.string({description:"Override tool detection (claude_code, cursor, vscode_copilot)"})};async run(){let{args:t,flags:c}=await this.parse(a);this.requireAuth(),o.existsSync(t.path)||this.error(`File not found: ${t.path}`);let p=o.readFileSync(t.path,"utf-8"),s=await r("/api/sessions/import",{content:p,tool:c.tool});this.log(`Imported session ${s.id} (${s.tool}, ${s.eventCount} events)`)}};export{e as default};
@@ -1 +1 @@
1
- import{a as l}from"../../chunk-SE3UKA3M.js";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{e as r}from"../../chunk-ZZHIBOMT.js";import"../../chunk-TWPG3TEQ.js";import"../../chunk-74QIUVWY.js";import"../../chunk-PZNWH4VQ.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{Flags as c}from"@oclif/core";var o=class d extends a{static{n(this,"SessionsList")}static description="List captured sessions";static examples=["<%= config.bin %> sessions list","<%= config.bin %> sessions list --tool claude_code","<%= config.bin %> sessions list --tool codex"];static flags={tool:c.string({description:`Filter by tool (${l.join(", ")})`}),limit:c.integer({description:"Max results",default:20})};async run(){let{flags:e}=await this.parse(d);this.requireAuth();let s=new URLSearchParams;e.tool&&s.set("tool",e.tool),s.set("limit",String(e.limit));let i=await r(`/api/sessions?${s}`);if(i.length===0){this.log("No sessions found.");return}for(let t of i){let p=t.projectPath?.split("/").pop()??"\u2014",m=t.analysis?.adherenceScore!=null?`${t.analysis.adherenceScore}%`:"\u2014",u=new Date(t.startedAt).toLocaleDateString();this.log(`${t.id.slice(0,8)} ${t.tool.padEnd(15)} ${p.padEnd(20)} ${String(t.eventCount).padStart(5)} events ${m.padStart(4)} adherence ${u}`)}}};export{o as default};
1
+ import{a as l}from"../../chunk-T75KAEJO.js";import{a}from"../../chunk-WUCACPGC.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-WL5ZWQAS.js";import"../../chunk-KEVDLLHT.js";import"../../chunk-DX6IPDED.js";import"../../chunk-3AV3GTMP.js";import{e as r}from"../../chunk-GIXHG5FK.js";import"../../chunk-X6CF5KTW.js";import"../../chunk-XQYAVSUQ.js";import"../../chunk-PZNWH4VQ.js";import{a as n}from"../../chunk-ZLLER3HP.js";import{Flags as c}from"@oclif/core";var o=class d extends a{static{n(this,"SessionsList")}static description="List captured sessions";static examples=["<%= config.bin %> sessions list","<%= config.bin %> sessions list --tool claude_code","<%= config.bin %> sessions list --tool codex"];static flags={tool:c.string({description:`Filter by tool (${l.join(", ")})`}),limit:c.integer({description:"Max results",default:20})};async run(){let{flags:e}=await this.parse(d);this.requireAuth();let s=new URLSearchParams;e.tool&&s.set("tool",e.tool),s.set("limit",String(e.limit));let i=await r(`/api/sessions?${s}`);if(i.length===0){this.log("No sessions found.");return}for(let t of i){let p=t.projectPath?.split("/").pop()??"\u2014",m=t.analysis?.adherenceScore!=null?`${t.analysis.adherenceScore}%`:"\u2014",u=new Date(t.startedAt).toLocaleDateString();this.log(`${t.id.slice(0,8)} ${t.tool.padEnd(15)} ${p.padEnd(20)} ${String(t.eventCount).padStart(5)} events ${m.padStart(4)} adherence ${u}`)}}};export{o as default};